Flask集成Twilio:订单处理超时致15秒静默通话断开求助
解决Twilio语音交互长任务通话断开问题
核心思路
Twilio的Webhook要求15秒内返回TwiML响应,要保持通话并处理长任务,必须先返回保持通话的TwiML,再异步执行订单处理,处理完成后通过Twilio API控制通话流程。
具体实现步骤
1. 立即返回保持通话的TwiML
当Twilio发送录音请求到你的Flask接口时,不要直接处理订单,先返回包含<Pause>或<Say>的TwiML,同时用<Redirect>让Twilio定期请求你的接口,维持通话连接:
<Response> <Say voice="alice">正在处理您的订单,请稍候...</Say> <Pause length="10"/> <Redirect method="POST">/check-order-status</Redirect> </Response>
2. 异步执行订单处理
用异步队列(比如Celery+Redis)把订单处理任务从请求线程中剥离,避免阻塞响应:
from flask import Flask, request, Response from celery import Celery import redis app = Flask(__name__) celery = Celery(app.name, broker='redis://localhost:6379/0') redis_client = redis.Redis(host='localhost', port=6379, db=0) @celery.task def process_order(recording_url, call_sid): # 标记订单处理中 redis_client.setex(f'order:{call_sid}', 3600, 'processing') # 执行长时处理逻辑:下载录音、语音识别、订单录入等 # ... # 处理完成后更新状态 redis_client.setex(f'order:{call_sid}', 3600, 'completed') @app.route('/handle-recording', methods=['POST']) def handle_recording(): recording_url = request.form.get('RecordingUrl') call_sid = request.form.get('CallSid') # 启动异步任务 process_order.delay(recording_url, call_sid) # 返回保持通话的TwiML twiml = ''' <Response> <Say voice="alice">正在处理您的订单,请稍候...</Say> <Pause length="10"/> <Redirect method="POST">/check-order-status</Redirect> </Response> ''' return Response(twiml, mimetype='application/xml')
3. 实现状态查询接口
创建接口让Twilio定期查询订单状态,根据状态返回对应TwiML:
@app.route('/check-order-status', methods=['POST']) def check_order_status(): call_sid = request.form.get('CallSid') order_status = redis_client.get(f'order:{call_sid}') if order_status == b'completed': # 处理完成,返回结果并结束通话 twiml = ''' <Response> <Say voice="alice">您的订单已处理完成,感谢您的来电!</Say> <Hangup/> </Response> ''' elif order_status == b'processing': # 继续等待,返回保持通话的指令 twiml = ''' <Response> <Say voice="alice">订单正在处理中,请再稍候...</Say> <Pause length="10"/> <Redirect method="POST">/check-order-status</Redirect> </Response> ''' else: # 处理出错,提示用户并挂断 twiml = ''' <Response> <Say voice="alice">抱歉,订单处理出现问题,请稍后再试。</Say> <Hangup/> </Response> ''' return Response(twiml, mimetype='application/xml')
注意事项
- 异步队列选型:生产环境优先用Celery这类成熟队列,避免用
threading/multiprocessing导致的资源泄漏问题。 - 响应超时控制:
<Pause>时长+接口响应时间不要超过15秒,确保Twilio每次都能及时收到响应。 - 超时兜底:设置订单处理最大等待时长,超过后主动提示用户并挂断,避免长时间占用通话资源。
内容的提问来源于stack exchange,提问作者fjhkjh
相关产品推荐
相关产品推荐

