カスタムチャネル

Webhookで外部テキストチャネルをElevenLabsエージェントに接続します

概要

Custom Channelは、外部メッセージングシステムをElevenLabsエージェントに接続します。ユーザーメッセージをElevenLabsのWebhookに送信し、エージェントの返信を独自のHTTPSエンドポイントで受信できます。

Custom Channelはアルファ版です。
Custom Channelは、ゼロ保持モードを使用するエージェントまたはワークスペースでは利用できません。

機能

機能サポート
ゼロ保持モード(ZRM)非対応 — ZRMワークスペースおよびZRMエージェントでは利用できません
メッセージ内の添付ファイル非対応 — メッセージはテキストのみです

セットアップ

1

Custom Channelを開く

エージェントを開き、Channelsを選択してCustom Channelを選び、Add triggerをクリックします。

2

トリガーを設定する

既存の接続を選択するか新規作成し、Reply Webhook URLを入力します。

3

認証情報をコピーする

Addをクリックし、Inbound Webhook URL、Inbound Secret、Outbound Signing Secretをコピーします。

4

サービスを設定する

X-Webhook-Secretにインバウンドシークレットを指定して、インバウンドWebhook URLへユーザーメッセージを送信します。アウトバウンド署名シークレットを使用して、各返信を検証します。

メッセージを送信する

生成されたWebhook URLにPOSTリクエストを送信します。

POST /v1/convai/api-integrations/custom_channel/triggers/{trigger_connection_id}/async_message
X-Webhook-Secret: <inbound-secret>
Content-Type: application/json
{
"data": {
"type": "user_message",
"text": "Where is my order?",
"user_identifier": "customer_8427"
},
"user_message_id": "msg_01k1e6z3f4t8n9c2",
"dynamic_variables": {
"order_id": "order_72491"
}
}
フィールド必須説明
data.typeはいuser_messageである必要があります。
data.textはい空でないユーザーメッセージ。
data.user_identifierいいえ外部ユーザーの識別子。
user_message_idはいシステムから指定する、空でない冪等性キー。
conversation_idいいえ会話を継続するには返されたIDを含めます。新しい会話を開始する場合は省略します。
dynamic_variablesいいえこのターンでエージェントに渡す動的変数。

ElevenLabsは、ターンを処理する前に202 Acceptedを返します。

{
"conversation_id": "conv_01k1e72d4x8p6v3m",
"status": "queued"
}

会話を継続するには、そのconversation_idと新しいuser_message_idを指定して別のリクエストを送信します。

返信を受信する

ElevenLabsは各ターンの後、返信Webhook URLにPOSTリクエストを送信します。

{
"version": "1",
"conversation_id": "conv_01k1e72d4x8p6v3m",
"user_message_ids": ["msg_01k1e6z3f4t8n9c2"],
"status": "completed",
"data": [
{
"type": "agent_response",
"event": {
"agent_response": "Your order is scheduled to arrive tomorrow.",
"response_id": "9f2c1a7e-4b3d-4e8a-9c1f-2d6b8e0a5f31",
"event_id": 4
}
},
{
"type": "agent_tool_response",
"event": {
"tool_name": "end_call",
"tool_call_id": "toolu_01k1e70r4b8y",
"tool_type": "system",
"event_id": 4,
"is_called": true,
"is_error": false,
"is_blocked": false,
"status": "success"
}
}
],
"error": null
}

処理に失敗した場合、statusはfailed、dataは[]となり、errorに説明が含まれます。

dataにはターン順にイベントが並びます。各項目にはtypeとeventがあります。

  • agent_responseには1つのエージェント発話が含まれます。response_idは発話を一意に識別し、event_idは発話をターンに関連付けます。チャンネルでターンごとに1つのテキストバブルを表示する場合は、agent_responseの値を連結してください。
  • agent_tool_responseはツールの結果を報告し、ターンのevent_idを共有します。statusはsuccess、error、blocked、またはskippedです。tool_type: "system"、tool_name: "end_call"、status: "success"のレスポンスは、エージェントが会話を終了したことを示します。

複数のインバウンドメッセージが1つのターンにまとめられる場合があります。user_message_idsには、この返信が応答するユーザーメッセージIDの一覧が含まれます。

返信署名を検証する

各返信にはElevenLabs-Signatureヘッダーが含まれます。

t=1753876800,v0=<hex-digest>

ダイジェストは、アウトバウンド署名シークレットを使用して{timestamp}.{raw_request_body}に対して生成されるHMAC-SHA256署名です。JSONを解析する前に生の本文を検証し、古いタイムスタンプは拒否してください。

import hashlib
import hmac
import time
def verify_signature(raw_body: bytes, header: str, secret: str) -> None:
values = dict(part.split("=", 1) for part in header.split(","))
timestamp = values["t"]
if abs(time.time() - int(timestamp)) > 30 * 60:
raise ValueError("Stale webhook signature")
expected = hmac.new(
secret.encode(),
timestamp.encode() + b"." + raw_body,
hashlib.sha256,
).hexdigest()
if not hmac.compare_digest(expected, values["v0"]):
raise ValueError("Invalid webhook signature")

配信動作

ElevenLabsは、約0秒、0.5秒、2秒後にプロセス内で3回配信を試みます。2xxレスポンスを受け取ると、配信成功と見なされます。

リクエスト本文は256KiBに制限されています。