如何用Twilio可编程语音、Function及TWIML实现IVR多语音输入交互
实现基于Twilio可编程语音的IVR系统(结合Twilio Function与TwiML)
看起来你已经搞定了Twilio呼叫的基础流程,接下来咱们把这个IVR系统打磨得更实用——让它能根据用户的语音/按键输入返回对应业务回复,结合你已有的Webhook和Twilio Function,一步步完善如下:
一、先理清楚现有逻辑的作用
你当前的C# Webhook负责初始化呼叫流程:通过<Gather>组件触发语音/按键收集,设置超时时间,并指定把用户输入结果发送到你的Twilio Function地址;而Twilio Function则接收语音识别结果,返回对应的TwiML回复。
你的现有Webhook代码(C#)
[HttpPost] public TwiMLResult Index(string message) { var response = new VoiceResponse(); var gather = new Gather( input: new List<Gather.InputEnum>() { Gather.InputEnum.Speech } , timeout: 5, action:new Uri("https://url-sample/GatherSample") ); gather.Say("Please press 1 or say sales for sales."); response.Append(gather); LogWriter.Debug($"Message : {response.ToString()}"); return new TwiMLResult(response); }
你的现有Twilio Function代码
exports.handler = function(context, event, callback) { const twiml = new Twilio.twiml.VoiceResponse(); const command = event.SpeechResult.toLowerCase(); twiml.say(`You said ${command}. I'll give you a ${command} fact.`); callback(null, twiml); };
二、完善IVR核心功能的关键调整
1. 给Function添加分支逻辑,匹配不同指令
现在的Function只是简单重复用户输入,咱们可以加条件判断,针对不同的语音/按键指令返回不同的业务回复,同时处理无法识别的情况:
调整后的Twilio Function代码:
exports.handler = function(context, event, callback) { const twiml = new Twilio.twiml.VoiceResponse(); // 兼容语音识别结果为空或按键输入的情况 const command = event.SpeechResult?.toLowerCase() || event.Digits || ''; // 匹配销售相关指令(支持语音说sales/按1) if (command.includes('sales') || command === '1') { twiml.say("Thank you for choosing our sales team. We're available Monday to Friday, 9 AM to 5 PM. You'll be connected to a representative in just a moment."); // 如果需要直接转接电话,添加<Dial>组件即可 // twiml.dial('+1234567890'); } // 新增支持客服分支(语音说support/按2) else if (command.includes('support') || command === '2') { twiml.say("Welcome to customer support. Please briefly describe your issue, and we'll help you resolve it right away."); // 如果需要再次收集用户问题,可以在这里嵌套<Gather>跳转到另一个Function // const gather = twiml.gather({input: 'speech', timeout: 10, action: '/support-handler'}); // gather.say("Please describe your issue now."); } // 处理无法识别的输入,引导重试 else { twiml.say("Sorry, I didn't catch that. Please say 'sales' or press 1 for sales, or say 'support' or press 2 for customer service."); // 跳回初始的Webhook,让用户重新输入 twiml.redirect('https://url-sample/'); // 替换成你初始Webhook的公网地址 } callback(null, twiml); };
2. 优化Webhook的配置,提升体验
咱们可以让<Gather>同时支持语音和按键输入,添加针对电话场景的语音模型提升识别准确率,还要加上超时后的 fallback 提示:
调整后的Webhook代码:
[HttpPost] public TwiMLResult Index(string message) { var response = new VoiceResponse(); var gather = new Gather( input: new List<Gather.InputEnum>() { Gather.InputEnum.Speech, Gather.InputEnum.Dtmf }, timeout: 5, numDigits: 1, // 按键只收集1位,适合IVR快捷选择 action: new Uri("https://url-sample/GatherSample"), speechModel: Gather.SpeechModelEnum.PhoneCall // 专门优化电话场景的语音识别模型 ); // 把提示语说得更清晰,引导用户操作 gather.Say("Welcome to our IVR system. Please press 1 or say 'sales' to reach the sales team, or press 2 or say 'support' for customer service."); response.Append(gather); // 如果用户超时未输入,播放 fallback 提示 response.Say("Sorry, I didn't receive any input. Thank you for calling, goodbye."); LogWriter.Debug($"Message : {response.ToString()}"); return new TwiMLResult(response); }
3. 必要的配置检查
- 确保你的Twilio Function已经绑定了正确的Twilio账号,并且地址能被Twilio访问到(本地开发的话,用ngrok之类的工具暴露公网地址)。
- 检查Webhook和Function的
action地址是否正确,避免拼写错误导致无法回调。
三、测试验证流程
- 用你的Twilio号码发起呼叫,听IVR提示语。
- 测试正常路径:说
sales或者按1,确认返回销售相关回复;说support或者按2,确认客服分支生效。 - 测试异常路径:说无关关键词,确认引导重试的提示正常播放;不做任何操作等超时,确认fallback提示生效。
内容的提问来源于stack exchange,提问作者Ayyappan Subramanian
相关产品推荐
相关产品推荐

