推播通知

本文將說明如何使用推播通知,在資源發生變更時通知應用程式。

總覽

Directory API 提供推播通知,可讓您監控資源的變更。您可以使用這項功能改善應用程式效能。這可讓您消除與輪詢資源相關的額外網路和運算成本,以便判斷資源是否已變更。每當監控的資源發生變更時,Directory API 就會通知您的應用程式。

如要使用推播通知,您必須完成以下兩個步驟:

  • 設定接收網址或「Webhook」回呼接收器。

    這是一個 HTTPS 伺服器,可處理資源變更時觸發的 API 通知訊息。

  • 為每個要監控的資源端點設定 (通知管道)。

    管道會指定通知訊息的路由資訊。在管道設定中,您必須指定要接收通知的特定網址。每當管道的資源發生變更時,Directory API 就會將通知訊息以 POST 要求傳送至該網址。

目前,Directory API 支援 Users 資源變更的通知。

建立通知管道

如要要求推播通知,您必須為每個要監控的資源設定通知管道。設定通知管道後,Directory API 會在任何監控的資源發生變更時通知應用程式。

提出監控要求

每個可觀看的 Directory API 資源都有一個相關聯的 watch 方法,位於以下格式的 URI:

https://www.googleapis.com/API_NAME/API_VERSION/RESOURCE_PATH/watch

如要設定通知管道,以便接收有關特定資源變更的訊息,請將 POST 要求傳送至資源的 watch 方法。

每個通知管道都會與特定使用者和特定資源 (或一組資源) 建立關聯。除非目前的使用者或服務帳戶擁有或具備存取此資源的權限,否則 watch 要求不會成功。

範例

單一網域的 User 資源的所有監控要求,一般格式如下:

POST https://admin.googleapis.com/admin/directory/v1/users/watch?domain=domain&event=event
Authorization: Bearer auth_token_for_current_user
Content-Type: application/json

{
  "id": "01234567-89ab-cdef-0123456789ab", // Your channel ID.
  "type": "web_hook",
  "address": "https://mydomain.com/notifications", // Your receiving URL.
  ...
  "token": "target=myApp-myFilesChannelDest", // (Optional) Your channel token.
  "params": {
    "ttl": 3600 // (Optional) Your requested time-to-live for this channel.
  }
}

使用 domainevent 參數指定要接收通知的網域和事件類型。

客戶的使用者資源的所有觀看要求都採用一般格式:

POST https://admin.googleapis.com/admin/directory/users/v1/watch?customer=customer&event=event
Authorization: Bearer auth_token_for_current_user
Content-Type: application/json

{
  "id": "01234567-89ab-cdef-0123456789ab", // Your channel ID.
  "type": "web_hook",
  "address": "https://mydomain.com/notifications", // Your receiving URL.
  ...
  "token": "target=myApp-myFilesChannelDest", // (Optional) Your channel token.
  "params": {
    "ttl": 3600 // (Optional) Your requested time-to-live for this channel.
  }
}

使用 customerevent 參數指定客戶 Google 帳戶的專屬 ID,以及您要接收通知的事件類型。

event 的可能值如下:

  • add:使用者建立的事件
  • delete:使用者刪除事件
  • makeAdmin:使用者管理員狀態變更事件
  • undelete:使用者取消刪除事件
  • update:使用者更新事件

注意:為了方便說明,以下範例省略了要求主體。

監控使用者建立的網域 mydomain.com 事件:

POST https://admin.googleapis.com/admin/directory/v1/users/watch?domain=mydomain.com&event=add

監控客戶 my_customer 的使用者建立事件:

POST https://admin.googleapis.com/admin/directory/v1/users/watch?customer=my_customer&event=add

必要屬性

您必須在每個 watch 要求中提供下列欄位:

  • id 屬性字串,可用於在專案中唯一識別這個新的通知管道。建議您使用通用專屬 ID (UUID) 或任何類似的專屬字串。長度上限:64 個半形字元。

    您設定的 ID 值會在您透過這個管道收到的每則通知訊息的 X-Goog-Channel-Id HTTP 標頭中回傳。

  • type 屬性字串設為 web_hook 值。

  • address 屬性字串會設為網址,該網址會監聽並回應此通知管道的通知。這是 Webhook 回呼網址,且必須使用 HTTPS。

    請注意,只有在網頁伺服器上安裝有效的 SSL 憑證時,Directory API 才能傳送通知至這個 HTTPS 位址。無效的憑證包括:

    • 自行簽署的憑證。
    • 由不受信任的來源所簽署的憑證。
    • 已撤銷的憑證。
    • 憑證的主體與目標主機名稱不相符。

選用屬性

