Webhook の使用 (アドオンパートナー向け)
最終更新日 2024年05月08日(水)
Table of Contents
Heroku Webhook は、何かが変更された場合の HTTP 通知へのサブスクリプションを提供します。アドオンパートナーは、アプリ、ドメイン、ビルド、リリース、アタッチメント、dyno などのリソースに関連したさまざまなイベントを追跡できます。
Webhook 統合には、Platform API 経由でサブスクライブし、エンドポイントを実装してイベントを受信することが必要です。このドキュメントでは、通知をサブスクライブして受信する方法について詳しく説明します。
Webhook サブスクリプションの作成
イベントを受信する前に、次のようにしてサブスクライブします。
POST api.heroku.com/addons/<uuid>/webhooks
Accept: application/vnd.heroku+json; version=3
{
"authorization": "Bearer 01234567-89ab-cdef-0123-456789abcdef",
"include": [
"api:app",
],
"level": "sync",
"url": "https://myaddon.example.com/webhooks/01234567-89ab-cdef-0123-456789abcdef"
}
<uuid>
は、リソースのプロビジョニングリクエスト中に返されたアドオンインスタンスの UUID に置き換えます。
Webhook サブスクリプションリクエストには、次のパラメータが含まれます。
必須
include
- サーバーが受信する 1 つ以上のイベントタイプ。たとえば、api:app
イベントはアプリ名、Web URL などの変更の通知を提供します。イベントのオプションと詳細については後述します。level
- 配信動作 (notify
またはsync
)。notify
では 1 回きりの “撃ちっ放し” 配信試行になる一方、sync
では成功するかタイムアウトするまで何度も配信を試行します。url
- 受信者の URL
通知の動作を理解するには、アプリの Webhook の記事の「Retries and limits 」(再試行と制限) セクションを参照してください。
配信のステータスは、webhook-deliveries
エンドポイント経由で確認できます。
オプション
authorization
- 受信者と共有されるシークレット。不正な投稿から保護するために、配信ではAuthorization
ヘッダーとしてこれを設定します。この例ではBearer
認証スキームを使用していますが、任意の文字列を使用できます。secret
- 配信の署名に使用する値。配信では、このシークレットをHeroku-Webhook-Hmac-SHA256
ヘッダーとして使用して、本体の HMAC-SHA256 を設定します。
secret
を省略した場合、生成された値は Heroku-Webhook-Secret
ヘッダーで返されます。作成後、この値は再現できないため、この時点でキャプチャする必要があります。そうしない場合、Webhook を PATCH して後からシークレットを更新することができます。
パートナーイベントの例
この記事の執筆時点で、パートナーは以下のイベントをサブスクリプションに含めることができます。
- api:addon-attachment create, destroy
- api:addon create, destroy, update
- api:app create, destroy, update
- api:build create, update
- api:collaborator create, destroy, update
- api:domain create, destroy
- api:dyno create
- api:formation destroy, update
- api:sni-endpoint create, destroy, update
一部のイベントには追加のアクセス許可が必要です。次のイベントへのアクセスをリクエストするには、サポートチケットを開いてください。
これらのイベントは、アドオンまたはそれに関連付けられたアプリに更新が発生すると送信されます。詳細は、Webhook イベント (パートナー向け) を参照してください。
サブスクリプションの管理
サブスクリプションを作成した後、確認または削除が必要になる場合があります。
次のようにして、アドオンの Webhook のリストを要求できます。
GET api.heroku.com/addons/<uuid>/webhooks
Accept: application/vnd.heroku+json; version=3
[{
"addon": {
"id": "01234567-89ab-cdef-0123-456789abcdef",
"name": "acme-inc-primary-database"
},
"created_at": "2015-01-01T12:00:00Z",
"id": "01234567-89ab-cdef-0123-456789abcdef",
"include": [
"api:app",
],
"level": "sync",
"url": "https://myaddon.example.com/webhooks/01234567-89ab-cdef-0123-456789abcdef",
"updated_at": "2015-01-01T12:00:00Z",
}]
次のようにして、アドオンの特定の Webhook の詳細を確認できます。
GET api.heroku.com/addons/<uuid>/webhooks/<uuid>
Accept: application/vnd.heroku+json; version=3
{
"addon": {
"id": "01234567-89ab-cdef-0123-456789abcdef",
"name": "acme-inc-primary-database"
},
"created_at": "2015-01-01T12:00:00Z",
"id": "01234567-89ab-cdef-0123-456789abcdef",
"include": [
"api:app",
],
"level": "sync",
"url": "https://myaddon.example.com/webhooks/01234567-89ab-cdef-0123-456789abcdef",
"updated_at": "2015-01-01T12:00:00Z",
}
最後に、次のようにして、アドオンから既存の Webhook を削除できます。
DELETE api.heroku.com/addons/<uuid>/webhooks/<uuid>
Accept: application/vnd.heroku+json; version=3
{
"addon": {
"id": "01234567-89ab-cdef-0123-456789abcdef",
"name": "acme-inc-primary-database"
},
"created_at": "2015-01-01T12:00:00Z",
"id": "01234567-89ab-cdef-0123-456789abcdef",
"include": [
"api:app",
],
"level": "sync",
"url": "https://myaddon.example.com/webhooks/01234567-89ab-cdef-0123-456789abcdef",
"updated_at": "2015-01-01T12:00:00Z",
}
Webhook の受信
Webhook イベントが一致すると、サーバーへの POST リクエストが実行されます。Authorization
ヘッダーは Webhook 作成時の authorization
値と一致し、Heroku-Webhook-Hmac-SHA256
には、Webhook 作成時に secret
値で本体に署名することで得られた署名が含まれます。結果は次のようなリクエストになります。
POST myaddon.com/webhooks/01234567-89ab-cdef-0123-456789abcdef
Authorization: Bearer 01234567-89ab-cdef-0123-456789abcdef
Heroku-Webhook-Hmac-SHA256: cLM15U5x+jHEkANnVasRwBw2yEHu94pXdjcT9Hajc1M=
{
"action": "update",
"actor": {
"email": "user-0436@example.com",
"id": "096370c8-f3ad-4e20-a309-fb4f06ec0a89"
},
"created_at": "2016-10-26T22:50:14Z",
"id": "d472a8bb-1a3c-4f78-aad1-995e6d0022ec",
"data": {
"archived_at": null,
"buildpack_provided_description": "Ruby/Rails",
"build_stack": {
"id": "5e854079-da33-475b-a209-77f527c0e2fb",
"name": "cedar-14"
},
"created_at": "2016-10-26T22:50:14Z",
"id": "d4714cc8-aa56-4314-817c-0c6a66ff3d41",
"git_url": "https://git.heroku.com/sample-app-0301.git",
"maintenance": false,
"name": "sample-app-0301",
"owner": {
"email": "user-0436@example.com",
"id": "096370c8-f3ad-4e20-a309-fb4f06ec0a89"
},
"region": {
"id": "7044c05a-0873-42c2-abbe-6841c5481ba7",
"name": "us"
},
"organization": null,
"space": null,
"released_at": "2016-10-26T22:50:14Z",
"repo_size": 1048576,
"slug_size": null,
"stack": {
"id": "5e854079-da33-475b-a209-77f527c0e2fb",
"name": "cedar-14"
},
"updated_at": "2016-10-26T22:50:14Z",
"web_url": "https://sample-app-0301.herokuapp.com/"
},
"previous_data": {
},
"published_at": null,
"resource": "app",
"sequence": null,
"updated_at": "2016-10-26T22:50:14Z",
"version": "application/vnd.heroku+json; version=3",
"webhook_metadata": {
"attempt": {
"id": "8a44f820-2354-489d-9a11-a793cbf49979"
},
"delivery": {
"id": "d244009a-670f-4340-88e9-789a4f9002d5"
},
"event": {
"id": "d472a8bb-1a3c-4f78-aad1-995e6d0022ec",
"include": "api:app"
},
"webhook": {
"id": "01234567-89ab-cdef-0123-456789abcdef"
}
}
}
配信が成功したことを示すには、常に 200 系列のステータスコードで応答する必要があります。Heroku では応答の本体は無視されるため、本体が空の 204 が理想的です。
204 No Content
配信の検査
配信のために Heroku がキューに入れる (または入れた) もののリストは、次のようにして取得できます。
GET api.heroku.com/addons/<uuid>/webhook-deliveries/<uuid>
Accept: application/vnd.heroku+json; version=3
[
{
"created_at": "2015-01-01T12:00:00Z",
"event": {
"id": "01234567-89ab-cdef-0123-456789abcdef"
},
"id": "01234567-89ab-cdef-0123-456789abcdef",
"status": "pending",
"updated_at": "2015-01-01T12:00:00Z",
"webhook": {
"id": "01234567-89ab-cdef-0123-456789abcdef"
}
}
]
status
は failure
、pending
、success
のいずれかです。最新の updated_at
の値をチェックすることで、キューに入っている配信の数と配信の成否を確認できます。
イベントの検査
例
サブスクライブ時に、1 つ以上のインクルード値を含めることができます。以下、使用する可能性がある特定のインクルードの具体例と、それぞれの期待される動作を示します。
アプリの Webhook
アプリ名の変更など、アプリの詳細を追跡するには、次のようにして api:app
イベントをサブスクライブします。
POST api.heroku.com/addons/:uuid/webhooks
Accept: application/vnd.heroku+json; version=3
{
"authorization": "Bearer 01234567-89ab-cdef-0123-456789abcdef",
"include": [
"api:app",
],
"level": "sync",
"url": "https://myaddon.com/webhooks/01234567-89ab-cdef-0123-456789abcdef"
}
応答は次のようになります。
200 OK
Heroku-Webhook-Secret: 0123456789abcdef0123456789abcdef0123456789abcdef0123456789ab
{
"addon": {
"id": "01234567-89ab-cdef-0123-456789abcdef",
"name": "acme-inc-primary-database"
},
"created_at": "2015-01-01T12:00:00Z",
"id": "01234567-89ab-cdef-0123-456789abcdef",
"include": [
"release"
],
"level": "notify",
"updated_at": "2015-01-01T12:00:00Z",
"url": "example"
}
以後、フォーメーションの変更時に、次のような内容を受信します。
POST myaddon.com/webhooks/01234567-89ab-cdef-0123-456789abcdef
Authorization: Bearer 01234567-89ab-cdef-0123-456789abcdef
Heroku-Webhook-Hmac-SHA256: cLM15U5x+jHEkANnVasRwBw2yEHu94pXdjcT9Hajc1M=
{
"action": "update",
"actor": {
"email": "user-0436@example.com",
"id": "096370c8-f3ad-4e20-a309-fb4f06ec0a89"
},
"created_at": "2016-10-26T22:50:14Z",
"id": "d472a8bb-1a3c-4f78-aad1-995e6d0022ec",
"data": {
"archived_at": null,
"buildpack_provided_description": "Ruby/Rails",
"build_stack": {
"id": "5e854079-da33-475b-a209-77f527c0e2fb",
"name": "cedar-14"
},
"created_at": "2016-10-26T22:50:14Z",
"id": "d4714cc8-aa56-4314-817c-0c6a66ff3d41",
"git_url": "https://git.heroku.com/sample-app-0301.git",
"maintenance": false,
"name": "sample-app-0301",
"owner": {
"email": "user-0436@example.com",
"id": "096370c8-f3ad-4e20-a309-fb4f06ec0a89"
},
"region": {
"id": "7044c05a-0873-42c2-abbe-6841c5481ba7",
"name": "us"
},
"organization": null,
"space": null,
"released_at": "2016-10-26T22:50:14Z",
"repo_size": 1048576,
"slug_size": null,
"stack": {
"id": "5e854079-da33-475b-a209-77f527c0e2fb",
"name": "cedar-14"
},
"updated_at": "2016-10-26T22:50:14Z",
"web_url": "https://sample-app-0301.herokuapp.com/"
},
"previous_data": {
},
"published_at": null,
"resource": "app",
"sequence": null,
"updated_at": "2016-10-26T22:50:14Z",
"version": "application/vnd.heroku+json; version=3",
"webhook_metadata": {
"attempt": {
"id": "8a44f820-2354-489d-9a11-a793cbf49979"
},
"delivery": {
"id": "d244009a-670f-4340-88e9-789a4f9002d5"
},
"event": {
"id": "d472a8bb-1a3c-4f78-aad1-995e6d0022ec",
"include": "api:app"
},
"webhook": {
"id": "01234567-89ab-cdef-0123-456789abcdef"
}
}
}
配信が成功したことを示すには、200 系列のステータスコードで応答する必要があります。応答の本体は無視されるため、ほとんどの場合、次のように応答する必要があります。
204 No Content
リリースの Webhook
アプリのリリースを追跡するために、次のようにして api:release
イベントをサブスクライブできます。
POST api.heroku.com/addons/:uuid/webhooks
Accept: application/vnd.heroku+json; version=3
{
"authorization": "Bearer 01234567-89ab-cdef-0123-456789abcdef",
"include": [
"api:release",
],
"level": "sync",
"url": "https://myaddon.com/webhooks/01234567-89ab-cdef-0123-456789abcdef"
}
応答は次のようになります。
200 OK
Heroku-Webhook-Secret: 0123456789abcdef0123456789abcdef0123456789abcdef0123456789ab
{
"addon": {
"id": "01234567-89ab-cdef-0123-456789abcdef",
"name": "acme-inc-primary-database"
},
"created_at": "2015-01-01T12:00:00Z",
"id": "01234567-89ab-cdef-0123-456789abcdef",
"include": [
"release"
],
"level": "notify",
"updated_at": "2015-01-01T12:00:00Z",
"url": "example"
}
以後、フォーメーションの変更時に、次のような内容を受信します。
POST myaddon.com/webhooks/01234567-89ab-cdef-0123-456789abcdef
Authorization: Bearer 01234567-89ab-cdef-0123-456789abcdef
Heroku-Webhook-Hmac-SHA256: cLM15U5x+jHEkANnVasRwBw2yEHu94pXdjcT9Hajc1M=
{
"action": "create",
"actor": {
"email": "heroku-postgresql@addons.heroku.com",
"id": "f87b5e7e-4631-46cc-9912-9fcdbbb6c985"
},
"created_at": "2016-10-26T22:50:29Z",
"id": "b6a68e77-8c13-41c8-b30c-b50cca7a608a",
"data": {
"addon_plan_names": [
"heroku-postgresql:essential-0"
],
"app": {
"id": "44dc9c7a-771c-4a9e-bfe9-a8dbc1c55f4d",
"name": "sample-app-0339"
},
"created_at": "2016-10-26T22:50:29Z",
"description": "Update DATABASE by heroku-postgresql",
"status": "succeeded",
"id": "5f1463a4-0210-43ba-b906-52599e246482",
"slug": null,
"updated_at": "2016-10-26T22:50:29Z",
"user": {
"email": "heroku-postgresql@addons.heroku.com",
"id": "f87b5e7e-4631-46cc-9912-9fcdbbb6c985"
},
"version": 3,
"current": true
},
"previous_data": {
},
"published_at": null,
"resource": "release",
"sequence": null,
"updated_at": "2016-10-26T22:50:29Z",
"version": "application/vnd.heroku+json; version=3",
"webhook_metadata": {
"attempt": {
"id": "8a44f820-2354-489d-9a11-a793cbf49979"
},
"delivery": {
"id": "d244009a-670f-4340-88e9-789a4f9002d5"
},
"event": {
"id": "b6a68e77-8c13-41c8-b30c-b50cca7a608a",
"include": "api:release"
},
"webhook": {
"id": "01234567-89ab-cdef-0123-456789abcdef"
}
}
}
配信が成功したことを示すには、200 系列のステータスコードで応答する必要があります。応答の本体は無視されるため、ほとんどの場合、次のように応答する必要があります。
204 No Content
フォーメーションの Webhook (追加のアクセス許可が必要)
アドオンインスタンスにアタッチされている実行中の dyno の数とサイズを追跡するには、次のようにして api:formation
イベントをサブスクライブします。
POST api.heroku.com/addons/:uuid/webhooks
Accept: application/vnd.heroku+json; version=3
{
"authorization": "Bearer 01234567-89ab-cdef-0123-456789abcdef",
"include": [
"api:formation",
],
"level": "sync",
"url": "https://myaddon.com/webhooks/01234567-89ab-cdef-0123-456789abcdef"
}
応答は次のようになります。
200 OK
Heroku-Webhook-Secret: 0123456789abcdef0123456789abcdef0123456789abcdef0123456789ab
{
"addon": {
"id": "01234567-89ab-cdef-0123-456789abcdef",
"name": "acme-inc-primary-database"
},
"created_at": "2015-01-01T12:00:00Z",
"id": "01234567-89ab-cdef-0123-456789abcdef",
"include": [
"release"
],
"level": "notify",
"updated_at": "2015-01-01T12:00:00Z",
"url": "example"
}
以後、フォーメーションの変更時に、次のような内容を受信します。
POST myaddon.com/webhooks/01234567-89ab-cdef-0123-456789abcdef
Authorization: Bearer 01234567-89ab-cdef-0123-456789abcdef
Heroku-Webhook-Hmac-SHA256: cLM15U5x+jHEkANnVasRwBw2yEHu94pXdjcT9Hajc1M=
{
"action": "update",
"actor": {
"email": "user-0297@example.com",
"id": "2530e242-a531-4d37-99ab-d8997e2335d0"
},
"created_at": "2016-10-26T22:49:29Z",
"id": "89d9e649-1ecf-464e-a15d-86c15365fc40",
"data": {
"app": {
"id": "b225a8d2-1602-42c3-a1a2-98c3c266cc0d",
"name": "sample-app-0197"
},
"command": "ruby server.rb",
"created_at": "2016-10-26T22:49:29Z",
"id": "13f27e47-df06-48a1-92be-f521babd9060",
"type": "web",
"quantity": 0,
"size": "1X",
"updated_at": "2016-10-26T22:49:29Z"
},
"previous_data": {
"quantity": 1
},
"published_at": null,
"resource": "formation",
"sequence": null,
"updated_at": "2016-10-26T22:49:29Z",
"version": "application/vnd.heroku+json; version=3",
"webhook_metadata": {
"attempt": {
"id": "8a44f820-2354-489d-9a11-a793cbf49979"
},
"delivery": {
"id": "d244009a-670f-4340-88e9-789a4f9002d5"
},
"event": {
"id": "89d9e649-1ecf-464e-a15d-86c15365fc40",
"include": "api:formation"
},
"webhook": {
"id": "01234567-89ab-cdef-0123-456789abcdef"
}
}
}
配信が成功したことを示すには、200 系列のステータスコードで応答する必要があります。応答の本体は無視されるため、ほとんどの場合、次のように応答する必要があります。
204 No Content
よくある質問
Heroku アプリのアドオンのユーザーアクセスをミラーリングするには、共同作業者の Webhook で十分ですか?
いいえ。エンタープライズおよびチームアカウントが所有するアプリの場合、ユーザーロールも追跡する必要があります。この機能はまだ Webhook として公開されていません。ポーリングベースのアプローチについては、こちらの記事を参照してください。
通常、アクセス許可のミラーリングが必要なのは、Heroku が提供するアドオン SSO 以外の追加認証を経由してアドオンへのアクセスを許可する場合に限られることに注意してください。