Webhook サブスクリプション


Google Health API を使用すると、ユーザーの健康データが変更されたときに、アプリケーションでリアルタイム通知を受け取ることができます。変更をポーリングする代わりに、Google Health API でデータが利用可能になるとすぐに、サーバーは HTTPS POST リクエスト(Webhook)を受信します。

サポートされるデータタイプ

Webhook 通知は、次のデータ型でサポートされています。

  • 手順
  • 高度
  • 距離
  • 階数
  • 重量
  • 睡眠

これらのデータタイプについては、ユーザーが対応するスコープのいずれかに同意した場合にのみ通知が送信されます。

  • アクティビティ: 歩数、高度、距離、階数のデータ型をカバーします。
    • https://www.googleapis.com/auth/googlehealth.activity_and_fitness
    • https://www.googleapis.com/auth/googlehealth.activity_and_fitness.readonly
  • 健康指標(体重データ型を含む):
    • https://www.googleapis.com/auth/googlehealth.health_metrics_and_measurements
    • https://www.googleapis.com/auth/googlehealth.health_metrics_and_measurements.readonly
  • 睡眠。睡眠データ型を対象とします。
    • https://www.googleapis.com/auth/googlehealth.sleep
    • https://www.googleapis.com/auth/googlehealth.sleep.readonly

サブスクライバーを管理する

通知を受け取るには、アプリケーションの通知エンドポイントを表す Subscriber を登録する必要があります。projects.subscribers で利用可能な REST API を使用して、サブスクライバーを管理できます。

サブスクライバー エンドポイントは HTTPS(TLSv1.2 以降)を使用し、一般公開されている必要があります。サブスクライバーの作成と更新時に、Google Health API は検証チャレンジを実行して、エンドポイント URI の所有権を確認します。検証に失敗すると、サブスクライバーの作成と更新オペレーションは FailedPreconditionException で失敗します。

サブスクライバーを作成する

プロジェクトの新しいサブスクライバーを登録するには、create エンドポイントを使用します。以下の情報を提供する必要があります。

  • endpointUri: Webhook 通知のリンク先 URL。
  • subscriberConfigs: 通知を受け取るデータ型と、それぞれのサブスクリプション ポリシー。
  • endpointAuthorization: エンドポイントの認可メカニズム。これには、ユーザーが提供する authorization_token が含まれている必要があります。authorization_token の値は、各通知メッセージとともに Authorization ヘッダーで送信されます。このトークンを使用して、受信リクエストが Google Health API からのものであることを確認できます。たとえば、Bearer 認証の場合は authorization_tokenBearer R4nd0m5tr1ng123 に、Basic 認証の場合は Basic dXNlcjpwYXNzd29yZA== に設定できます。
  • subscriberId: サブスクライバーに指定する一意の識別子。この ID は 4 ~ 36 文字で、正規表現([a-z]([a-z0-9-]{2,34}[a-z0-9]))と一致する必要があります。

subscriberConfigs では、各データ型に subscriptionCreatePolicy を設定する必要があります。自動定期購入を使用する場合は AUTOMATIC に設定し、ユーザーの定期購入を自分で管理する場合は MANUAL に設定します。各オプションの詳細については、自動サブスクリプション手動サブスクリプションをご覧ください。

リクエスト

POST https://health.googleapis.com/v4/projects/project-id/subscribers?subscriberId=subscriber-id
{
  "endpointUri": "https://myapp.com/webhooks/health",
  "subscriberConfigs": [
    {
      "dataTypes": ["steps", "altitude", "distance", "floors", "weight"],
      "subscriptionCreatePolicy": "AUTOMATIC"
    },
    {
      "dataTypes": ["sleep"],
      "subscriptionCreatePolicy": "MANUAL"
    }
  ],
  "endpointAuthorization": {
    "authorization_token": "Bearer example-secret-token"
  }
}

レスポンス

