Webhook とは
Webhook は、あるサービスで出来事が起きたとき、決めておいた URL へその内容を自動で送る仕組みです。こちらから何度も確かめに行かなくても、知らせを受けてすぐに次の作業を始められます。
この記事でわかること
- Webhook が何をする仕組みかを説明できる
- ポーリングとの違いと、イベント・ペイロードの意味がわかる
- 署名の確かめ方と、送り直しや重なりへの備え方を知る
目次
Webhook(ウェブフック)は、あるサービスで出来事が起きたときに、あらかじめ決めておいた URL へ、その内容を自動で送る仕組みです。こちらから確かめに行かなくても、相手のサービスのほうから知らせが届きます。
たとえば、教室の申し込みフォームに新しい申し込みが入ったら、すぐにチームのチャットへ知らせたり、名簿に加えたりしたいことがあります。Webhook のしくみを知っておくと、こうした「起きたらすぐ動く」つなぎ方ができるかを判断でき、受け取る側で気を付けること(本物かどうかの確認や、二重に届いたときの扱い)もわかります。
- 出来事が起きるフォームに新しい回答
- 送る側が知らせる署名付きの JSON を POST
- 受け口が確かめる署名・時刻・処理済みの ID
- 返事をする失敗なら時間をおいて再送
Webhook は何のためにあるのか
API は、こちらから必要なときに問い合わせるつなぎ方です。Webhook はその逆で、出来事が起きた側のサービスが、こちらの URL に知らせを送ってきます。
Webhook は、たとえば次のような場面で使われます。
- 教室の申し込みフォームに回答が届いたら、チームのチャットに知らせる
- オンライン講座の支払いが終わったら、受講の登録を始める
- 小さな会社に届いた問い合わせを、顧客管理のツールに自動で加える
Webhook は特定の規格の名前ではなく、広く使われているやり方の呼び名です。そのため、送る中身の形や確かめ方はサービスごとに少しずつ違います。実際につなぐときは、送る側のサービスの説明を確かめます。
ポーリングとどう違うのか
出来事を知るもう 1 つの方法が、ポーリングです。ポーリングは、決まった間隔で「新しいものはありますか」と API に問い合わせ続けるやり方です。
郵便で考えるとわかりやすいでしょう。ポーリングは、1 時間ごとに郵便受けを見に行くようなものです。Webhook は、荷物が届いたら呼び鈴が鳴るようなものです。
| ポーリング | Webhook | |
|---|---|---|
| 誰が動くか | 受け取る側が問い合わせる | 出来事が起きた側が送る |
| 知るまでの時間 | 次に問い合わせるまで遅れる | 出来事のすぐあと |
| むだな通信 | 何もなくても問い合わせる | 出来事があるときだけ |
| 受け取る側の準備 | 問い合わせるプログラム | インターネットから届く https の URL |
ポーリングにも良いところがあります。受け取る側に公開の URL が要らず、自分の都合のよいときに取りに行けます。実際には、すぐに知りたいことは Webhook で受け、取りこぼしがないかをときどき API で確かめる、という組み合わせもよく使われます。
Webhook はどう動くのか
Webhook の流れは次のとおりです。
- 受け取る側が、送り先の URL(受け口)を送る側のサービスに登録する
- 送る側で出来事が起きる
- 送る側が、出来事の内容を受け口へ HTTP の POST で送る
- 受け口が中身を確かめ、受け取ったことを 200 番台のステータスコードで返す
- 返事がない・失敗が返ったときは、送る側が時間をおいて送り直す
イベントとは
イベントは、Webhook のきっかけになる出来事です。「フォームに回答が届いた」「支払いが終わった」「予定が取り消された」などがあり、form.submission.created のような名前が付いていることがよくあります。どのイベントで送るかを選べるサービスもあります。
ペイロードとは
ペイロードは、送られてくる中身のことです。多くは JSON で、イベントの名前や出来事の時刻、関係するデータが入ります。必要なデータを全部入れるサービスもあれば、ID だけを送り、詳しい中身は API で取りに来てもらうサービスもあります。
受け口は、届いたらできるだけ早く 200 番台で返事をするのが基本です。時間のかかる処理(メールを送る、ほかのツールに登録するなど)は、受け取ったことを記録してから後で行います。そうすると、送る側が時間切れとみなして送り直すのを防げます。
署名で何を確かめるのか
受け口の URL は、インターネットのどこからでも呼べます。そのため、URL を知った人が偽の知らせを送ってくるおそれがあります。これを見分けるのが署名です。
多くのサービスは、HMAC(エイチマック)で署名を作ります。HMAC は、秘密の文字列(鍵)とハッシュ関数を使って、本文から決まった長さの値を作る方法です。くわしくは MDN の用語集の「HMAC」にあります。送る側と受け取る側だけが同じ秘密を持ち、送る側は本文と秘密から計算した値をヘッダーに付けて送ります。受け取る側が手元の秘密で同じ計算をして値が一致すれば、秘密を知る相手から、途中で書き換えられずに届いたとわかります。
確かめるときは、次の点を押さえます。
- 届いたままの本文で計算する(JSON として読み込んでから書き直すと、空白や並びが変わって一致しなくなります)
- サービスの説明どおりの材料と方法で計算する(「時刻と本文をつないだもの」に署名する、といった決まりがあります)
- 値は、かかる時間が中身に左右されない方法で比べる(多くのプログラミング言語に用意されています)
- 署名に時刻が入っているときは、古すぎる知らせを断る(一度届いた知らせを写して後から送りつける「リプレイ攻撃」を防げます)
- 一致しない知らせは処理せずに断る
署名の秘密は、API キーと同じように扱います。ブラウザーに届くコードや公開の場所に書かず、漏れたかもしれないときは作り直します。
届かないときや二回届いたときはどうなるのか
受け口が止まっていたり、時間切れになったりすると、多くのサービスは時間をおいて何度か送り直します。1 分後、5 分後、30 分後のように、間隔をだんだん長くするのが一般的です。
送り直しがあるということは、同じ知らせが 2 回以上届くことがある、ということでもあります。たとえば、受け口は処理を終えていたのに、返事が届く前に通信が切れると、送る側は失敗とみなして送り直します。また、届く順番が出来事の順番と同じとは限りません。
そこで受け取る側は、同じ知らせを何度受け取っても結果が変わらないように作ります。この性質をべき等(MDN の用語集)といいます。
- 知らせに付いている ID(配送や出来事の ID)を記録し、処理済みの ID が来たら何もせずに 200 番台を返す
- 名簿に加える前に、同じ申し込みがすでにないかを確かめる
- 届いた順番に頼らず、必要なら出来事の時刻を見て新しいほうを残す
送り直しにも回数や期間の限りがあります。受け口が長く止まっていたときは、送る側の管理画面の送り状況や API で、取りこぼしがないかを確かめます。
まとめ
- Webhook は、出来事が起きたときに相手から知らせが届くつなぎ方です
- ポーリングと比べて早く知ることができ、むだな通信も減ります
- 届いた知らせは、署名と時刻で本物かを確かめます
- 同じ知らせが重なることがあるので、ID で見分けて、何度受け取っても同じ結果になるように作ります
mukumo では Webhook で何を受け取れますか
mukumo(ムクモ)のフォーム作成では、フォームの設定の「Webhook」に https の送り先 URL を入れると、回答が届くたびにその回答を JSON で送ります。X-Webhook-Signature ヘッダーには、設定の「署名の秘密」で「時刻.本文」を HMAC-SHA256 で計算した値が入るので、同じ計算をして mukumo から届いたことを確かめられます。
一時的に届かなかったときは、時間をおいて自動でやり直します。回答の画面で送り状況を確かめられ、編集できる人は「もう一度送る」で送り直せます。同じ回答が重なって届いたときは、X-Webhook-Delivery ヘッダーで見分けられます。
よくある質問
Webhook を受け取るには自分のサーバーが必要ですか
インターネットから届く https の URL があれば受け取れます。自分でサーバーを持たなくても、ノーコードの自動化ツールや、短いプログラムを置けるクラウドのサービスで受け口を作れます。
Webhook と API はどちらを使えばよいですか
どちらか一方に決める必要はありません。すぐに知りたい出来事は Webhook で受け、詳しいデータの取得や取りこぼしの確認には API を使う、という組み合わせがよく使われます。
受け口の URL を知られたら危ないですか
URL は推測されにくいものにしておくとよいですが、URL を秘密にすることだけには頼れません。届いた知らせの署名を確かめれば、URL を知った人からの偽の知らせを断れます。
Webhook はどうやって試せばよいですか
テストの知らせを送る機能や、送った記録を見る画面を用意しているサービスが多くあります。本番とは別に試しの受け口を作り、署名の確かめや重なりの扱いまで試しておくと安心です。