- Home
- リファレンス
- Webhook を利用する
- Webhook でイベントを通知する
Webhook でイベントを通知する
ハンドオーバーなどのイベントを外部システムへ通知する Webhook の設定方法を説明します。
担当者の対応が必要になったことを、外部システムへ Webhook で通知できます。Webhook は、選択中のボットごとに設定します。
Webhook を設定する
-
管理コンソールにログイン して、管理コンソールで操作するボットを切り替える の手順で、設定するボットを選択します。
-
選択中のボットカードの [
]
→
[Webhook 設定]
を順にクリックします。Webhook 設定画面が表示されます。
-
以下の項目を設定します。
項目 説明 [Webhook を有効にする] チェックを入れると、選択したイベントが発生したときに Webhook を送信します。 [シークレット] Webhook の署名に使用する値です。 [コピー] をクリックすると、シークレットをコピーできます。新しい値へ変更する場合は [生成] をクリックします。変更した場合は、Webhook を受信する外部システムにも新しい値を設定してください。 [通知するイベント] 通知するイベントを選択します。
- [ハンドオーバーリクエスト] : エンドユーザーが担当者への対応を依頼したときに発生します。
- [返信待ち] : 担当者が公開コメントを送信したあとに、エンドユーザーから新しいメッセージが届いたときに発生します。
[送信先 URL] https://から始まる外部システムの URL を入力します。明示的にポートを指定する場合は、443 だけを利用できます。 -
[保存] をクリックします。
Webhook で送信される内容
選択したイベントが発生すると、 [送信先 URL] へ HTTPS の POST リクエストが送信されます。リクエストボディは JSON 形式です。以下は、送信される JSON の例です。
{
"id": "123e4567-e89b-12d3-a456-426614174000",
"eventName": "AWAITING_HUMAN_REPLY",
"timestamp": "2026-08-25T03:00:17.232Z",
"data": {
"conversationId": "cv-example",
"url": "https://example.wisora.example/ui/chat-logs/cv-example",
"botId": "Additional-8f3c2a71",
"botName": "サンプルボット"
}
}
各プロパティの意味は以下のとおりです。
| プロパティ | 説明 |
|---|---|
id | イベントを識別する ID です。 |
eventName | イベントの種類です。
|
timestamp | イベントが発生した日時です。ISO 8601 形式の UTC で送信されます。 |
data | イベントの詳細です。 |
data.conversationId | イベントが発生したチャットの会話 ID です。 |
data.url | イベントが発生した会話を表示するチャットログ画面の URL です。 |
data.botId | イベントが発生したボットの ID です。含まれない場合があります。 |
data.botName | イベントが発生したボットの名前です。含まれない場合があります。 |
data.externalUserId | 外部認証でチャットしたエンドユーザーの ID です。外部認証を利用していない場合は含まれません。 |
同じ id のイベントが複数回送信される場合があります。外部システムでは、処理済みの id を記録し、同じイベントを重複して処理しないようにしてください。
署名を検証する
Wisora は、
[シークレット]
を鍵として、リクエストボディから HMAC-SHA256 の署名を計算します。計算した署名を Base64 形式に変換し、x-wisora-signature ヘッダーに設定します。
-
JSON として解析する前のリクエストボディを、UTF-8 のバイト列として取得します。
-
[シークレット] の UTF-8 バイト列を鍵にして、リクエストボディの HMAC-SHA256 を計算します。
-
計算結果を Base64 形式へ変換します。
-
変換した値と
x-wisora-signatureヘッダーの値を、処理時間が値に左右されない方法で比較します。 -
値が一致した場合だけ、リクエストボディを処理します。
リクエストボディを変更しないでください
署名を検証するときは、受信したリクエストボディを整形したり、JSON として解析した内容を再生成したりせず、受信したバイト列をそのまま使用してください。空白、改行、プロパティの順序が変わると署名は一致しません。JSON として解析するのは、署名を検証したあとにしてください。
Node.js で署名を検証する
Node.js では、標準モジュールの node:crypto を使って署名を検証できます。
-
以下のコードを
webhook-verification.jsとして保存します。
webhook-verification.js をダウンロードimport { createHmac, timingSafeEqual } from "node:crypto"; import { readFile } from "node:fs/promises"; import { pathToFileURL } from "node:url"; export function createWisoraSignature(rawBody, secret) { if (!Buffer.isBuffer(rawBody) || typeof secret !== "string") { return null; } return createHmac("sha256", Buffer.from(secret, "utf8")) .update(rawBody) .digest("base64"); } export function verifyWisoraSignature(rawBody, signature, secret) { const expectedSignature = createWisoraSignature(rawBody, secret); if (expectedSignature === null || typeof signature !== "string") { return false; } const expectedSignatureBytes = Buffer.from(expectedSignature, "base64"); let actualSignature; try { actualSignature = Buffer.from(signature, "base64"); } catch { return false; } return ( actualSignature.length === expectedSignatureBytes.length && timingSafeEqual(actualSignature, expectedSignatureBytes) ); } async function main() { const [bodyPath] = process.argv.slice(2); const signature = process.env.WISORA_WEBHOOK_SIGNATURE; const secret = process.env.WISORA_WEBHOOK_SECRET; if (!bodyPath || !secret) { console.error( "WISORA_WEBHOOK_SECRET を設定し、JSON ファイルを指定してください。", ); process.exitCode = 2; return; } const rawBody = await readFile(bodyPath); if (!signature) { console.log(createWisoraSignature(rawBody, secret)); return; } const verified = verifyWisoraSignature(rawBody, signature, secret); if (!verified) { console.error("署名が一致しません。"); process.exitCode = 1; return; } console.log("署名が一致しました。"); } if ( process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href ) { await main(); } -
以下のリクエストボディを、末尾に改行を付けずに
webhook-body.jsonとして保存します。「Webhook で送信される内容」の JSON は読みやすいように整形しています。この例では、同じ内容を 1 行にしたリクエストボディを使用します。
webhook-body.json をダウンロード{"id":"123e4567-e89b-12d3-a456-426614174000","eventName":"AWAITING_HUMAN_REPLY","timestamp":"2026-08-25T03:00:17.232Z","data":{"conversationId":"cv-example","url":"https://example.wisora.example/ui/chat-logs/cv-example","botId":"Additional-8f3c2a71","botName":"サンプルボット"}} -
説明用のシークレットを指定して、署名を生成します。
WISORA_WEBHOOK_SECRET='00000000-0000-4000-8000-000000000000' \ node webhook-verification.js webhook-body.json署名が生成されます。
Ac23s8CC0vUCk7oBL1qLXwFh3LTZPPu116XknBwti2s=この署名と、
x-wisora-signatureヘッダーの値を比較してください。一致した場合は、Webhook が Wisora から送信されたことを表します。
署名が一致しないリクエストは処理しないでください。
Wisora