Webhookとは?仕組み・APIとの違いとIncoming Webhookの使い方をわかりやすく解説

Webhook(ウェブフック)とは、あるサービスでイベントが起きたとき、あらかじめ登録しておいたURLへ自動でHTTPリクエストを送り、別のシステムへ通知やデータを届ける仕組みです。「何か起きたら相手から教えてくれる」プッシュ型の連携で、Slackへの通知やECサイトの注文連携など、リアルタイムな自動化の土台として広く使われています。この記事では、Webhookの基本から、よく混同されるAPIとの違い、Incoming/Outgoingの違い、Slack・Discordでの具体的な送信例、そしてセキュリティ対策までを一気に整理します。

まとめ

先に要点だけ押さえておきましょう。

  • Webhookとは:イベント発生をきっかけに、登録済みURLへサーバー側から自動でHTTP(多くはPOST)を送る「プッシュ型」の通知の仕組み。
  • APIとの違い:APIは欲しいときにこちらから取りに行く「プル型」、Webhookは起きた瞬間に届く「プッシュ型」。ポーリングの無駄な通信を減らせる。
  • Incoming/Outgoing:外部から自分のサービスへ受け取るのがIncoming、自分から外部へ送るのがOutgoing。SlackやDiscordへの通知は代表的なIncomingの例。
  • 使い方:受信側でWebhook URLを発行し、そのURLへJSONをPOSTするだけ。curlやプログラムから数行で送れる。
  • 注意点:URLは秘密情報として扱い、署名検証・HTTPS・レート制限・再送設計(冪等性)をセットで考える。

それぞれを、図解的なイメージと具体的なコードを交えて順に見ていきます。

Webhookとは何か

Webhookは、特定のイベント(フォーム送信、注文確定、ビルド完了など)が発生したときに、発信元のサービスが「受信先のURL」へ自動的にHTTPリクエストを送る仕組みです。送られるリクエストの本体には、イベントの内容がJSONなどの形式で含まれており、受信側はそれを受け取って通知の表示やデータベース更新といった処理を行います。一度URLとイベントを登録しておけば、あとはイベントが起きるたびに自動で通知が飛ぶため、人手による確認や定期的な問い合わせが不要になります。

「Webhook」という名前は、Web上のイベントに対して任意の処理を引っかける(hook)ことに由来します。サービス側に常駐プログラムを置く必要はなく、URLを1つ用意するだけで連携が始められる手軽さが特徴です。

WebhookとAPIの違い

WebhookとAPIはどちらもシステム間でデータをやり取りする手段ですが、通信のきっかけが正反対です。API(特にREST API)は、必要になったときに利用者側からサーバーへリクエストを送って情報を取得する「プル型」です。最新情報を知りたい場合は、一定間隔で何度も問い合わせる「ポーリング」が必要になり、変化がないときも通信が発生します。一方Webhookは、イベントが起きた瞬間にサーバー側から送られてくる「プッシュ型」のため、無駄な通信を抑えつつリアルタイムに近い連携が実現できます。

観点 Webhook API(REST)
通信のきっかけ イベント発生時 必要なとき
方式 プッシュ型 プル型
リアルタイム性 高い 間隔に依存
無駄な通信 少ない 発生しやすい
事前設定 受信URLの登録 原則不要
向くケース 通知・即時連携 好きな時に取得

両者は対立するものではなく、補完関係です。「変化があったら教えてほしい」場面ではWebhook、「今この時点のデータが欲しい」場面ではAPIと使い分けます。なお同じプル型のAPIでも設計思想に違いがあり、REST APIとGraphQLの比較はGraphQLとREST APIの違いは何か?その主要な特徴を比較で詳しく解説しています。

Webhookの仕組み(通知が届くまでの流れ)

Webhookは「発信元」と「受信先」の2者で成り立ちます。通知が届くまでの流れは次のとおりです。

  • 1. 設定:発信元のサービスで、通知したいイベントと送信先(Webhook URL)を登録する。
  • 2. 発火:登録したイベントが発生すると、発信元が受信URLへHTTPリクエスト(通常はPOST)を送る。
  • 3. 受信・処理:受信側がリクエストの中身(ペイロード)を解析し、通知・記録・別処理の呼び出しなどを実行する。

ヘッダーとペイロードの基本

