本博客由工程队成员Mihail Comanescu撰写
我一直在FreeSwitch实施JavaScriptIVR免费Switchwiki,我发现没有什么信息 如何正确实现以下是我遇到的一些挑战 和我在实施JaavascriptIVRfreeSwitch时想出的解决办法
挑战
- 播放某种音频录制
- 播放动态内容
- 捕捉用户输入播放
- 捕捉超时段输入
概述
环视wiki, 我们发现少许方法 允许我们在频道传递信息 或监听dTMF音调
会话.speak语音引擎回播并看起来有希望,但它让我失望,因为Cepestral两个TS引擎之一没有从盒子里工作,而Flite即TTS引擎有声音太机器人无法实际使用
Session.sayPhrase使用 XML语言宏,但依赖表示语言模块,这不是我想要的尽量多拨号从XML转javascripti期望完全能写入javascript
Session.streamFile可用于播放音频文件,因为它能自动检测推荐编码向下侧使用 session.streamFile它使用回调函数处理它收到的DTMF调子,缺乏控制IVR行为的能力显示维基流File可设置函数,每次用户按键时都调用函数估计我可以存储数字函数外的某个地方,但我仍然会遇到下列问题:回调执行时我如何冻结并恢复当前处理线程如果我多文件需要流出,那么事情会变得复杂,因为DTMF操作可能多回调一次
回调用dTMF键按键时,我不得不检查我是否存有键存储到内存空间中,并或多或少地同步到列表中的下一流中去。
无法将回调函数附加到调用程序上, 因为它们运行在不同执行背景中:javascript运行模式spidermonkey并说运行FreeSwitch执行上下文
execute('ssay','en_spelled迭代')调用CallieIVR拨号应用程序Callie工作顺序播放文件列表匹配 < said字符串>规则比方说参数en, 会通知Callie使用英语记录集, 名拼写dellie会通知Callie尝试拼写并迭代后会通知Callie一次读一字母更多资料称程序可查找来.
基本说来,我的IVR应至少能重播一多段录制并重播后给我从用户收集输入的选项用户按键时IVR播放文件,IVR静默并收集用户输入直到期望超时或期望按键流文件或执行文件都达不到框外的要求
解决之道
多次测试后,我发现分流File对通道变量回放-终结器响应,这些回播-终结器一旦设置到特定密钥列表中,一按键即中断当前回播复用终止器存储信道变量回播终结器使用
我最不需要的是回放静默方式 等待用户输入或推算使用 session.execute类似地说,睡眠是一个拨号应用程序,暂停通道超时或直到发布DTMF信号此时,这几乎完美, 除非我们考虑 可能需要数位对我们来说不幸的是数字不作为回放终止程序抓取,但可用 session.getDigits换句话说,我们不得不检查 session.getDigits
包装式
如何使用上方方法构建avaScriptIVR我们可以写图书馆代码处理它
视图代码
varIVR=函数{/I used prerecorded sounds from callie this.localPath="path to your sounds folder";this.sleep=function(time){if(session.ready)session.execute("sleep",time);}this.play=function(filePath){if(!session.getVariable("playback_terminator_used"))try{session.streamFile(filePath);}catch(e){console_log("WARNING","Could not stream file "+this.localPath+filePath);console_log("WARNING","Error:"+e);}}this.say=function(stuff){if(!session.getVariable("playback_terminator_used"))session.execute("say","en name_spelled iterated "+stuff);}this.flushDigit=function(){var terms=session.getVariable("playback_terminator_used");if(!terms) {terms=session.getDigits(1,"");session.flushDigits();}session.execute("unset","playback_terminator_used");return terms;}this.clearDTMF=function(){session.execute("set","playback_terminators=none");session.flushDigit();}this.getDigits=function(numDigits,mTerminator,iTimeout,dTimeout){numDigits=Number(numDigits);iTimeout=Number(iTimeout);dTimeout=Number(dTimeout);if(!iTimeout) iTimeout=3000;if(!dTimeout) dTimeout=5000;if(!numDigits) return "";if(numDigits<0) return "";var keep=false,myDigits="",aDigit=this.flushDigit();var origTerminators=session.getVariable("playback_terminators");if(!mTerminator) mTerminator="";if(mTerminator.indexOf("+")>=0) keep=true;session.setVariable("playback_terminators","0123456789*#");if(!aDigit){this.sleep(iTimeout);aDigit=this.flushDigit();}numDigits--;if(aDigit){if(mTerminator.indexOf(aDigit)>=0){if(keep) myDigits+=aDigit;return myDigits;}}myDigits+=aDigit;var isDigit=true;if(!numDigits) return myDigits;while(numDigits&&isDigit){this.sleep(dTimeout);aDigit=this.flushDigit();if(aDigit){numDigits--;if(mTerminator.indexOf(aDigit)>=0) isDigit=false;if(isDigit||keep) myDigits+=aDigit;} else isDigit=false;}session.setVariable("playback_terminators",origTerminators);return myDigits;}}
大块代码 但是它究竟能做什么简言之,它试图创建对象处理上文描述的IVR问题我们现在有一些函数处理问题的不同方面
沉睡函数打包上文描述的拨号应用播放并说不执行查找回播终结器,并使用时按魔术键IVR重试某事,则声音和菜单其余部分跳转选择此行为是因为极有可能他已经知道菜单并免等待,因为最近大家都急忙忙忙忙
flackDigit应用清除并返回回播终止程序或会话.getDigits方法
获取digits将返回numDigits指定的数字数或数直到终结器密钥在Merminator变量中指定如果终结者定义中有一个+,则GetDigits返回数字,包括终止者下两个字段用于具体说明超时iTimeout表示它应该等待第一位数被考虑按下并Timeout表示允许连续两位数间时间数
欢乐FreeSwitch编码