Twilio移动端挂断后回呼循环问题及C#回调逻辑正确性咨询
问题背景
我有一个用C#编写的MVP应用,核心功能如下:
- 将用户的电话系统注册到其个人资料中,并设为Twilio的已认证DID呼叫方
- 用户点击网站按钮后,Twilio呼叫用户;用户按1后,Twilio添加目标号码并录制通话(已获得用户同意)
遇到的问题
从移动端发起呼叫后,Twilio能正常呼叫用户,用户也可以接通并与目标方通话,但当用户挂断手机时,Twilio会立即回呼用户,形成循环呼叫。
期望效果
用户挂断手机后,Twilio通话完全结束,不再重连。
我的思路与疑问
我尝试在CallStatusCallback webhook中添加逻辑,当Twilio返回callStatus为completed时发送Hangup命令,代码如下:
[HttpPost("twilio-webhook-CallStatusCallback")] public ActionResult CallStatusCallback() { var callStatus = Request.Form["CallStatus"]; if (callStatus == "completed") { // Handle call completed event var response = new VoiceResponse(); response.Hangup(); return TwiML(response); } // Handle other call statuses if needed return new HttpStatusCodeResult(HttpStatusCode.OK); }
有两个疑问:
- 这段代码的语法/逻辑是否正确?
response.Hangup()如何识别要结束的对应通话?我已经添加了webhook,但需要帮助检测正确状态并向特定通话发送Hangup命令。
解决方案与答疑
1. 当前代码的问题
这段代码的语法没问题,但逻辑完全没必要——当Twilio发送completed状态回调时,通话已经结束了,此时返回Hangup指令不会对任何通话产生影响。
2. 循环呼叫的根源
Twilio重复回呼的核心原因,大概率是你在发起呼叫的初始逻辑里,错误设置了「通话结束后自动触发新呼叫」的规则,或者呼叫触发的webhook被重复调用了,比如:
- 初始呼叫的TwiML中,某个分支重定向到了触发呼叫的端点
- 移动端发起请求的逻辑有问题,用户挂断后前端重复发送呼叫请求
- Twilio的呼叫状态回调被错误配置为触发新呼叫
3. 正确的处理方式
要解决循环呼叫,得从根源入手:
- 排查呼叫触发逻辑:检查你调用
CallResource.Create发起Twilio呼叫的代码,确保没有在通话结束后自动触发新呼叫的逻辑 - 检查初始TwiML流程:用户按1连接目标号码时用的
<Dial>标签,不要设置action属性指向会触发新呼叫的端点;如果不需要在通话结束后执行额外操作,<Dial>可以不带action - 主动结束特定通话的正确方式:如果确实需要主动结束某个通话,不要在
CallStatusCallback里返回TwiML,而是通过Twilio API调用CallResource.Update方法,传入目标通话的CallSID(Twilio会在回调请求中通过CallSid参数传递这个值)并设置状态为completed:
using Twilio.Rest.Api.V2010.Account; // 从回调请求中获取当前通话的CallSID var callSid = Request.Form["CallSid"]; // 主动结束该通话 CallResource.Update( pathSid: callSid, status: CallResource.StatusEnum.Completed );
- 覆盖全状态验证:在
CallStatusCallback中,除了completed,还要处理busy、failed、canceled等状态,确保这些场景下不会触发新呼叫
4. 关于response.Hangup()的说明
response.Hangup()生成的TwiML指令,只对当前正在处理的通话生效——也就是当Twilio向你的webhook请求TwiML来控制通话流程时,返回这个指令会让当前通话挂断。但在CallStatusCallback场景下,通话已经结束,所以这个指令完全没用。要操作特定通话,必须通过Twilio API并指定对应的CallSID。
内容的提问来源于stack exchange,提问作者Klint Price
相关产品推荐
相关产品推荐