您也可以在 watch 要求中指定這些選用欄位:

  • token 屬性會指定任意字串值,做為頻道權杖。您可以將通知管道符記用於各種用途。舉例來說,您可以使用權杖驗證每則傳入訊息是否屬於應用程式建立的管道,以確保通知不會遭到偽造,或是根據這個管道的用途,將訊息路由至應用程式中的正確目的地。長度上限:256 個半形字元。

    權杖會納入應用程式透過這個管道收到的每則通知訊息中的 X-Goog-Channel-Token HTTP 標頭。

    如果您使用通知管道符記,建議您:

    • 使用可擴充的編碼格式,例如網址查詢參數。範例:forwardTo=hr&createdBy=mobile

    • 請勿加入 OAuth 權杖等機密資料。

  • expiration 屬性字串,設定為您希望 Directory API 停止傳送此通知管道訊息的日期和時間的 Unix 時間戳記 (以毫秒為單位)。

    如果管道設有到期時間,則會在應用程式收到的每則管道通知訊息中,將該時間納入 X-Goog-Channel-Expiration HTTP 標頭的值 (以人類可讀格式表示)。

如要進一步瞭解要求,請參閱 API 參考資料中 Users 資源的 watch 方法。

觀看回應

如果 watch 要求成功建立通知管道,則會傳回 HTTP 200 OK 狀態碼。

手錶回應的訊息主體會提供您剛建立的通知管道相關資訊,如以下範例所示。

{
  "kind": "api#channel",
  "id": "01234567-89ab-cdef-0123456789ab", // ID you specified for this channel.
  "resourceId": "B4ibMJiIhTjAQd7Ff2K2bexk8G4", // ID of the watched resource.
  "resourceUri": "https://admin.googleapis.com/admin/directory/v1/users?domain=domain&event=event", // Version-specific ID of the watched resource.
  "token": "target=myApp-myFilesChannelDest", // Present only if one was provided.
  "expiration": 1384823632000, // Actual expiration time as Unix timestamp (in ms), if applicable.
}

除了您在要求中傳送的屬性之外,傳回的資訊還包含 resourceIdresourceUri,用於識別在這個通知管道中監控的資源。

您可以將傳回的資訊傳遞至其他通知管道操作,例如想停止接收通知時。

如要進一步瞭解回應,請參閱 API 參考資料中 使用者 資源的 watch 方法。

同步處理訊息

建立通知管道來監控資源後,Directory API 會傳送 sync 訊息,表示通知已開始。這些訊息的 X-Goog-Resource-State HTTP 標頭值為 sync。由於網路時間問題,您可能會在收到 watch 方法回應之前,就收到 sync 訊息。

您可以放心忽略 sync 通知,但也可以使用這項通知。舉例來說,如果您決定不保留管道,可以在呼叫中使用 X-Goog-Channel-IDX-Goog-Resource-ID 值,停止接收通知。您也可以使用 sync 通知進行一些初始化作業,為日後的事件做好準備。

以下是 Directory API 傳送至接收網址的 sync 訊息格式。

POST https://mydomain.com/notifications // Your receiving URL.
X-Goog-Channel-ID: channel-ID-value
X-Goog-Channel-Token: channel-token-value
X-Goog-Channel-Expiration: expiration-date-and-time // In human-readable format. Present only if the channel expires.
X-Goog-Resource-ID: identifier-for-the-watched-resource
X-Goog-Resource-URI: version-specific-URI-of-the-watched-resource
X-Goog-Resource-State: sync
X-Goog-Message-Number: 1

同步處理訊息的 X-Goog-Message-Number HTTP 標頭值一律為 1。這個管道的後續通知訊息編號會比前一個大,但訊息編號不會依序排列。

更新通知管道

通知管道可以設有到期時間,而這個值是由您的要求或任何 Directory API 內部限制或預設值決定 (會使用較嚴格的值)。如果管道有到期時間,watch 方法會在傳回的資訊中加入 Unix 時間戳記 (以毫秒為單位),做為管道的到期時間。此外,應用程式在 X-Goog-Channel-Expiration HTTP 標頭中,為這個管道收到的每則通知訊息中,都會包含到期日和時間 (以人類可讀格式)。

目前無法自動續訂通知管道。當管道即將到期時,您必須呼叫 watch 方法,將其替換為新的管道。如往常一樣,您必須為新管道的 id 屬性使用專屬值。請注意,當同一個資源的兩個通知管道都處於作用中狀態時,可能會出現「重疊」的時間。

接收通知

每當監控的資源有所變更,應用程式就會收到說明變更內容的通知訊息。Directory API 會將這些訊息以 HTTPS POST 要求的形式傳送至您為此通知管道指定的 address 屬性網址。

解讀通知訊息格式

