← 所有文章
指南

WhatsApp 语音通话没响铃?从 preparing 到接通的排查指南

创建 WhatsApp 语音通话返回 201,对方手机却没有响铃时,先找出最后一个能够确认的阶段。响应中的 state: preparing 只表示浏览器通话链接已准备好,不表示已经拨号。反复创建通话,反而可能让最初的请求更难追踪。

本文适用于 UnifyPort 通过非官方接口提供的内测版、人工发起、单对单语音外呼,不是 Meta WhatsApp Business Calling API 指南。首次接入与完整请求示例请看语音通话接入教程。这里重点说明如何利用应用已有的证据定位问题。

1. 先判断手上的证据能说明什么

证据能确认什么不能确认什么
创建返回 201 和 preparing通话链接已准备好已拨号、已响铃或已接通
当前通话查询返回 active当前有已接通的系统管理通话对应回调已送达应用
收到 call.answered对应通话已接通客服工单已更新
收到 call.ended对应通话已结束零秒就代表未接通
当前通话查询返回 data: {}未查到当前由 UnifyPort 管理的通话之前通话的结果或手机端是否空闲

合并这些信息前,先核对工作区、account_id 和通话标识。API 响应使用 call_id,通话事件使用 data.call.id。同一个消息账号也可能被另一位操作员用于发起其他通话。

2. 创建成功,但对方没有响铃

按以下顺序对照创建通话契约检查:

  1. 确认应用选中了预期的、已授权的 WhatsApp 消息账号,且其 runtime_status 为 running。
  2. 核对保存的请求:to.id 必须是该账号返回的 conversation_id,to.type 为 user,media_type 为 voice,不能用手机号字符串替代。
  3. 将当前时间与响应的 expires_at 比较。准备期从创建起默认两分钟,但服务端可以调整,应以返回时间为准;它不限制已经接通的通话时长。
  4. 确认指定客服在到期前打开私密的一次性 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 去重、持久化以及通话和工单的关联。

投递不保证顺序。接通事件晚于结束事件到达时,应补存接通证据,但不要把终态通话重新显示为进行中。仅凭回调缺失,无法认定通话从未接通。

5. 零秒时长和空结果,需要结合上下文

duration_seconds 统计接通时长并向下取整到秒,因此零秒不能证明未接通。应同时保存接通事件证据与结束原因。创建阶段同步失败可能没有结束事件,不要让所有创建失败都无限等待回调。

看一个假设的排查例子:客服启动已准备的通话,当前通话查询显示已接通,接收端也已存下接通事件,但工单仍显示“等待中”。此时应继续检查应用内的关联和状态更新,重拨不会修复这条记录。稍后查询返回空结果,也不能还原缺失的历史,应使用已保存的事件与请求。

6. 整理一份能够继续定位的记录

记录工作区、消息账号、会话和通话标识、request_id、UTC 时间、脱敏响应、客服的操作与权限状态,以及已有的接收端日志。每一项标明“已确认”或“未知”。截图和共享日志中不要包含 API key、签名密钥或完整的私密通话链接。

仍有无法解释的环节时,将记录交给技术支持。本文不代表支持来电、群组通话、录音、转写、SIP/PBX 接入或 AI 自动外呼。

UnifyPort API

让消息接入变成一条稳定的产品管线。

先用统一 API 跑通发送,再用标准事件把所有入站消息接回业务系统。