Webhook

受信 Webhook は、秘密の URL に JSON を送信することで、他のシステムがチャンネルに投稿できるようにします。送信 Webhook はその逆で、トリガーワードで始まるメッセージ、またはメッセージメニューで選択されたメッセージをあなたの URL に送信し、あなたが応答した内容を投稿します。

Webhookの管理場所

右上のアバターを開き、統合機能を選択します。現在のコミュニティの統合機能ページには、内向きのウェブフックと外向きのウェブフックがリスト表示されます。各Webhookは1つのコミュニティに属します。

デフォルトでは、コミュニティ管理者とシステム管理者がWebhookを作成できます。システム管理者は、システムコンソールの権限設定で他のロールにこの権限を付与できます。また、システム管理者はシステムコンソール › 統合機能 › 統合機能管理で各タイプを無効にすることもできます。内向きのウェブフックを有効にすると外向きのウェブフックを有効にするは、デフォルトで両方ともオンになっています。

A channel with messages from a CI bot and from GitHub, shown as cards with fields, pipeline stages and a button
カードとして描画される統合機能メッセージ:フィールド、パイプラインステージ、アクションボタン。

内向きWebhookの作成

  1. 統合機能で内向きのウェブフックを選択し、内向きのウェブフックを追加するをクリックします。
  2. タイトルと説明を入力します。これらは統合機能ページでのみ表示されます。
  3. メッセージがデフォルトで送信先となるチャンネルを選択します。非公開チャンネルの場合、そのメンバーである必要があります。
  4. 送信者が他の場所に投稿できないようにする場合は、このチャンネルに固定するにチェックを入れます。
  5. 必要に応じて、そのメッセージ用のユーザー名とプロフィール画像のURLを設定します(名前とアイコンを参照)。
  6. 保存するを選択します。表示されたURLをコピーします:https://chat.example.com/hooks/<key>。
このURLは唯一の秘密です:これを保有する者は誰でもチャンネルに投稿できます。公開リポジトリに公開しないよう注意し、漏洩した場合はWebhookを削除してください。

APIを使用する場合:POST /api/v4/hooks/incomingに{"channel_id", "display_name", "description", "username", "icon_url", "channel_locked"}を送信します。レスポンスのidがキーです。コマンドラインから:amctl webhook create-incoming --channel <channel id> --user <user> --display-name "CI"。

内向きWebhookへのメッセージ送信

curl -X POST https://chat.example.com/hooks/xgh5ycrx1jf7mbs9w8z4c8e7ho \
  -H 'Content-Type: application/json' \
  -d '{"text": "Deploy of **api 2.4.0** finished :white_check_mark:"}'

サーバーは200を返し、ボディにokを返します。SlackのWebhookと同様に、JSONをpayloadフィールドに含めたapplication/x-www-form-urlencodedも受け付けるため、Slack向けに作られたツールは通常、変更なしで動作します。