{
  "name": "projects/project-id/subscribers/subscriber-id",
  "endpointUri": "https://myapp.com/webhooks/health",
  "state": "ACTIVE",
  "subscriberConfigs": [
    {
      "dataTypes": ["steps", "altitude", "distance", "floors", "weight"],
      "subscriptionCreatePolicy": "AUTOMATIC"
    },
    {
      "dataTypes": ["sleep"],
      "subscriptionCreatePolicy": "MANUAL"
    }
  ],
  "endpointAuthorization": {
    "authorizationTokenSet": true
  }
}

チャンネル登録者の一覧表示

list エンドポイントを使用して、プロジェクトに登録されているすべてのサブスクライバーを取得します。

リクエスト

GET https://health.googleapis.com/v4/projects/project-id/subscribers

レスポンス

{
  "subscribers": [
    {
      "name": "projects/project-id/subscribers/subscriber-id",
      "endpointUri": "https://myapp.com/webhooks/health",
      "state": "ACTIVE",
      "subscriberConfigs": [
        {
          "dataTypes": ["steps", "altitude", "distance", "floors", "weight"],
          "subscriptionCreatePolicy": "AUTOMATIC"
        },
        {
          "dataTypes": ["sleep"],
          "subscriptionCreatePolicy": "MANUAL"
        }
      ],
      "endpointAuthorization": {
        "authorizationTokenSet": true
      }
    }
  ],
  "nextPageToken": ""
}

サブスクライバーを更新する

patch エンドポイントを使用して、プロジェクトのサブスクライバーを更新します。更新可能なフィールドは endpointUrisubscriberConfigsendpointAuthorization です。

フィールドを更新するには、updateMask クエリ パラメータとリクエスト本文を指定します。updateMask には、更新するフィールド名のカンマ区切りのリストを、フィールド名にキャメルケースを使用して(endpointUri など)含める必要があります。リクエスト本文には、更新するフィールドの新しい値を含む Subscriber オブジェクトの一部を含める必要があります。updateMask で指定されたフィールドのみが更新されます。updateMask にないフィールドをリクエスト本文で指定すると、それらのフィールドは無視されます。

endpointUri または endpointAuthorization を更新すると、エンドポイントの確認が実行されます。詳しくは、エンドポイントの確認 をご覧ください。

subscriberConfigs を更新する際は、マージではなく完全な置き換えであることに注意してください。subscriberConfigsupdateMask に含まれている場合、そのサブスクライバーの保存されているすべての構成は、リクエスト本文で提供されたリストで上書きされます。構成を追加または削除するには、構成の完全なセットを指定する必要があります。他のフィールドを更新し、現在の構成を保持する場合は、updateMask から subscriberConfigs を省略します。

リクエスト

PATCH https://health.googleapis.com/v4/projects/project-id/subscribers/subscriber-id?updateMask=endpointUri
{
  "endpointUri": "https://myapp.com/new-webhooks/health"
}

レスポンス

{
  "name": "projects/project-id/subscribers/subscriber-id",
  "endpointUri": "https://myapp.com/new-webhooks/health",
  "state": "ACTIVE",
  "subscriberConfigs": [
    {
      "dataTypes": ["steps", "altitude", "distance", "floors", "weight"],
      "subscriptionCreatePolicy": "AUTOMATIC"
    },
    {
      "dataTypes": ["sleep"],
      "subscriptionCreatePolicy": "MANUAL"
    }
  ],
  "endpointAuthorization": {
    "authorizationTokenSet": true
  }
}

エンドポイントの確認

通知配信のセキュリティと信頼性を確保するため、Google Health API は、サブスクライバーを作成するたび、またはエンドポイント構成(endpointUri または endpointAuthorization)を更新するたびに、必須の 2 段階認証プロセス ハンドシェイクを実行します。このプロセスは、API 呼び出し中に同期的に実行されます。サービスは、User-Agent Google-Health-API-Webhooks-Verifier を使用して、エンドポイント URI に 2 つの自動 POST リクエストを送信します。JSON 本文は {"type": "verification"} です。

  • 承認済みハンドシェイク: 構成済みの Authorization ヘッダーを含む最初のリクエストが送信されます。サーバーは 200 OK または 201 Created ステータスで応答する必要があります。
  • Unauthorized Challenge: 2 回目のリクエストが認証情報なしで送信されます。サーバーは 401 Unauthorized または 403 Forbidden ステータスで応答する必要があります。