所有通知訊息都包含一組含有 X-Goog- 前置字串的 HTTP 標頭。某些類型的通知也可以包含訊息主體。

標頭

Directory API 發布至接收網址的通知訊息會包含下列 HTTP 標頭:

標頭 說明
一律顯示
X-Goog-Channel-ID 您提供的 UUID 或其他專屬字串,用於識別這個通知管道。
X-Goog-Message-Number 這個通知管道用來識別此訊息的整數。sync 訊息的值一律為 1。頻道上的後續訊息數量會增加,但並非依序。
X-Goog-Resource-ID 識別受監控資源的不易解讀值。這個 ID 在各 API 版本中皆為穩定狀態。
X-Goog-Resource-State 觸發通知的新資源狀態。可能的值: sync事件名稱
X-Goog-Resource-URI 受監控資源的 API 版本專屬 ID。
有時會出現
X-Goog-Channel-Expiration 通知管道到期日,以人類可讀的格式表示。只有在定義時才會出現。
X-Goog-Channel-Token 應用程式設定的通知管道憑證,可用於驗證通知來源。只有在定義時才會出現。

使用者通知訊息會在要求主體中包含下列資訊:

屬性 說明
kind 表示這是使用者資源。值:固定字串「admin#directory#user」。
id 使用者資源的專屬 ID。
etag 通知訊息的 ETag。與使用者資源的 ETag 不同。
primaryEmail 使用者的主要電子郵件地址。

範例

User 資源事件的通知訊息一般格式如下:

POST https://mydomain.com/notifications // Your receiving URL.
Content-Type: application/json; utf-8
Content-Length: 0
X-Goog-Channel-ID: directoryApiId
X-Goog-Channel-Token: 398348u3tu83ut8uu38
X-Goog-Channel-Expiration: Tue, 29 Oct 2013 20:32:02 GMT
X-Goog-Resource-ID:  ret08u3rv24htgh289g
X-Goog-Resource-URI: 'https://admin.googleapis.com/admin/directory/v1/users?domain=domain&event=event
X-Goog-Resource-State:  event
X-Goog-Message-Number: 10

{
  "kind": "admin#directory#user",
  "id": long,
  "etag": string,
  "primaryEmail": string
}

使用者刪除活動的範例:

POST https://mydomain.com/notifications // Your receiving URL.
Content-Type: application/json; utf-8
Content-Length: 189
X-Goog-Channel-ID: deleteChannel
X-Goog-Channel-Token: 245t1234tt83trrt333
X-Goog-Channel-Expiration: Mon, 09 Dec 2013 22:24:23 GMT
X-Goog-Resource-ID:  B4ibMJiIhTjAQd7Ff2K2bexk8G4
X-Goog-Resource-URI: https://admin.googleapis.com/admin/directory/v1/users?domain=mydomain.com&event=delete&alt=json
X-Goog-Resource-State:  delete
X-Goog-Message-Number: 236440

{
  "kind": "admin#directory#user",
  "id": "111220860655841818702",
  "etag": "\"Mf8RAmnABsVfQ47MMT_18MHAdRE/evLIDlz2Fd9zbAqwvIp7Pzq8UAw\"",
  "primaryEmail": "user@mydomain.com"
}

根據通知內容採取行動

如要表示成功,您可以傳回下列任一狀態碼:200201202204102

如果您的服務使用 Google 的 API 用戶端程式庫,並傳回 500502503504,Directory API 會以指數遞減方式重試。其他所有傳回的狀態碼都會視為訊息傳送失敗。

停止通知

expiration 屬性可控制通知何時自動停止。您可以選擇在特定管道到期前停止接收通知,方法是在下列 URI 中呼叫 stop 方法:

https://www.googleapis.com/admin/directory_v1/channels/stop

這個方法需要您至少提供管道的 idresourceId 屬性,如以下範例所示。請注意,如果 Directory API 有多種具有 watch 方法的資源類型,則只有一個 stop 方法。

只有具備適當權限的使用者才能停止頻道。請特別注意以下幾點:

  • 如果頻道是由一般使用者帳戶建立,只有建立頻道的使用者 (透過 OAuth 2.0 授權憑證的用戶端 ID 識別) 才能停止頻道。
  • 如果頻道是由服務帳戶建立,則任何同一個用戶端的使用者都能停止頻道。

以下程式碼範例說明如何停止接收通知:

POST https://www.googleapis.com/admin/directory_v1/channels/stop
  
Authorization: Bearer CURRENT_USER_AUTH_TOKEN
Content-Type: application/json

{
  "id": "4ba78bf0-6a47-11e2-bcfd-0800200c9a66",
  "resourceId": "ret08u3rv24htgh289g"
}