フィールド意味
textMarkdown形式のメッセージ。attachmentsがない場合は必須です。サーバーのメッセージ上限を超える長文は、複数のメッセージに分割されます。
channelWebhook のコミュニティの別のチャンネル(名前を指定、ops-alerts または #ops-alerts)、または Webhook の所有者からのダイレクトメッセージには @username を使用します。Webhook がそのチャンネルにロックされている場合は拒否されます。旧名称 town-square は、現在 general と呼ばれるコミュニティのデフォルトチャンネルに依然として到達します。
username, icon_url, icon_emojiサーバーが上書きを許可している場合に、表示する名前と画像。
attachmentsメッセージの添付ファイル。カードとして表示されます(下記参照)。
propsそれを読み取るアプリのために、メッセージに保存される追加プロパティ。
typeそれを描画するアプリ用のカスタム投稿タイプ(例:custom_poll)。system_で始まるタイプは拒否されます。
root_idスレッドの最初のメッセージのID。そのスレッドに返信するために使用します。
priorityメッセージの優先度(例:{"priority": "urgent"})。
silenttrueの場合、プッシュ通知なしでメッセージを送信します。

Webhook が投稿するすべてのメッセージには、作成者の名前で表示される場合でも、その名前の横に BOT タグが付与され、実際の人間のメッセージと区別できるようにします。Webhook のメッセージは、送信 Webhook をトリガーすることはありません。

名前とアイコン

Webhookは、作成者として投稿されますが、サーバーが上書きを許可している場合は異なります。システムコンソール › 統合機能 › 統合機能管理内の2つの設定(どちらもデフォルトではオフ)を変更することで、この挙動を変えることができます:

  • 統合機能によるユーザー名の上書きを許可する (ServiceSettings.EnablePostUsernameOverride): ユーザー名またはリクエストの username が表示されます。どちらも指定されていない場合、webhook が表示されます。
  • 統合機能によるプロフィール画像アイコンの上書きを許可する(ServiceSettings.EnablePostIconOverride):Webhookのプロフィール画像、またはリクエストのicon_urlまたはicon_emojiが表示されます。

リクエスト内の値は、Webhookに保存された値よりも優先されます。

添付ファイル

添付ファイルは、テキストの下に構造化されたコンテンツを追加します。Slackのメッセージ添付ファイル形式に従います:

{
  "text": "Build failed on `main`",
  "attachments": [{
    "fallback": "main #1902 failed",
    "color": "#d24b4e",
    "author_name": "GitHub Actions",
    "author_icon": "https://chat.example.com/static/ci.png",
    "title": "main #1902 failed",
    "title_link": "https://ci.example.com/runs/1902",
    "text": "Commit `0f4d8e2` by Jonas Weber",
    "fields": [
      {"title": "Branch", "value": "zephyr-3.7", "short": true},
      {"title": "Duration", "value": "3m 40s", "short": true}
    ],
    "footer": "Lumen CI",
    "ts": 1760000000
  }]
}
フィールド意味
fallbackカードを表示できない場所(通知など)向けのプレーンテキスト。
colorカラーバー:16進カラー、またはgood、warning、danger。
pretextカードの上のテキスト。
author_name, author_link, author_icon小さなヘッダー行。
title, title_linkカードのタイトル。リンクであることも可能です。
textMarkdown形式のカード本文。
fields{"title", "value", "short"}のリスト。shortフィールドは横並びで配置されます。
image_url, thumb_url下の大きな画像、または横の小さな画像。
footer, footer_icon, tsフッター行と時間(Unix秒)。
actionsボタンとメニュー:対話型メッセージを参照してください。

カード:ステージとチャート

Antimatterは、デフォルトのインターフェースによって描画される2つのフィールドを添付ファイルに追加します。

  • stages: パイプラインのステップをピル(カプセル状の表示)として最大20個表示します。各項目は{"name", "status"}の形式で、ステータスはpassed、failed、running、pending、skipped、またはcanceledのいずれかです。
  • chart: 最近の値を示す小型の折れ線グラフ、{"values": [2 to 200 numbers], "threshold": number, "label": "…"}。しきい値は破線で描画され、アラートの上限を表します。
{
  "attachments": [{
    "color": "danger",
    "title": "main #1902 failed",
    "stages": [
      {"name": "build", "status": "failed"},
      {"name": "unit", "status": "skipped"},
      {"name": "publish", "status": "skipped"}
    ]
  }, {
    "color": "warning",
    "title": "API latency above 400 ms",
    "chart": {"values": [210, 230, 260, 390, 450, 470], "threshold": 400, "label": "p95 latency, ms"}
  }]
}

クラシックインターフェースや他のクライアントはこれらの2つのフィールドを無視するため、textまたはfieldsにも必須情報を記載してください。

外向きのウェブフックの作成

送信 Webhook は、コミュニティの 公開 チャンネルを監視します。メッセージの最初の単語がトリガーワードと一致した場合、または誰かがメッセージのメニューでそれを選択した(メッセージ操作)場合、メッセージをあなたの URL に送信します。

  1. 統合機能で外向きのウェブフックを選択し、外向きのウェブフックを追加するをクリックします。
  2. タイトルと説明を入力します。
  3. リクエストのコンテントタイプを選択します: application/x-www-form-urlencodedまたはapplication/json。
  4. チャンネルを選択し、トリガーワード(1つにつき1行)を入力するか、両方指定します。チャンネルのみ指定しトリガーワードがない場合、そのチャンネルのすべてのメッセージが送信されます。両方指定した場合、メッセージは両方の条件に一致する必要があります。
  5. トリガーとなる条件 で、最初の単語がトリガーワードと正確に一致する、最初の単語がトリガーワードで始まる、または メッセージメニューから を選択します。メッセージメニューから を選択すると、トリガーワードは非表示になり、チャンネル は任意(指定しない場合、コミュニティのすべての公開チャンネルで操作が提供されます)、タイトル は必須になります:これはメニューでの操作の名前です。
  6. コールバックURL(1つにつき1行)を入力します。各URLには、条件に一致したすべてのメッセージが送信されます。
  7. 返信に使用される ユーザー名 と プロフィール画像 を任意で設定します。メッセージメニューからの操作の場合、アイコン フィールドが プロフィール画像 に置き換わります:.png または .jpg 画像の URL、または Antimatter のデフォルトインターフェースではアップロードされた画像。メニューでは灰色で表示されます。指定しない場合、操作にはニュートラルなアイコンが付与されます。
  8. 保存するを選択し、表示されたトークンをコピーします。サービスはこのトークンを使用して、リクエストが自分のサーバーからのものであることを確認します。

API を使用する場合: POST /api/v4/hooks/outgoing に {"team_id", "channel_id", "trigger_words", "trigger_when", "callback_urls", "content_type", "display_name"} を送信します (trigger_when: 完全一致は 0、"先頭一致"は 1、"メッセージメニューから"は 2)。 trigger_when が 2 の Webhook はトリガーワードを必要とせず、display_name が必要です。アイコンは POST /api/v4/hooks/outgoing/{hook_id}/icon にアップロードします (multipart、フィールド image: PNG、JPEG または GIF、128 px の PNG として保存)。その後、その icon_url は GET /api/v4/hooks/outgoing/{hook_id}/icon を指します。

サービスがプライベートネットワーク上にある場合、システム管理者が信頼されていない内部接続を許可する(ServiceSettings.AllowedUntrustedInternalConnections)にそのアドレスを許可する必要があります。それ以外の場合、サーバーはプライベートアドレスを呼び出しません。

外向きのリクエスト

Antimatterは、コンテントタイプに応じてJSONまたはフォームエンコードで、これらのフィールドを含むPOSTリクエストを送信します:

{
  "token": "6kd1ofo5ojr5zgu5ipfipybgnc",
  "team_id": "…",
  "team_domain": "lumen-labs",
  "channel_id": "…",
  "channel_name": "ops-alerts",
  "timestamp": 1760010000000,
  "user_id": "…",
  "user_name": "priya",
  "post_id": "…",
  "text": "deploy api 2.4.0",
  "trigger_word": "deploy",
  "file_ids": ""
}

処理を行う前に、token を Webhook のトークンと比較してください。フォームエンコード形式では、timestamp はミリ秒ではなく秒単位です。サーバーは、統合機能リクエストタイムアウト(デフォルトは 30 秒、ServiceSettings.OutgoingIntegrationRequestsTimeout)が許可する間、応答を待機します。

アウトゴーイング Webhook への応答

返信を投稿するには、JSON で応答します。何も投稿しない場合は、空のボディで応答します。

{
  "text": "Deploying **api 2.4.0** to staging…",
  "response_type": "comment",
  "username": "deploy-bot",
  "icon_url": "https://chat.example.com/static/deploy.png"
}
  • text および attachments:返信の内容です。どちらもない場合、何も投稿されません。
  • response_type:comment を指定すると、トリガーメッセージのスレッドに返信が投稿されます。それ以外の場合は、チャンネルに投稿されます。
  • username、icon_url:サーバーが上書きを許可している場合に使用されます。許可されていない場合は、Webhook 自体の値が使用されます。
  • props、type、priority:インゴーイング Webhook と同じです。

返信は、Webhook の作成者として投稿され、上書き名がある場合はその名前で表示されます。簡潔な応答を超える長文の場合は、即座に応答し、インゴーイング Webhook または API を使用して後から投稿してください。

メッセージアクション

メッセージアクションは、トリガーとなる条件 が メッセージメニューから に設定されたアウトゴーイング Webhook です。投稿されたメッセージに対して発火することはありません。代わりに、ユーザーはメッセージのメニュー: メッセージアクション (⋯) › その他のアクション の 統合機能 セクションの下に、そのアイコン付きで表示されます。クラシックなインターフェースではメッセージアクションは表示されません。選択すると、その 1 つのメッセージがコールバック URL に送信され、短い通知としてアクションの名前が 送信先 として表示されますか、または ephemeral_text が表示されます。

  • 表示場所: Webhook が紐付けられたチャンネル内、またはチャンネルが紐付けられていない場合は、そのコミュニティのすべての公開チャンネル内。メッセージアクションは公開チャンネルでのみ利用可能です。
  • ゲスト は、自分が参加しているチャンネルに紐付けられたアクションのみを取得でき、コミュニティ全体のアクションは取得できません。
  • アーカイブ済みおよび読み取り専用チャンネル: メッセージは依然として送信できます。チャンネルをアーカイブすると、それに紐付けられた Webhook が削除されるため、アーカイブ済みチャンネルにはコミュニティ全体のアクションのみが保持されます。ユーザーがそこに投稿できなかった回答は、そのユーザー本人のみに表示されます。
  • レート制限: 各ユーザーは、5 件のバースト後、1 分間に 10 件のメッセージアクションを実行できます。これを超えると、サーバーは 429 で応答します。
  • プライベートネットワーク: 他のアウトゴーイング Webhook と同様に、内部アドレスは 信頼されていない内部接続を許可する に許可する必要があります。

リクエスト

ペイロードは、Webhook のコンテンツタイプに従って JSON またはフォームエンコードで送信されます:

{
  "token": "6kd1ofo5ojr5zgu5ipfipybgnc",
  "trigger": "message_action",
  "team_id": "…",
  "team_domain": "lumen-labs",
  "channel_id": "…",
  "channel_name": "ops-alerts",
  "timestamp": 1760010000000,
  "user_id": "…",
  "user_name": "priya",
  "post_id": "…",
  "post_root_id": "",
  "post_create_at": 1760009000000,
  "post_user_id": "…",
  "post_user_name": "jonas",
  "permalink": "https://chat.example.com/lumen-labs/pl/…",
  "text": "The staging database is full again",
  "files": [{"id": "…", "name": "df.txt", "link": "https://chat.example.com/api/v4/files/…"}],
  "priority": "",
  "requested_ack": false,
  "burn_on_read": false
}
  • user_id と user_name はアクションを選択したユーザー、post_user_id と post_user_name はメッセージの作成者です。
  • 送信されるのはそのメッセージのみで、スレッドの残りのメッセージは送信されません。
  • files は、アクションを選択したユーザーがファイルをダウンロードできる場合のみ、そのメッセージのファイルを列挙します。link のダウンロードには、API の他のファイルと同様にセッションまたはトークンが必要です。
  • burn-on-readメッセージは、テキストやファイルなしで送信され、burn_on_readがtrueに設定されます。
  • フォームエンコードの場合、ファイルはfile_id、file_name、file_linkフィールドとして、同じ順序で繰り返し送信されます。

応答

アウトゴーイングWebhookへの応答と同様です(アウトゴーイングWebhookへの応答を参照):textまたはattachmentsを指定するとチャンネルに返信が投稿され、"response_type": "comment"を指定するとそのメッセージのスレッドに投稿されます。また、ephemeral_text(300文字に切り詰められます)で応答することもできます。これにより、アクションを選択した本人のみが通知内でそれを見ることができます。空のボディを返すと何も投稿されません。

{"ephemeral_text": "Ticket OPS-412 created"}

APIによる方法

  • GET /api/v4/channels/{channel_id}/message_actions:チャンネル内で選択可能なアクションを、id、display_name、description、icon_urlとともに返します。トークンやコールバックURLは返されません。
  • POST /api/v4/posts/{post_id}/message_actions/{hook_id}:読み取り可能なメッセージに対してアクションを実行します。応答として{"ephemeral_text"}を返します。

Webhook が動作しない場合

  • フック URL から 501 が返された場合:サーバーでインゴーイング Webhook が無効になっています。
  • 400 "Failed to decode the payload…":JSON が無効であるか、フォームフィールドの名前が payload ではありません。"No text specified." は、リクエストに text も attachments も含まれていないことを意味します。
  • 403:Webhook が別のチャンネルにロックされているか、その所有者がもはやそのチャンネルを読み取れなくなっています。
  • アウトゴーイングWebhookがトリガーされない場合:チャンネルが非公開である、トリガーが最初の単語ではない、メッセージがWebhookからのものである、またはWebhookがメッセージメニューからトリガーされるよう設定されている場合。
  • メッセージアクションがメニューに表示されない場合:チャンネルが非公開である、アクションが別のチャンネルに紐付けられている、ユーザーがゲストでありアクションにチャンネルが紐付けられていない、またはアウトゴーイングWebhookが無効化されている場合。
  • メッセージアクション実行時の404:アクションが存在しない、またはそのユーザーに対してそのメッセージのチャンネルをカバーしていない場合。429:ユーザーが1分間に10回以上のアクションを実行した場合。502:どのコールバックURLにも到達できなかった場合(ログに理由が記録されます)。
  • ログ:ウェブフックのデバッグを有効にする(LogSettings.EnableWebhookDebugging)をオンにし、ログレベルを DEBUG に設定すると、サーバーは失敗したインゴーイングリクエストのペイロードをログに記録します。失敗したアウトゴーイング呼び出しは Outgoing Webhook POST failed としてログに記録されます。