インバウンドウェブフック
動的なエージェントルーティング — インバウンド通話が着信するとFinnが御社のサーバーを呼び出します。
インバウンド Webhook
インバウンドコールの着信時、Finn は自社サーバーにリアルタイムで問い合わせて、応答するエージェント、注入する変数、読み込むナレッジベースを決定できます。これにより、発信者番号、アカウントの階層、時間帯、A/B コホートなど、バックエンド側の任意のロジックで動的にルーティングできます。
固定のエージェントで十分な場合は、このページは不要です。通話ごとの動的なルーティングが必要な場合に参照してください。
仕組み
caller dials → Finn answers ring → Finn POSTs to your URL → your server returns agent + vars → Finn streams the voice agent
このハンドシェイクにより約 100〜200ms のレイテンシが追加されます。エンドポイントは500ms 以内に応答する必要があり、超過した場合 Finn は既定のエージェントにフォールバックします。
設定
1. インバウンド Webhook の URL を設定する
ダッシュボード → 設定 → 電話番号 → [番号] → インバウンド Webhook URL。
HTTPS エンドポイントを貼り付けて保存します。Finn は到達性を確認するため、{"ping": true} ボディで一度だけ ping を送信します。
API で設定する
curl https://api.hirefinn.ai/v1/phone-numbers/ph_1234 \
-X PATCH \
-H "Authorization: Bearer $FINN_API_KEY" \
-d '{ "inbound_webhook_url": "https://your-app.com/finn/inbound" }'
2. フォールバック用エージェントを設定する
その番号の既定の Finn を設定します。Webhook がタイムアウトした場合、エラーを返した場合、または無効な応答を返した場合に使用されます。
リクエストのペイロード
Finn は次の内容を指定の URL に POST します。
{
"session_id": "ws_2H4abc",
"request_type": "inbound",
"phone_number_id": "ph_1234",
"channel": "pstn",
"from": {
"phone": "+919876543210",
"country": "IN",
"carrier": "Airtel"
},
"to": {
"phone": "+918765432100",
"country": "IN"
},
"received_at": "2026-05-22T14:30:00Z",
"metadata": {}
}
WhatsApp の通話では、from ブロックに WhatsApp 固有のフィールドが使用されます。
"from": {
"wa_id": "919876543210",
"display_name": "Priya M",
"profile_pic_url": "https://..."
},
"channel": "whatsapp"
レスポンス
通話のルーティング方法を示す JSON ボディを 500ms 以内に返します。
{
"finn_id": "fn_def456",
"language": "hi-IN",
"variables": {
"customer_name": "Priya M",
"account_tier": "premium",
"last_order_id": "ord_99831",
"preferred_agent": "Aria"
},
"knowledge_base_ids": ["kb_general", "kb_premium_perks"],
"metadata": {
"campaign_tag": "premium-support-q2",
"ab_cohort": "B"
},
"recording_enabled": true,
"max_call_duration_seconds": 600
}
フィールドリファレンス
| フィールド | 必須 | 備考 |
|---|---|---|
finn_id | はい | 応答するエージェント。自組織に属している必要があります。 |
language | いいえ | エージェントの既定の言語を上書きします。en-US、hi-IN、es-ES など。 |
variables | いいえ | 自由形式のキー/値の集合。プロンプト内で {variable_name} として利用できます。 |
knowledge_base_ids | いいえ | この通話で読み込むナレッジベースを上書きします。 |
metadata | いいえ | 通話レコードと通話後 Webhook に付加されます。独自の分析用タグ付けに使用します。 |
recording_enabled | いいえ | エージェントのデフォルトを上書きします。 |
max_call_duration_seconds | いいえ | 上限値。デフォルトは 1800(30 分)。 |
着信を拒否
{ "action": "reject", "reason": "blocked_caller" }
Finn は設定した音声メッセージ(「この番号は現在使われていません」)を再生して通話を終了します。DNC の遵守、ブロック済みアカウント、営業時間外の切断に使用します。
即時に転送
{ "action": "transfer", "to": "+918888888888", "reason": "vip_route" }
AI エージェントを介さず、直接オペレーターに転送します。VIP/エスカレーション対応に便利です。
実装例(Node)
import express from "express";
const app = express();
app.use(express.json());
app.post("/finn/inbound", async (req, res) => {
const { from, to, channel } = req.body;
// 1. Look up caller in CRM (must be fast — DB index by phone)
const phone = from.phone ?? `+${from.wa_id}`;
const customer = await crm.findByPhone(phone);
// 2. Block known DNC
if (customer?.dnc) {
return res.json({ action: "reject", reason: "dnc" });
}
// 3. VIP → straight to human
if (customer?.tier === "vip") {
return res.json({
action: "transfer",
to: process.env.VIP_DESK_NUMBER!,
reason: "vip_route",
});
}
// 4. Localized agent based on caller country
const language = from.country === "IN" ? "hi-IN" : "en-US";
// 5. Pick agent + load context
return res.json({
finn_id: customer?.tier === "premium"
? "fn_premium_aria"
: "fn_standard_aria",
language,
variables: {
customer_name: customer?.name ?? "there",
account_tier: customer?.tier ?? "standard",
last_order_id: customer?.last_order_id ?? "",
},
knowledge_base_ids:
customer?.tier === "premium" ? ["kb_general", "kb_premium"] : ["kb_general"],
metadata: { ab_cohort: customer?.ab_cohort ?? "A" },
});
});
app.listen(3000);
署名の検証
通話後 Webhook と同じ方式です。生のボディに対する HMAC-SHA256 で、ヘッダーは X-Finn-Signature です。
const sig = req.headers["x-finn-signature"] as string;
const ok = verifyFinnSignature(rawBody, sig, process.env.FINN_INBOUND_SECRET!);
if (!ok) return res.status(401).send("bad signature");
検証処理の完全な実装は 通話後 Webhook を参照してください。
パフォーマンス要件
これはホットパス上の処理です。応答を待つ間、発信者には呼び出し音が流れています。
| 指標 | 目標値 |
|---|---|
| 応答時間 | 500ms 未満(p99) |
| タイムアウト | 1000ms |
| タイムアウト時のフォールバック | 電話番号に設定されたデフォルトエージェント |
| 5xx 時のフォールバック | デフォルトエージェント |
| 不正な JSON 時のフォールバック | デフォルトエージェント+エラーをログに記録 |
500ms 未満を達成するためのヒント
- 電話番号ごとに CRM の照会結果をキャッシュする(5 分間)
- データベースを同一リージョンに配置する — Webhook が us-east、DB が us-west では片道 80ms かかります
- ルーティングの判定を事前計算する — 顧客レコードに結果を保存し、リアルタイムで判定しない
- 受信時のホップでは必須でないエンリッチメントを省く — その処理は通話後 Webhook に回します
発信者の事前スクリーニング
多くのアプリでは、着信 Webhook を次のいずれかのパターンで利用しています。
| パターン | ユースケース |
|---|---|
| 検索とパーソナライズ | 顧客レコードを取得し、名前とティアを変数として渡す |
| DNC の適用 | ブロック済み番号からの着信を拒否 |
| VIP ルーティング | エージェントを介さず、担当者に直接転送 |
| 言語判定 | インドの発信者には hi-IN、米国の発信者には en-US を選択 |
| A/B テスト | 通話の 50% を新しいエージェントバージョンにルーティング |
| 営業時間外のルーティング | 営業時間外は別のエージェント(または留守番電話)に振り分け |
| キャンペーントラッキング | 特定のトラッキング番号からの通話にキャンペーン ID を付与 |
| マルチテナント SaaS | 発信先の番号に対応するテナントへルーティング |
テスト
Finn CLI を使えば、実際の PSTN 着信なしでインバウンド通話をシミュレートできます:
finn inbound simulate \
--phone-number-id ph_1234 \
--from +919876543210 \
--webhook-url https://your-app.com/finn/inbound
出力にはエンドポイントの応答、レイテンシ、解決されたエージェントと変数が表示されます。CI にも組み込めます。
よくある落とし穴
| 症状 | 対処 |
|---|---|
| 常にデフォルトのエージェントにフォールバックする | エンドポイントの応答が 500ms を超えています。Finn の webhook ログでタイミングを確認してください。 |
| エージェントが話し出す前に発信者に 2〜3 秒の無音が聞こえる | エンドポイントは遅いものの、タイムアウト以内です。200ms 未満に最適化してください。 |
| 変数がエージェントの発話に反映されない | プロンプトのプレースホルダー {customer_name} と webhook のキー customerName が一致していません。両方で snake_case を使用してください。 |
| 意図しないエージェントが応答した | エンドポイントが別の組織に属する finn_id を返しています。所有権を確認してください。 |
action: reject が反映されない | reason が文字列であること、レスポンスの JSON が有効であることを確認してください。無効なレスポンスはフォールバックになります。 |
関連項目
Was this page helpful?
Still stuck or have feedback?
Email [email protected] or use the chat bubble in the bottom-right corner — it's a Finn that knows the Academy cold.