本文件說明如何使用推播通知,在資源變更時通知應用程式。
總覽
Google Calendar API 提供推播通知,可讓您監控資源的變化。您可以使用這項功能來改善應用程式的效能。如此一來,您就可以省下輪詢資源相關的額外網路和運算費用,以便判斷這些資源是否有所變動。每當監控的資源有所變更,Google Calendar API 就會通知您的應用程式。
如要使用推播通知,您必須執行下列兩項操作:
設定接收網址或「Webhook」回呼接收器。
這個 HTTPS 伺服器會處理資源變更時觸發的 API 通知訊息。
為您要監控的每個資源端點設定 (通知管道)。
管道會指定通知訊息的轉送資訊。在頻道設定過程中,您必須指明要接收通知的確切網址。每當管道的資源變更時,Google Calendar API 都會以
POST
要求的形式傳送通知訊息至該網址。
目前 Google Calendar API 支援在 Acl、CalendarList、活動和設定資源變更時接收通知。
建立通知管道
如要要求推播通知,您必須為每個要監控的資源設定通知管道。設定通知管道後,如果任何監控的資源有所變更,Google Calendar API 會通知您的應用程式。
提出觀看要求
每項可觀察的 Google Calendar API 資源都有相關聯的 watch
方法,且 URI 的 URI 如下所示:
https://www.googleapis.com/API_NAME/API_VERSION/RESOURCE_PATH/watch
如要設定特定資源變更相關訊息的通知管道,請將 POST
要求傳送至資源的 watch
方法。
每個通知管道都與特定使用者和一項特定資源 (或一組資源) 相關聯。除非目前的使用者擁有這項資源或具備存取這項資源的權限,否則 watch
要求不會成功。
範例
開始觀察特定日曆集中的活動集合變更:
POST https://www.googleapis.com/calendar/v3/calendars/my_calendar@gmail.com/events/watch 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-myCalendarChannelDest", // (Optional) Your channel token. "expiration": 1426325213000 // (Optional) Your requested channel expiration time. }
必要屬性
每次發出 watch
要求時,都必須提供下列欄位:
-
id
屬性字串,專門用來在專案中識別這個新通知管道。建議您使用通用唯一識別碼 (UUID) 或任何類似的不重複字串。長度上限:64 個半形字元。每當您收到這個管道的通知訊息時,系統都會在
X-Goog-Channel-Id
HTTP 標頭中回應您設定的 ID 值。 -
設為
web_hook
值的type
屬性字串。 -
設為網址的
address
屬性字串,會監聽並回應這個通知管道的通知。這是您的 Webhook 回呼網址,必須使用 HTTPS。請注意,您的網路伺服器必須安裝有效的 SSL 憑證,Google Calendar API 才能傳送通知到這個 HTTPS 位址。無效的憑證包括:
- 自行簽署的憑證。
- 由不受信任的來源所簽署的憑證。
- 已撤銷的憑證。
- 憑證的主體與目標主機名稱不符。
選用屬性
您也可以在 watch
要求中指定這些選用欄位:
-
token
屬性,用於指定做為管道權杖的任意字串值。您可以將通知管道權杖用於多種用途。例如,您可以使用此權杖來驗證每則傳入的訊息是否來自您應用程式建立的管道,確保通知不會遭到假冒,或根據這個管道的用途,將訊息轉送至應用程式中的適當目的地。長度上限:256 個字元。應用程式收到該管道收到的每則通知訊息,都會包含在
X-Goog-Channel-Token
HTTP 標頭中。如果您使用通知管道權杖,建議您採取下列做法:
使用可擴充編碼格式,例如網址查詢參數。範例:
forwardTo=hr&createdBy=mobile
請勿加入 OAuth 權杖等機密資料。
-
將
expiration
屬性字串設為 Unix 時間戳記 (以毫秒為單位),指定您希望 Google Calendar API 停止在此通知管道傳送訊息的日期和時間 (以毫秒為單位)。如果管道設有到期時間,會在應用程式收到該管道的每則通知訊息中,納入為
X-Goog-Channel-Expiration
HTTP 標頭的值 (採用人類可讀的格式)。
如要進一步瞭解要求,請參閱 API 參考資料中 Acl、CalendarList、事件和設定資源的 watch
方法。
查看回覆
如果 watch
要求成功建立通知管道,則會傳回 HTTP 200 OK
狀態碼。
手錶回應的訊息內文會提供您剛建立的通知管道相關資訊,如以下範例所示。
{ "kind": "api#channel", "id": "01234567-89ab-cdef-0123456789ab"", // ID you specified for this channel. "resourceId": "o3hgv1538sdjfh", // ID of the watched resource. "resourceUri": "https://www.googleapis.com/calendar/v3/calendars/my_calendar@gmail.com/events", // Version-specific ID of the watched resource. "token": "target=myApp-myCalendarChannelDest", // Present only if one was provided. "expiration": 1426325213000, // Actual expiration time as Unix timestamp (in ms), if applicable. }
除了您在要求中傳送的屬性外,傳回的資訊還包含 resourceId
和 resourceUri
,方便識別在這個通知管道中監控的資源。
您可以將傳回的資訊傳遞給其他通知管道作業,例如您想要停止接收通知時。
如要進一步瞭解回應,請參閱 API 參考資料中 Acl、CalendarList、活動和設定資源的 watch
方法。
同步處理郵件
建立通知管道來監看資源後,Google Calendar API 會傳送 sync
訊息,表示通知即將開始。這些訊息的 X-Goog-Resource-State
HTTP 標頭值為 sync
。由於網路時間問題,即使您尚未收到 watch
方法回應,還是有可能收到 sync
訊息。
您可以放心忽略 sync
通知,但也能使用。舉例來說,如果您決定不想保留管道,可以在呼叫中使用 X-Goog-Channel-ID
和 X-Goog-Resource-ID
值來停止接收通知。您也可以使用 sync
通知執行一些初始化作業,為後續事件做好準備。
以下為 Google Calendar 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
。此管道後續收到的每則通知都有比先前的訊息編號多,不過訊息編號不會依序顯示。
續訂通知管道
通知管道設有到期時間,這個值可由您要求或任何 Google Calendar API 內部限製或預設值決定 (使用較多的值)。如果管道有到期時間,則在 watch
方法傳回的資訊中會納入 Unix 時間戳記 (以毫秒為單位)。此外,在您的應用程式收到的每則通知訊息中,X-Goog-Channel-Expiration
HTTP 標頭中也會包含到期日/時間 (採用使用者可理解的格式)。
目前無法自動續訂通知管道。當管道即將過期時,您必須呼叫 watch
方法,將管道替換為新管道。和往常一樣,新管道的 id
屬性必須使用不重複的值。請注意,相同資源的兩個通知管道啟用時,可能會出現「重疊」的時間範圍。
接收通知
每當監控的資源發生變更,應用程式就會收到說明變更的通知訊息。Google Calendar API 會以 HTTPS POST
要求的形式將這些訊息傳送至您在此通知管道中指定為 address
屬性的網址。
解讀通知訊息格式
所有通知訊息都會包含一組含有 X-Goog-
前置字串的 HTTP 標頭。部分類型的通知也可包含訊息內文。
標頭
Google Calendar API 發布至接收網址的通知訊息包含下列 HTTP 標頭:
標頭 | 說明 |
---|---|
一律顯示 | |
|
您提供的 UUID 或其他不重複的字串,用以識別此通知管道。 |
|
為此通知管道識別此訊息的整數。sync 訊息的值一律為 1 。管道上每則後續訊息傳送的訊息數量都會增加,但這些訊息不會依序產生。 |
|
用於識別受監控資源的不透明值。此 ID 在各 API 版本之間都是穩定的。 |
|
觸發通知的新資源狀態。可能的值:sync 、exists 或 not_exists 。
|
|
已監控資源的 API 版本專屬 ID。 |
有時可提供 | |
|
通知管道到期的日期和時間,以使用者可理解的格式表示。只有在已定義時才會顯示。 |
|
由應用程式設定的通知管道權杖,可用來驗證通知來源。只有在已定義時才會顯示。 |
Google Calendar API 發布至您接收網址的通知訊息不會包含訊息內文。這些訊息不包含更新資源的特定資訊,您必須再次發出 API 呼叫,才能查看完整的變更詳細資料。
示例
針對已修改的事件集合變更通知訊息:
POST https://mydomain.com/notifications // Your receiving URL. Content-Type: application/json; utf-8 Content-Length: 0 X-Goog-Channel-ID: 4ba78bf0-6a47-11e2-bcfd-0800200c9a66 X-Goog-Channel-Token: 398348u3tu83ut8uu38 X-Goog-Channel-Expiration: Tue, 19 Nov 2013 01:13:52 GMT X-Goog-Resource-ID: ret08u3rv24htgh289g X-Goog-Resource-URI: https://www.googleapis.com/calendar/v3/calendars/my_calendar@gmail.com/events X-Goog-Resource-State: exists X-Goog-Message-Number: 10
根據通知內容採取行動
如要表示成功,您可以傳回下列任一狀態碼:200
、201
、202
、204
或 102
。
如果您的服務使用 Google API 用戶端程式庫並傳回 500
、502
、503
或 504
,則 Google Calendar API 會以指數輪詢重試。其他所有傳回狀態碼都視為訊息失敗。
瞭解 Google Calendar API 通知事件
本節詳細說明您在搭配 Google Calendar API 使用推播通知時,可以收到哪些通知訊息。
送達時間 | ||
---|---|---|
sync |
ACL、日曆清單、活動、設定。 | 已成功建立新頻道。你應該會開始收到相關通知。 |
exists |
ACL、日曆清單、活動、設定。 | 資源有所變更。可能的變更包括建立新資源,或是修改或刪除現有資源。 |
停止通知
expiration
屬性可控制自動停止通知的時機。您可以選擇停止接收特定管道的通知,只要在下列 URI 中呼叫 stop
方法即可:
https://www.googleapis.com/calendar/v3/channels/stop
這個方法需要您至少提供頻道的 id
和 resourceId
屬性,如以下範例所示。請注意,如果 Google Calendar API 有多種類型的資源具有 watch
方法,那麼只有一個 stop
方法。
只有具備適當權限的使用者才能停止頻道。請特別注意以下幾點:
- 如果頻道是由一般使用者帳戶建立,則只有建立管道的用戶端相同用戶端 (由驗證權杖中的 OAuth 2.0 用戶端 ID 辨識) 可以停止頻道。
- 如果頻道是由服務帳戶建立,則來自同一用戶端的任何使用者都可以停止頻道。
以下程式碼範例說明如何停止接收通知:
POST https://www.googleapis.com/calendar/v3/channels/stop Authorization: Bearer CURRENT_USER_AUTH_TOKEN Content-Type: application/json { "id": "4ba78bf0-6a47-11e2-bcfd-0800200c9a66", "resourceId": "ret08u3rv24htgh289g" }