このハンドシェイクにより、エンドポイントがアクティブで、セキュリティが正しく適用されていることを確認できます。いずれかの手順が失敗すると、API リクエストは FAILED_PRECONDITION エラーで失敗します。このハンドシェイクが成功した後にのみ、サブスクライバーが保存され、健康データ通知を受信できるように有効になります。

鍵のローテーション

endpointAuthorization の鍵をローテーションする必要がある場合は、次の手順を行います。

  1. 古い endpointAuthorization 値と新しい endpointAuthorization 値の両方を受け入れるようにエンドポイントを構成します。
  2. ?updateMask=endpointAuthorization を含む patch リクエストを使用して、新しい endpointAuthorization 値でサブスクライバー構成を更新します。
  3. ステップ 2 が成功したことを確認したら、新しい endpointAuthorization 値のみを受け入れるようにエンドポイントを構成します。

登録者を削除する

delete エンドポイントを使用して、プロジェクトからサブスクライバーを削除します。削除すると、購読者は通知を受け取らなくなります。

リクエスト

DELETE https://health.googleapis.com/v4/projects/project-id/subscribers/subscriber-id

レスポンス

削除が成功すると、HTTP ステータス `200 OK` の空のレスポンス本文が返されます。
{}

ユーザーの登録

Google Health API を使用すると、ユーザー サブスクリプションを効率的に管理できるため、ユーザー オンボーディング時の手動登録の必要性が軽減されます。

自動サブスクリプション

自動定期購入を使用することをおすすめします。この機能を有効にするには、特定のデータ型の subscriberConfigssubscriptionCreatePolicyAUTOMATIC に設定します。AUTOMATIC ポリシーで指定する dataTypes は、Google Health API が通知を送信するデータ型と同じです。ただし、これらのデータ型についてユーザーの同意も得られている必要があります。

ユーザーが AUTOMATIC ポリシーのあるデータ型に対応するスコープのアプリへの同意を付与すると、Google Health API は、ユーザーが同意したデータ型と、そのユーザーの自動サブスクライバー構成データ型との共通部分から得られるデータ型を自動的に追跡し、通知を送信します。ユーザーがこれらのタイプの新しいデータを生成するたびに、通知がエンドポイントに送信されます。これは、購読者の作成前または作成後に同意したユーザーに適用されます。サブスクライバーが作成される前に生成されたデータについては、通知はバックフィルされません。

ユーザーが同意を取り消すと、対応するデータタイプの通知は停止します。自動サブスクリプションは Google によって管理され、個別に一覧表示したり削除したりすることはできません。親サブスクライバーが削除された場合にのみ削除されます。

手動サブスクリプション

ユーザーごとにサブスクリプションを手動で管理する場合は、subscriberConfigssubscriptionCreatePolicyMANUAL に設定します。このポリシーでは、ユーザー サブスクリプションは自動的に作成されません。この機能は、手動サブスクリプションを管理するための API が利用可能になったときに使用されます。これらの API が利用可能になるまでは、AUTOMATIC サブスクリプションを使用することをおすすめします。

通知

ユーザーのデータが登録されたデータ型で変更されると、Google Health API は HTTPS POST リクエストをサブスクライバー エンドポイント URL に送信します。

通知形式

通知ペイロードは、データ変更の詳細を含む JSON オブジェクトです。これには、更新されたデータのクエリに使用できるユーザー ID、データ型、時間間隔が含まれます。

