WhatsApp 音声通話が鳴らない?preparing から接続までのトラブルシューティング
WhatsApp 音声通話の作成が 201 を返しても相手の電話が鳴らない場合は、最後に確認できた段階を特定しましょう。state: preparing はブラウザー用の通話リンクが準備できたことを示すだけで、発信が始まったことを意味しません。作成リクエストを繰り返すと、最初の試行を追跡しにくくなる場合があります。
本記事は、UnifyPort が非公式インターフェースを通じてプライベートベータで提供する、人が開始する1対1の音声発信を対象としています。Meta WhatsApp Business Calling API のガイドではありません。初期設定と完全なリクエスト例は音声通話の導入チュートリアルを参照してください。ここでは、アプリに残っている証拠から問題の箇所を絞り込みます。
1. 証拠から何が確認できるかを整理する
| 証拠 | 確認できること | 確認できないこと |
|---|---|---|
作成が 201 と preparing を返す | 通話リンクの準備が完了した | 発信、呼び出し、接続が行われた |
現在の通話の照会が active を返す | 管理対象の通話が接続済みで、通話中である | Webhook がアプリに届いた |
call.answered を受信する | 対応する通話が接続された | サポートチケットが更新された |
call.ended を受信する | 対応する通話が終了した | 通話時間ゼロなら未接続だった |
現在の通話の照会が data: {} を返す | 現在 UnifyPort が管理する通話が見つからない | 過去の通話結果やモバイルアプリでの通話状況 |
情報を結び付ける前に、ワークスペース、account_id、通話識別子を照合してください。API レスポンスでは call_id、通話イベントでは data.call.id を使います。同じメッセージングアカウントで、別の担当者が別の通話を開始している可能性もあります。
2. 作成は成功したのに相手の電話が鳴らない
通話作成の契約と照らし合わせ、次の順に確認します。
- アプリが意図した認証済みの WhatsApp メッセージングアカウントを選択しており、
runtime_statusがrunningであることを確認します。 - 保存したリクエストを確認します。
to.idはそのアカウントから返されたconversation_id、to.typeはuser、media_typeはvoiceである必要があります。電話番号の文字列で代用できません。 - 現在時刻をレスポンスの
expires_atと比較します。準備期間は作成から既定で2分ですが、サーバー側で変更できるため、返された時刻を使います。この期限は接続後の通話時間を制限しません。 - 担当者が期限前に非公開の使い捨て
join_urlを開き、Start call を押したことを確認します。ページを開くだけでは発信されません。マイクの許可は必須、カメラは任意です。許可済みであることも接続の証拠にはなりません。
期限切れのリンクは再利用しないでください。現在の通話を照会してから、担当者が意図的に新しい準備リクエストを行います。確認項目に問題がなくても呼び出しを確認できない場合は、リクエストとブラウザーの証拠を保存します。根拠なしに相手の電話、ブラウザー、ネットワークを原因と決め付けないでください。
3. タイムアウトや競合で結果が不明になった
作成リクエストのタイムアウトは結果不明であり、何も作成されなかった証拠ではありません。競合レスポンスでは実際のエラー本文を保存し、すべて同じ原因だと想定しないでください。サーバーから読み取り専用の現在の通話の照会を実行します。
curl 'https://api.unifyport.ai/v1/calls/active?account_id=acc_example' \
-H 'X-Api-Key: <YOUR_API_KEY>'
接続済みの音声発信では、次のようなレスポンスが返ります。
{
"request_id": "req_example",
"data": {
"call_id": "call_example",
"state": "active",
"direction": "outbound",
"media_type": "voice"
}
}
現在管理対象の通話がない場合は、次のようになります。
{
"request_id": "req_example",
"data": {}
}
照会では preparing、dialing、ringing、connecting が返る場合もあります。すべての通話が全状態を経由するとは限りません。この照会は失った通話リンクを復元せず、通話履歴も返しません。また、どちらかが WhatsApp モバイルアプリで通話中かどうかも判定しません。照会の失敗を、空の正常レスポンスとして扱わないでください。
返された識別子を、アプリ内の通話とチケットの対応関係に照合します。自動で別の通話を作成したり、アカウントを空けるために所属不明の通話を切断したりしないでください。不明点が残る場合は、担当者と確認してから再試行を判断します。意図的に切断する場合、レスポンスの ended と failed はどちらも終了状態です。failed だけを理由に切断リクエストを繰り返さないでください。
4. 接続されたのにコールバックが届かない
利用資格からアプリの保存状態まで、順に確認します。
- 利用資格:
is_betaはサポートが有効にする読み取り専用のワークスペースフラグです。ワイルドカード購読だけではベータの利用資格を得られません。資格のないワークスペースが通話イベントを明示的に購読すると、403 beta_feature_not_enabledが返ります。 - 購読: 資格のあるワークスペースでは、
subscribed_eventsに必要なイベント名を含めるか、*、空リスト、または省略を使います。明示的なリストは列挙されたイベントだけに一致します。接続イベントと終了イベントの両方を確認してください。 - 配信: 設定されたエンドポイントの URL と状態、受信側のアクセスログ、HTTP レスポンスを確認します。
2xxは配信確認であり、チケット更新の成功を証明しません。 - 処理: 配信と署名検証のガイドに従います。
signing_secretを設定している場合、X-Device-Timestampと生のリクエスト本文を使ってX-Device-Signatureを検証します。イベントのidによる重複排除、永続化、通話とチケットの関連付けを個別に確認します。
配信順序は保証されません。接続イベントが終了イベントより遅く届いた場合は接続の証拠を保存しますが、UI 上の終了済み通話を進行中に戻さないでください。コールバックがないことだけでは、一度も接続されなかったとは判断できません。
5. 通話時間ゼロと空の結果は前後の情報で判断する
duration_seconds は接続時間を秒単位で切り捨てた値です。ゼロだけでは未接続の証明になりません。終了理由とともに接続イベントの証拠も保持してください。作成時の同期エラーでは終了イベントがない場合があるため、すべての作成失敗をコールバック待ちのままにしないでください。
仮の調査例を考えます。担当者が準備済みの通話を開始し、現在の通話の照会は接続済みを示し、受信側も接続イベントを保存しているのに、チケットは「待機中」のままです。次に調べるのはアプリ内の関連付けと状態更新です。再発信してもその記録は修復されません。その後の照会が空でも、失われた履歴は復元できません。保存済みのイベントとリクエストを使ってください。
6. 調査を引き継げる記録をまとめる
ワークスペース、メッセージングアカウント、会話、通話の識別子、request_id、UTC 時刻、機密情報を除いたレスポンス、担当者の操作と権限の状態、取得済みの受信ログを記録します。各項目を「確認済み」または「不明」と明記してください。スクリーンショットや共有ログに API キー、署名用シークレット、非公開通話リンクの全文を含めないでください。
未解決の箇所が残る場合は、記録をテクニカルサポートに送ってください。本記事は、着信、グループ通話、録音、文字起こし、SIP/PBX 連携、AI による自動発信への対応を意味しません。
メッセージ連携を安定したプロダクトパイプラインへ。
まずは 1 つの API で送信を始め、標準イベントですべての inbound メッセージを業務システムへ戻しましょう。