送られてくるリクエストは、メタ情報を載せる「ヘッダー」と、実際のデータを載せる「ボディ(ペイロード)」に分かれます。ヘッダーにはContent-Typeや認証・署名情報が入り、ボディにはイベントの詳細がJSONなどで入ります。受信側は送信元サービスの仕様に合わせてペイロードを解析する必要があるため、連携先の公式ドキュメントでフィールドの形式を確認しておくことが大切です。

Webhookの主な活用例

Webhookは「イベントが起きた瞬間に自動で通知・連携する」という性質から、手作業の確認や定期的なポーリングを置き換える用途で幅広く使われています。代表的なものを挙げます。

  • チャット通知:GitHubへのプッシュやサーバーのエラー発生をトリガーに、SlackやDiscordのチャンネルへ即時通知する。もっとも身近な使い方です。
  • CI/CD連携:ビルドやデプロイの成功・失敗をフックして、後続のデプロイ処理や担当者への通知を自動化する。
  • ECサイトの注文・在庫連携:注文確定をトリガーに在庫管理や配送のシステムへデータを渡し、在庫数の更新や出荷指示をリアルタイムに行う。
  • フォーム送信からのCRM連携:問い合わせや資料請求が発生した瞬間に顧客管理システムへリードを登録し、営業担当へ通知する。
  • 監視・アラート:サービスやサーバーの異常検知をフックして、即座に運用チームへアラートを飛ばす。

いずれも「変化が起きた瞬間に動く」というWebhookの特性を活かし、人手を介さずにシステム同士をつなぐ自動化の起点として機能します。次のセクションでは、こうした連携を「受け取る側」「送る側」のどちらから見るかで整理します。

Incoming WebhookとOutgoing Webhookの違い

Webhookは向きによって2種類に分けて語られることがあります。外部サービスから自分のシステムへ情報を「受け取る」のがIncoming Webhook、自分のサービスから外部へ情報を「送る」のがOutgoing Webhookです。SlackやDiscordに通知を送る用途は、受信側(チャットツール)から見ればIncoming Webhookにあたり、最も身近な実例です。

種類 向き 代表的な使い方
Incoming Webhook 外部 → 自分 外部通知の受け取り
Outgoing Webhook 自分 → 外部 外部URLへ送信

Incoming Webhookを実際に使う(Slack)

もっとも需要が多いのが、SlackへIncoming Webhookで通知を送るケースです。現在のSlackでは、Webhook URLは「Slackアプリ」を作成して発行します。アプリディレクトリから直接追加する旧来の方式(レガシーのカスタムインテグレーション)は非推奨となっているため、新規に作る場合はアプリ経由が基本です。

Webhook URLを発行する手順

  • 1. Slackのアプリ管理ページ(api.slack.com/apps)で「Create New App」→「From scratch」を選ぶ。
  • 2. アプリ名と対象ワークスペースを指定して作成する。
  • 3. 「Incoming Webhooks」を有効化し、通知先チャンネルを選んでWebhook URLを発行する。

curlでメッセージを送る

発行したURLへ、JSONをPOSTするだけで投稿できます。Slackでは本文をtextフィールドに入れます。

curl -X POST \
  -H "Content-Type: application/json" \
  -d '{"text": "デプロイが完了しました :rocket:"}' \
  https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXX

URL部分は発行された自分のWebhook URLに置き換えてください。リッチな見た目にしたい場合は、textの代わりにBlock Kit(blocks)形式のペイロードを使います。

Pythonで送る

スクリプトやバッチから送る場合は、標準ライブラリだけでも実装できます。

import json
import urllib.request
 
url = "https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXX"
payload = {"text": "ビルドに失敗しました。ログを確認してください。"}
 
data = json.dumps(payload).encode("utf-8")
req = urllib.request.Request(
    url,
    data=data,
    headers={"Content-Type": "application/json"},
)
with urllib.request.urlopen(req) as res:
    print(res.status)  # 200 なら投稿成功

cronなどのスケジューラと組み合わせれば、サーバーの状態を定期的にSlackへ報告するといった運用も簡単に実現できます。送信に使うURLはコードに直書きせず、環境変数で管理するのが安全です。

DiscordとMicrosoft Teamsで使う場合

Discord

Discordはチャンネル設定の「連携サービス」からWebhookを作成し、発行されたURLへJSONをPOSTします。本文はSlackと異なりcontentフィールドに入れる点に注意してください。

curl -X POST \
  -H "Content-Type: application/json" \
  -d '{"content": "ビルドが成功しました"}' \
  https://discord.com/api/webhooks/123456789/your-webhook-token