{
  "data": {
    "version": "1",
    "clientProvidedSubscriptionName": "subscription-name",
    "healthUserId": "health-user-id",
    "operation": "UPSERT",
    "dataType": "steps",
    "intervals": [
      {
        "physicalTimeInterval": {
          "startTime": "2026-03-0B01:29:00Z",
          "endTime": "2026-03-08T01:34:00Z"
        },
        "civilDateTimeInterval": {
          "startDateTime": {
            "date": {
              "year": 2026,
              "month": 3,
              "day": 7
            },
            "time": {
              "hours": 17,
              "minutes": 29
            }
          },
          "endDateTime": {
            "date": {
              "year": 2026,
              "month": 3,
              "day": 7
            },
            "time": {
              "hours": 17,
              "minutes": 34
            }
          }
        },
        "civilIso8601TimeInterval": {
          "startTime": "2026-03-07T17:29:00",
          "endTime": "2026-03-07T17:34:00"
        }
      }
    ]
  }
}

operation フィールドは、通知をトリガーした変更のタイプを示します。

  • UPSERT: データの追加または変更時に送信されます。
  • DELETE: ユーザーがデータを削除したとき、またはユーザーが権限を取り消したりアカウントを削除したりするなどのシステム イベントによってデータが削除されたときに送信されます。

再試行によって通知が重複して送信される可能性があるため、特に UPSERT オペレーションでは、通知処理ロジックをべき等にすることをおすすめします。

clientProvidedSubscriptionName フィールドは一意の識別子です。MANUAL ポリシーを含む定期購入の場合、このフィールドには、定期購入の作成時に指定された、デベロッパーが提供する永続的な定期購入名が含まれます。これにより、手動登録を管理するための固定 ID が提供されます。AUTOMATIC ポリシーで作成されたサブスクリプションの場合、Google Health API は、通知ごとにこのフィールドに一意の識別子(ランダムな UUID)を自動的に生成して割り当てます。手動ポリシーと自動ポリシーの両方に clientProvidedSubscriptionName を含めることで、すべてのサブスクリプション タイプで通知ペイロードの形式が統一されます。

healthUserId は、データが変更されたユーザーの Google Health API 識別子です。アプリケーションが複数のユーザーをサポートしている場合、アプリケーションに同意したユーザーの通知を受け取ることができます。通知を受け取ったら、healthUserId を使用してどのユーザーのデータが変更されたかを特定し、そのユーザーの OAuth 認証情報を使用してデータをクエリできるようにします。

ユーザーの OAuth 認証情報を healthUserId にマッピングするには、getIdentity エンドポイントを使用します。ユーザーのオンボーディング時にユーザーの認証情報を使用してこのエンドポイントを呼び出し、healthUserId を取得して、このマッピングを保存します。このマッピングは時間の経過とともに変化しないため、無期限にキャッシュに保存できます。例については、ユーザー ID を取得するをご覧ください。これにより、通知の healthUserId に基づいてデータをクエリするときに、正しいユーザー認証情報を選択できます。

通知に応答する

サーバーは、通知に対して HTTP 204 No Content ステータス コードですぐに応答する必要があります。タイムアウトを回避するには、レスポンスを送信した後で通知ペイロードを非同期で処理します。Google Health API が他のステータス コードを受信した場合、またはリクエストがタイムアウトした場合、通知の送信を後で再試行します。

Node.js(Express)の例:

app.post('/webhook-receiver', (req, res) => {
    // 1. Immediately acknowledge the notification
    res.status(204).send();

    // 2. Process the data asynchronously in the background
    const notification = req.body;
    setImmediate(() => {
        console.log(`Update for user ${notification.data.healthUserId} of type ${notification.data.dataType}`);
        // Trigger your data retrieval logic here
    });
});

チャンネル登録者のステータスと復元

サブスクライバー エンドポイントが利用できなくなった場合や、エラー ステータス コード(204 以外)を返した場合、Google Health API は保留中の通知を最大 7 日間保存し、指数バックオフで配信を再試行します。

エンドポイントがオンラインに戻り、204 で応答すると、API は保存されたメッセージのバックログを自動的に配信します。7 日以上前の通知は破棄され、復元できません。