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 通知的目標網址。
  • subscriberConfigs:要接收通知的資料類型,以及每種資料類型的訂閱政策。
  • endpointAuthorization:端點的授權機制。這個 authorization_token 必須包含您提供的 authorization_token。系統會在每個通知訊息的 Authorization 標頭中傳送 authorization_token 的值。您可以使用這個權杖,確認傳入要求是否來自 Google Health API。舉例來說,您可以將 authorization_token 設為 Bearer 驗證的 Bearer R4nd0m5tr1ng123,或是 Basic 驗證的 Basic dXNlcjpwYXNzd29yZA==
  • subscriberId:您為訂閱者提供的專屬 ID。這個 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 中,系統會略過這些欄位。

如果您更新 endpointUriendpointAuthorization,系統會執行端點驗證。詳情請參閱「端點驗證」。

更新 subscriberConfigs 時,請注意這是「完整取代」,而非合併。如果 subscriberConfigs 包含在 updateMask 中,系統會以要求主體中提供的清單,覆寫該訂閱者的所有已儲存設定。如要新增或移除設定,您必須提供完整的設定組合。如要更新其他欄位並保留目前的設定,請從 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
  }
}

端點驗證

為確保通知傳送的安全性與可靠性,每當您建立訂閱者或更新其端點設定 (endpointUriendpointAuthorization) 時,Google Health API 都會執行強制性的兩步驟驗證握手程序。這項程序會在 API 呼叫期間同步執行。服務會使用 User-Agent Google-Health-API-Webhooks-Verifier,向端點 URI 自動傳送兩項 POST 要求,並附上 JSON 內文 {"type": "verification"}

  • 授權握手:系統會傳送第一個要求,並附上您設定的 Authorization 標頭。伺服器必須傳回 200 OK201 Created 狀態。
  • 未經授權的驗證:第二個要求是在沒有憑證的情況下傳送。伺服器必須傳回 401 Unauthorized403 Forbidden 狀態。

這項信號交換程序會確認端點處於啟用狀態,並正確強制執行安全性。如果任一步驟失敗,API 要求就會失敗並傳回 FAILED_PRECONDITION 錯誤。只有在握手程序成功後,系統才會儲存及啟用訂閱者,以便接收健康資料通知。

金鑰輪替

如要輪替 endpointAuthorization 的金鑰,請按照下列步驟操作:

  1. 設定端點,同時接受新舊 endpointAuthorization 值。
  2. 使用 patch 要求和 ?updateMask=endpointAuthorization,以新的 endpointAuthorization 值更新訂閱者設定。
  3. 確認步驟 2 成功後,請設定端點,只接受新的 endpointAuthorization 值。

刪除訂閱者

使用 delete 端點從專案中移除訂閱者。刪除後,訂閱者就不會再收到通知。

要求

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

回應

如果刪除作業成功,系統會傳回 HTTP 狀態為 `200 OK` 的空白回應主體。
{}

使用者訂閱

Google Health API 可協助您有效管理使用者訂閱項目,減少使用者加入時的手動註冊需求。

自動訂閱

建議使用自動訂閱功能。如要啟用這項功能,請在 subscriberConfigs 中將特定資料類型的 subscriptionCreatePolicy 設為 AUTOMATIC。您透過 AUTOMATIC 政策指定的 dataTypes,與 Google Health API 傳送通知的資料類型相同,前提是使用者也同意存取這些資料類型。

如果使用者同意應用程式存取與 AUTOMATIC 政策相關的資料類型,Google Health API 就會自動追蹤並傳送通知,告知使用者同意提供的資料類型與該使用者的自動訂閱者設定資料類型之間的交集。每當該使用者產生這些類型的新資料時,系統就會將通知傳送至端點。無論使用者是在您建立訂閱者之前或之後授予同意聲明,這項功能都適用。系統不會為訂閱者建立前產生的資料補充通知。

如果使用者撤銷同意聲明,系統就會停止傳送相應資料類型的通知。自動訂閱項目由 Google 管理,無法個別列出或刪除,只有在刪除父項訂閱者時才會移除。

手動訂閱

如要手動管理每位使用者的訂閱項目,請在 subscriberConfigs 中將 subscriptionCreatePolicy 設為 MANUAL。這項政策生效後,系統不會自動建立使用者訂閱項目。日後推出手動管理訂閱項目的 API 時,就會使用這項功能。在這些 API 推出前,建議使用AUTOMATIC訂閱項目。

通知

當使用者訂閱的資料類型發生變化時,Google Health API 會向訂閱端點網址發出 HTTPS POST 要求。

通知格式

通知酬載是 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 欄位是專屬 ID。如果訂閱項目採用 MANUAL 政策,這個欄位會包含訂閱項目建立時指定的永久訂閱項目名稱,由開發人員提供。這項 ID 可用於管理手動訂閱項目。如果是使用 AUTOMATIC 政策建立的訂閱項目,Google Health API 會自動為每則通知產生專屬 ID (隨機 UUID),並指派給這個欄位。無論是手動或自動政策,都應加入 clientProvidedSubscriptionName,確保所有訂閱類型的通知酬載格式一致。

healthUserId 是 Google Health API 的使用者 ID,用於識別資料已變更的使用者。如果應用程式支援多位使用者,您可能會收到已授予應用程式同意聲明的使用者通知。收到通知時,請使用 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 天的通知會遭到捨棄,無法復原。