Microsoft Teams(旧Incoming Webhookは廃止・移行が必要)

Teamsでは長く「Incoming Webhook(Office 365コネクタ)」が使われてきましたが、Microsoftはこの旧コネクタを段階的に廃止し、2026年5月のロールアウト(5月18日〜22日)をもって提供を終了しました。後継はPower Automateの「Workflows」で、既存の連携はWorkflowsのwebhookへ移行が必要です。WorkflowsのwebhookはMessageCard形式のペイロードも再フォーマットなしで送信できますが、ボタンなどインタラクティブな要素を使う場合はAdaptive Card形式が必要になります。移行の対応状況や仕様は変動してきた経緯があるため、最新の手順はMicrosoftの公式アナウンス(Retirement of Office 365 connectors within Microsoft Teams)で確認してください。これからTeams通知を新規に組む場合は、最初からWorkflowsで実装するのが安全です。

Webhookのセキュリティ対策

Webhookの受信URLは「知っていれば誰でもリクエストを送れる」公開エンドポイントです。URLが漏れると、なりすましの通知やスパムを送り込まれるおそれがあるため、URL自体を秘密情報として扱うことが大前提になります。ソースコードに直書きせず、環境変数やシークレット管理の仕組みで保管しましょう。

署名検証で送信元を確かめる

多くのサービスは、リクエストヘッダーに署名(HMACなど)を付けて送ってきます。受信側は、事前に共有された秘密鍵で本文から署名を再計算し、ヘッダーの署名と一致するかを検証することで、「正規の送信元から、改ざんされずに届いたリクエスト」だけを処理できます。あわせて通信はHTTPSに限定し、盗聴や中間者攻撃を防ぎます。受信したデータも、そのまま使わずスキーマ検証やサニタイズを行うことで、不正なデータの混入を防げます。

Webhook導入時の注意点

便利な反面、設計を誤ると通知の取りこぼしや二重処理が起きます。実運用では次の点を押さえておきましょう。

  • レート制限:送信先には単位時間あたりの上限がある。超過すると一時的に拒否されるため、まとめ送信やキューイングで間引く。
  • 再送と冪等性:送信側は失敗時に指数バックオフで再試行する設計が一般的。受信側は同じリクエストを複数回受け取っても結果が変わらない「冪等」な処理にしておく。
  • ステータスコード:受信側は正常に受け取れたら200番台を返す。エラー時は原因に応じた4xx/5xxを返し、送信側のリトライ判断を正しく促す。
  • ログと監視:受け取った内容と結果をログに残し、一定回数失敗したらアラートを出す仕組みを用意しておくと障害対応が早くなる。

よくある質問(FAQ)

Q. WebhookとAPIはどちらを使えばいいですか?

「変化が起きたら通知してほしい」ならWebhook、「必要なタイミングで自分から取りに行きたい」ならAPIが適しています。通知をきっかけにAPIで詳細データを取得するなど、両者を組み合わせる構成もよく使われます。

Q. Webhookに通知が届きません。何を確認すべきですか?

まずWebhook URLが正しいか(古いURLや打ち間違いがないか)、Content-Typeが正しく、JSONが有効な形式かを確認します。次に受信先サービスの稼働状況、返ってきたHTTPステータスコード、通知先チャンネルの設定(アプリが参加しているか)の順に切り分けると原因を特定しやすくなります。

Q. 「Invalid payload」エラーが出ます。

送信したJSONの構造に誤りがあるサインです。必須フィールド(Slackならtext、Discordならcontent)の不足、クォート漏れ、特殊文字のエスケープ漏れが主な原因です。送信前にJSONの妥当性をチェックすると防げます。

Q. Webhook URLが漏れたらどうなりますか?

第三者がそのチャンネルへ自由に投稿できてしまいます。漏洩に気づいたら速やかにWebhookを無効化・再発行し、URLは環境変数やシークレット管理で扱ってください。

Q. Teamsで昔のIncoming Webhookが使えなくなりました。

Teamsの旧Incoming Webhook(Office 365コネクタ)は2026年5月に廃止され、Power AutomateのWorkflowsへの移行が必要です。WorkflowsのwebhookではMessageCard形式のペイロードも再フォーマットなしで使えますが、ボタンなどインタラクティブな要素を使う場合はAdaptive Card形式が必要です。最新の対応状況は公式の移行ガイドで確認のうえ、再設定してください。

関連記事

資料請求

RELATED POSTS 関連記事