フォーム送信からAI即架電を始める場合、Webhookを受けた処理の中で、そのまま電話をかけない方が良いです。まず送信イベントを一件として保存します。重複や入力不備を判定した後、架電待ちの処理へ渡してください。

この間に数秒の処理が加わっても、二重発信や取りこぼしを防げる方が重要です。即時性は「フォーム受付から架電開始までの所要時間」として測り、Webhookへ早く応答することとは分けて考えます。

一件の送信を識別できる受付IDを作る

最初に必要なのは、電話番号ではなく送信イベントを識別するIDです。同じ人が同じ日に二つの資料を請求する場合もあります。反対に、一回の送信が通信上の理由で再送されることもあります。

フォーム側で一意の受付IDを発行できるなら、その値を連携先まで引き継ぎます。発行できない場合は、Webhookを最初に受けたシステムでIDを作り、受信した内容と一緒に保存します。再送時にも同じ値を渡せることが条件です。

GitHubのWebhook運用ガイドでは、配信ごとのIDを使って一意性を確認する方法が案内されています。再配信しても同じIDが使われます。これはGitHub固有の仕様ですが、送信元の再試行を新しい業務依頼として扱わない設計は、フォーム連携でも応用できます。

架電判断に必要な項目だけを受け取る

フォームの全項目をそのまま電話システムへ渡す必要はありません。架電を始める判断と、電話の冒頭で必要になる情報を先に決めます。

項目使い道欠けた場合の扱い
受付ID同じ送信の再処理を防ぐ架電せず要確認へ送る
フォーム・用件会話内容と重複判定を分ける共通シナリオへ流さず要確認にする
電話番号発信先を特定する架電対象外にする
受付日時発信可能時間と処理期限を判定するサーバー受信日時を補助的に残す
表示した案内の版送信時に何を案内したか確認する現行版と同一と決め付けない
氏名または呼称電話冒頭の取り違えを防ぐ呼称なしで成立する会話へ切り替える

電話番号は保存前に表記を統一します。ハイフンや空白を除くだけでなく、国番号を含む形式へ変換した結果も分けて残すと、元の入力を確認できます。番号の形式が正しくても本人の番号とは限らないため、形式確認と本人確認は同じ処理にしません。

必須項目が足りないときは、空欄のまま架電サービスへ送らないでください。自動補完できる値と、人が確認しなければならない値を分けます。後者は少数の要確認一覧へ送ります。

Webhookの受信と架電処理を分ける

Webhookの役割は、送信元からイベントを確実に受け取るところまでです。架電の可否判定や外部APIへの指示まで同じ通信内で終えようとすると、処理時間が長くなります。送信元は失敗と判断し、同じ内容を再送する場合があります。

GitHubはWebhook受信後10秒以内に2xxを返し、時間がかかる処理はキューで非同期に行う方法を案内しています。StripeのWebhookガイドも、複雑な処理より先に成功応答を返すよう求めています。各サービスの制限時間をそのままAI即架電へ当てはめるのではなく、「受信を確定する処理」と「電話を始める処理」を分ける根拠として使います。

実際の流れは次の順にします。

  1. 送信元とイベント種別を確認する
  2. 受付IDと受信内容を保存する
  3. 保存できた時点で受信成功を返す
  4. 別の処理で必須項目と重複、停止、時間帯を判定する
  5. 条件を満たした一件だけを架電待ちへ送る
  6. 架電サービスの受付IDや通話IDを元の受付へ戻す

署名を提供する送信元では、署名検証も受信処理に含めます。TwilioのWebhookセキュリティガイドでは、受信したリクエストがTwilioから送られたことを署名で検証するよう案内しています。連携元が別製品の場合は、その製品が用意する検証方法を使ってください。

通信の再送と利用者の再送信を分ける

受付IDが同じイベントは、通信上の再送です。すでに保存済みなら、同じ状態を返し、新しい架電待ちは作りません。AWS Lambdaのベストプラクティスでも、重複イベントを同じ結果として扱えるよう、処理を冪等にすることが推奨されています。

受付IDが異なっても、同じ利用者が送信ボタンを二回押した可能性があります。業務上の重複は、電話番号だけで判定できません。用件とフォーム、送信間隔も使います。同じ電話番号でも、資料請求と予約変更は別の連絡だからです。

重複と判定した二件目は、消さずに元の受付IDとの関係を残します。あとから「送信は二件あるのに、電話が一回しかない」理由を確認できるためです。再発信の回数や間隔は、別記事のAI即架電の再試行ルールで扱います。

架電前の状態を細かく分けすぎない

連携状態は、担当者が次の処理を判断できる粒度で十分です。処理内部の細かな工程まで管理画面へ出すと、何を直せばよいのか分かりにくくなります。

状態意味次に行うこと
受付済みイベントを保存した必須項目と発信条件を判定する
保留時間外などで今は発信しない発信可能時刻に再判定する
架電待ち条件を満たし、まだ指示していない一回だけ架電APIへ送る
架電確認中指示したが開始結果が未確定同じ受付IDで結果を照会する
開始済み架電サービスの通話IDを保存した通話結果の受信を待つ
要確認入力不備や結果不明がある担当者が内容を確認する
除外停止希望や対象外条件に該当した自動処理を終了する

時間外のイベントをエラーにすると、送信元が再送し続ける場合があります。受付自体は成功させ、発信条件だけを保留にします。停止希望や対象外条件も同様に、連携失敗ではなく「架電しないと判断した受付」として残します。

タイムアウト後は新しい架電を作らない

最も注意したいのは、架電APIへ指示した直後に通信が切れた場合です。応答がないからといって、架電されていないとは限りません。相手の電話は鳴っているのに、呼び出し側だけが結果を受け取れていない可能性があります。

架電指示には、元の受付IDから作った重複防止キーを付けます。サービス側が同じキーの再送を一件として扱えるか、事前に確認してください。対応していない場合は、指示前後の状態とサービス側の通話IDを照合できる方法を決めます。

タイムアウトした受付は「失敗」ではなく「架電確認中」に置きます。管理画面や照会APIで開始有無を確認できるまでは、新しい架電を作りません。結果を確認できないまま即時性の期限を過ぎた場合は、自動再送ではなく担当者確認へ切り替えます。

本番前に八つの経路を通す

一回の正常送信だけでは、重複防止が機能するか確認できません。テスト用の電話番号を使い、受付IDと状態の変化を照合します。

  1. 一回のフォーム送信から一回だけ架電が始まる
  2. 同じ受付IDを再送しても新しい架電が作られない
  3. 異なる受付IDで同じ内容を連続送信した場合に業務上の重複として止まる
  4. 電話番号が空欄または不正な形式なら架電されない
  5. 発信可能時間外の受付が保留される
  6. 停止対象の電話番号が除外される
  7. 架電APIの応答が途切れても二回目を作らず開始有無を確認できる
  8. 架電開始後の通話IDと結果が元の受付IDへ戻る

テストでは通話履歴だけを見ません。フォームの受付記録と連携キューも確認し、架電サービスの記録と照合してください。どこまで進み、どこで止まったかが同じ受付IDで追えれば、連携失敗を利用者任せにせず復旧できます。

最初に、現在のフォームから一件分の項目を書き出します。その横に「架電判断に使う」「会話で使う」「連携先へ渡さない」のいずれかを付けてください。受付IDと重複判定、タイムアウト時の照会方法まで決まったら、AI即架電サービス比較表で必要なAPI・Webhook連携を確認すると進めやすくなります。