Voximplant平台:按需(用户按DTMF3)转接呼入电话至手机号的实现问题
Voximplant平台:按需(用户按DTMF3)转接呼入电话至手机号的实现问题
我太懂这种找了一圈答案却全是矛盾、还没一个能用的憋屈感了!你想要的是呼入进来先不直接转手机,必须等用户在特定状态下按了DTMF3之后才触发转接,而且觉得AppEvents.CallAlerting这个事件场景不对,完全没错——那个事件是刚来电时触发,根本不符合你“按需转接”的需求。
先看看你尝试的两个转接函数,核心思路是对的,但可能在全局Call实例的管理、流程触发时机上出了问题,导致没生效。我给你梳理下正确的实现流程,再给你修正后的代码:
先明确核心流程
- 呼入电话进来后,先接听,进入菜单状态播放提示音(告诉用户按3转接)
- 监听用户的DTMF输入,只有检测到按下3时,才执行转接逻辑
- 转接时创建PSTN呼叫到目标手机,成功连接后打通两边的媒体通道
- 完善各种异常处理(比如转接失败、任意一方挂断)
修正后的完整代码
// 全局保存呼入电话的实例,避免作用域问题导致Call对象引用错误 let incomingCall; // 监听呼入事件 VoxEngine.addEventListener(AppEvents.IncomingCall, (e) => { incomingCall = e.call; // 先接听呼入电话 incomingCall.answer(); // 呼入接通后进入菜单状态 incomingCall.addEventListener(CallEvents.Connected, startMenuState); // 原呼入挂断时直接终止整个流程 incomingCall.addEventListener(CallEvents.Disconnected, VoxEngine.terminate); }); // 进入菜单状态:播放提示音,监听DTMF function startMenuState() { // 用TTS播放提示,告诉用户按3转接 incomingCall.playTTS("请按3转接至手机", () => { // 提示音播放完后,开始监听用户的DTMF输入 incomingCall.addEventListener(CallEvents.DTMFReceived, handleDTMFInput); }); } // 处理DTMF输入,判断是否按了3 function handleDTMFInput(e) { if (e.dtmf === "3") { // 移除DTMF监听,防止用户重复按3触发多次转接 incomingCall.removeEventListener(CallEvents.DTMFReceived, handleDTMFInput); // 执行转接逻辑 forwardToMobile(); } } // 核心转接函数 function forwardToMobile() { const callerId = incomingCall.callerid(); const targetMobile = '393333333333'; // 你的目标手机号 // 发起PSTN呼叫到目标手机 const outboundCall = VoxEngine.callPSTN(targetMobile, callerId); // 目标手机接通后,建立两边的媒体桥接 outboundCall.addEventListener(CallEvents.Connected, (e) => { VoxEngine.sendMediaBetween(incomingCall, e.call); // 给目标手机播放提示,说明是转接来电 e.call.playTTS("您有一个转接来电,请接听"); }); // 转接失败的处理:给原呼入方播放提示后终止 outboundCall.addEventListener(CallEvents.Failed, () => { incomingCall.playTTS("转接失败,请稍后再试", () => { VoxEngine.terminate(); }); }); // 目标手机挂断的处理:告知原呼入方后终止 outboundCall.addEventListener(CallEvents.Disconnected, () => { incomingCall.playTTS("转接已结束", () => { VoxEngine.terminate(); }); }); // 原呼入方中途挂断的话,主动挂断目标手机的呼叫 incomingCall.addEventListener(CallEvents.Disconnected, () => { if (outboundCall) outboundCall.hangup(); VoxEngine.terminate(); }); }
为什么你的原代码可能没生效?
- Call实例引用错误:你原代码里用的
Call可能不是当前的呼入电话实例,尤其是如果在菜单状态里没有正确保存全局的呼入对象,会导致后续操作找不到正确的通话实例 - 触发时机不对:原代码里绑定的
CallEvents.PlaybackFinished可能没有对应到正确的播放操作,导致转接函数没被触发 - 异常处理不完善:缺少对原呼入电话中途挂断的处理,或者转接失败后没有给用户反馈,看起来像是没生效
你可以把这段代码替换进去测试,应该能满足你“按需转接”的需求。
备注:内容来源于stack exchange,提问作者Joe
相关产品推荐
相关产品推荐

