← 全記事
比較

WhatsApp Calling API の録音と文字起こし: チャット受信と通話インテリジェンスを分けて設計する

Meta は 2026 年 6 月 30 日の WhatsApp Business Platform changelog で、サポートチームにとって重要な更新を出しました。Cloud API に call recording と call transcription のガイドが追加され、WhatsApp Business Calling API の一部として扱われています。公式の通話機能には、ユーザー発信の通話、ビジネス発信の通話、SIP、calling webhook、calling pricing も含まれます。

WhatsApp で音声サポートをしているチームには朗報です。録音と文字起こしがあれば、顧客が何を聞いたのか、担当者が何を約束したのか、次に何を確認すべきかを検索できる記録として残せます。ここで「WhatsApp 側で顧客コンテキストの問題は解決した」と考えたくなるかもしれません。

しかし、解決されたのは音声通話の記録化です。チャット受信の設計問題は別に残ります。

通話インテリジェンスとメッセージ受信は別物

通話の文字起こしは、音声セッションから生まれるアーティファクトです。口頭の内容をテキスト化し、QA、要約、教育、フォローアップに使えます。一方で、チャット受信パイプラインの役割は、顧客メッセージをすぐに受け取り、署名を検証し、イベントを保存し、人間、CRM、キュー、AI ワーカーへルーティングすることです。

この二つは同じ顧客タイムライン上で合流すべきですが、同じ依存先にまとめるべきではありません。

観点WhatsApp Calling API の録音/文字起こし署名付き受信チャット webhook
主な対象音声通話と録音/文字起こし顧客メッセージイベント
タイミング通話中または通話後受信メッセージが届いた瞬間
向いている用途QA、要約、コンプライアンス確認、教育、フォローアップ受信、ルーティング、重複排除、CRM 記録、AI トリアージ
避けたい失敗通話後に文脈を失う最初の顧客メッセージがキューに入る前に失われる
チャネル範囲WhatsApp の公式通話機能WhatsApp、Telegram、LINE、TikTok、Zalo、X の標準イベントストリーム

WhatsApp の音声が主チャネルなら、公式 Calling API を中心に置けます。日本やタイのように LINE が強い市場も含め、LINE、WhatsApp、Telegram、Zalo など複数のチャットを扱うチームでは、通話文字起こしは顧客タイムラインの一部であり、受信システムそのものではありません。

境界を先に決める

公式 WhatsApp Calling API は音声レイヤーに置きます。顧客が電話したい、call button が必要、担当者への音声ルーティングが必要、録音や文字起こしを QA に使いたい場合は、この公式機能が適しています。

メッセージ受信はイベントレイヤーに置きます。このレイヤーは地味で厳密であるべきです。

  1. 受信配送を受け取る。
  2. 署名を検証する。
  3. イベント ID で raw event を保存する。
  4. provider、account、conversation、sender、message type でルーティングする。
  5. AI、CRM、人間のキューは保存後に動かす。

チャットは非同期です。顧客が「電話の後、受け取り時間は変更されましたか?」と送って離脱することがあります。受信経路が通話文字起こし、CRM 参照、AI 要約を待っていると、最初に保存すべきメッセージを失うリスクがあります。

UnifyPort の役割

UnifyPort は公式 WhatsApp Calling API を置き換えるものではありません。WhatsApp の音声通話、録音、公式の通話文字起こしが必要なら、そこは Meta の公式通話機能を使います。

UnifyPort の役割はもっと限定的です。通常のメッセージングアカウントからの受信メッセージを非公式インターフェースで受け取り、署名付きの正規化 webhook event として配送します。同じ handler で WhatsApp、Telegram、LINE、TikTok、Zalo、X を扱えます。

webhook endpoint を作り、message.received を購読し、signing_secret を設定します。

curl -X POST https://api.unifyport.ai/v1/webhook-endpoints \
  -H "X-Api-Key: <YOUR_API_KEY>" \
  -H "Content-Type: application/json" \
  -d '{
  "url": "https://support.example.com/webhook",
  "status": "active",
  "subscribed_events": ["message.received"],
  "signing_secret": "<WEBHOOK_SIGNING_SECRET>"
}'

WhatsApp メッセージが届くと、標準イベントを受け取ります。

{
  "id": "evt_20260710_01",
  "type": "message.received",
  "provider": "whatsapp",
  "account_id": "acc_support_whatsapp",
  "occurred_at": "2026-07-10T02:30:00Z",
  "data": {
    "conversation": { "id": "84901234567", "type": "user", "title": "Minh Tran" },
    "sender": { "id": "84901234567", "type": "user", "name": "Minh Tran" },
    "message": {
      "id": "wamid.HBgM20260710",
      "type": "text",
      "text": "Can someone confirm whether my pickup changed after the call?",
      "direction": "inbound",
      "sent_at": "2026-07-10T02:29:58Z"
    },
    "event": { "kind": "message_received" }
  }
}

endpoint に signing_secret がある場合、配送には X-Device-TimestampX-Device-Signature が含まれます。署名は <X-Device-Timestamp>.<raw request body> に対する hex HMAC-SHA256 です。これにより、保存や AI への転送の前に、受信サービスで同じ方法で検証できます。

構成はシンプルに保てます。

WhatsApp / LINE / Zalo / Telegram / TikTok / X message
  -> UnifyPort message.received webhook
  -> HMAC-SHA256 signature verification
  -> Event store
  -> Routing, CRM lookup, AI triage, or human queue

WhatsApp voice call
  -> Official WhatsApp Calling API layer
  -> Recording / transcript / summary artifact
  -> Attach to the same customer timeline

重要なのは、顧客タイムラインをどこから始めるかです。最初の受信イベントから始め、録音、文字起こし、要約を関連アーティファクトとして追加します。

小さなチームの判断軸

2〜10 人のサポートチームにとって、問いは「通話文字起こしを使うか」ではありません。「顧客の最初の接点をどのシステムが保存するか」です。

WhatsApp 音声が主チャネルなら、公式通話スタックが体験の中心になれます。担当者が電話を受け、録音と文字起こしが通話に紐づき、ワークフローは voice-first になります。

チャットが主チャネルなら、受信レイヤーは音声ツールを待つべきではありません。まずメッセージを保存し、その後で拡張します。

  • 顧客が後で電話したら、録音と文字起こしを同じ conversation に紐づける。
  • AI が返信を下書きする場合も、元の message.received を source にする。
  • 人間が返信する場合は、接続済みアカウントから POST /v1/messages を呼ぶ。
  • 追加チャネルが同じキューに入る場合は、別 inbox ではなく provider でルーティングする。

Meta の録音と文字起こし更新により、WhatsApp 音声はサポート用途でより使いやすくなりました。ただし、チャット受信レイヤーの必要性は消えません。二つのレイヤーを分けておけば、片方がもう片方の入口を止めることなく、両方を活用できます。