如何在Twilio通话日志中正确获取并展示未接来电
Twilio 通话日志未接来电识别解决方案
核心问题原因
Twilio 默认将完成完整信令交互的通话统一标记为 completed 状态,不会自动区分「响铃阶段挂断」和「正常接通后挂断」的场景,仅靠status字段无法直接识别未接来电,需要结合多个通话字段自定义判定规则。
事后日志拉取识别方案
调用Twilio Call Rest API拉取通话记录时,优先提取以下3个核心字段组合判断:
direction:确认是入站通话(值为inbound,即个人手机拨打Twilio号码的场景)answered_by:未接通的通话该字段会返回unanswered或unknown,正常接通的通话会返回human/machine等明确值duration:响铃阶段就挂断的通话时长通常为0或小于1秒
同时满足以下条件的通话可直接标记为未接来电:
direction == 'inbound' && (answered_by == 'unanswered' || answered_by == 'unknown') && duration < 1
实时未接来电标记方案
如果需要在通话结束时实时标记状态,不需要事后批量拉取日志,可以通过配置通话状态回调实现:
- 在你的TwiML响应或者号码配置中,指定
statusCallback地址,开启ringing、answered、completed三类事件回调 - 服务端存储单条通话(以
CallSid为唯一标识)的事件时序,符合以下逻辑的入站通话标记为未接:- 先后收到
ringing、completed事件 - 中间没有收到
answered事件
- 先后收到
示例代码(Node.js)
// 存储通话事件的临时Map,生产环境可以替换为Redis等持久化存储 const callEventMap = new Map(); app.post('/twilio/call-status', async (req, res) => { const { CallSid, CallStatus, Direction } = req.body; // 初始化当前通话的事件列表 if (!callEventMap.has(CallSid)) { callEventMap.set(CallSid, []); } callEventMap.get(CallSid).push(CallStatus); // 通话结束时判断是否为未接 if (CallStatus === 'completed') { const eventList = callEventMap.get(CallSid); const isMissedCall = Direction === 'inbound' && eventList.includes('ringing') && !eventList.includes('answered'); // 此处将isMissedCall字段写入你的业务日志库即可 callEventMap.delete(CallSid); } res.sendStatus(200); });
注意事项
- 不要单独依赖
duration字段判断未接,部分运营商的超短接通场景也会出现时长小于1秒的情况,必须和answered_by字段组合判断 - 如果开启了Twilio自动语音信箱、AI应答等服务,需要额外排除这类系统自动应答的场景,避免误判
内容的提问来源于stack exchange,提问作者Sheshagiri Nimmana
相关产品推荐
相关产品推荐

