play_and_get_digits
关于通过UUID播放play_and_get_digits获取按键,这个事吐槽下,弄到了大晚上才弄明白,前后经历了很多挫折,最终还是看了上海老李写的文档发现了解决办法。
最近一直想利用官方自大的IVRmenu菜单功能实现自己的ivr定制需求,但是发现了几个问题,fs自带的ivr,无法判断空闲坐席,无法判断登录坐席,通过看案例可以通过dialplan方式获取判断上下班时间,折腾了整整一天没有找到合适资料,查找了各种资料甚少,或者说我是小白,如果哪位网页有方法可以告诉我,相互交流下。幸好自己多年前写过板卡模式呼叫中心系统的代码经验,加之今年疫情期间,已经基本迁移到现有的C#ESL控制模式里边,新冠疫情期间也熬了几次夜才做的差不多,没有完全验证,今天一个热力公司客服系统有需求,所以趁客户的需求赶紧完善下我们基于fs开发的yhhpbx业务能力,也算是需求驱动我的研发动力。
好久不写程序,感觉有点生疏,最近自己的小团队突破20人了,没有精力直接参与开发了,管理也是大头,总之一切为了生存,经营一个大家庭不容易。
言归正传,
play_and_get_digits 不管是用app,还是api都不能马上获取到按键,最终只能通过自己程序阻塞获取按键,直到时间超时,按键长度超时目前不知道怎么用,也没有找的合适的方法,直接亮出我们的方法C# esl ,有参考老李的的作品。
/// <summary>
/// 播放语音文件并且接受DTMF
/// 2020.11.6升级
/// </summary>
/// <param name="t_eslConnection"></param>
/// <param name="arg_uuid"></param>
/// <param name="arg_VoiceFile"></param>
/// <param name="destption">调用来源</param>
/// <returns></returns>
public static string AskPlayBackfrom_DigitsSelect(ESLconnection t_eslConnection, string arg_uuid, string arg_VoiceFile, string destption)
{
try
{
//ESLconnection eslConnection = new ESLconnection(Global.g_fsServerIP, Global.g_fsServerProt, "ClueCon");
if (t_eslConnection.Connected() != ESL_SUCCESS)
{
DebugView.DebugViewPrint("AskPlayBackfrom_DigitsSelect()", "Error connecting to FreeSwitch");
return "";
}
string comSelectVoice = arg_VoiceFile;
comSelectVoice = comSelectVoice.Replace(@"\\", "/");
comSelectVoice = comSelectVoice.Replace(@"\", "/");
comSelectVoice = comSelectVoice.Replace(@"//", "/");
if (!File.Exists(comSelectVoice))
{
comSelectVoice = Application.StartupPath + "/Voice/" + arg_VoiceFile;
comSelectVoice = comSelectVoice.Replace(@"\\", "/");
comSelectVoice = comSelectVoice.Replace(@"\", "/");
comSelectVoice = comSelectVoice.Replace(@"//", "/");
}
if (!File.Exists(comSelectVoice))
{
DebugView.DebugViewPrint("EslMainFun.AskPlayBackfrom_DigitsSelect", "[" + comSelectVoice + "]不存在...");
comSelectVoice = "D:/Voice/" + arg_VoiceFile;
comSelectVoice = comSelectVoice.Replace(@"\\", "/");
comSelectVoice = comSelectVoice.Replace(@"\", "/");
comSelectVoice = comSelectVoice.Replace(@"//", "/");
}
//play_and_get_digits <min> <max> <tries> <timeout> <terminators> <file> <invalid_file> [<var_name> [<regexp> [<digit_timeout> [<transfer_on_failure>]]]]
//sprintf(cmd_tmp,"1 1 1 10 a %s",filename);//设置让 play_get_dtmf 函数里面的按键处理条 件无效, ivr check_dtmf_event 函数自己处理按键判断
//string filename = "F:/MornRay/Project/Esl/Voice/we.wav";
//<min最小按键个数> <max最大按键个数> <tries提示音乐播放次数> <timeout ms按键超时时间> <terminators结束字符> <file放音文件>
int MaxTimer = 30;
int MaxDtmf = 1;
string EndDtmf = "#";
string cmd_tmp = String.Format("1 " + MaxDtmf + " 2 " + MaxTimer * 1000 + " '' {0} ''", comSelectVoice);
ESLevent retEvent = t_eslConnection.Execute("play_and_get_digits", cmd_tmp, arg_uuid);
string DtmfKeys = Check_dtmf_event(t_eslConnection, "", "", EndDtmf, MaxDtmf, MaxTimer, 0);
return DtmfKeys;
}
catch (Exception ex)
{
LogP.LogError("AskPlaybackfrom_digits(string arg_uuid, string arg_VoiceFile),Exception:" + ex.Message, "eeror.fscmd.log");
LogP.LogError("app=>play_and_get_digits ,uuid=" + arg_uuid + ", from:" + destption, "eeror.fscmd.log");
return "";
}
}
/// <summary>
/// 播音取按键
/// </summary>
/// <param name="eslCon">连接</param>
/// <param name="filename">filename:语音文件名称,多个文件以分号";"隔开,文件名称可以带.wav,扩展名,假如没有,默认是.pcm扩展名.可指定路径,假如没有,默认是语音程序的./data/system目录下</param>
/// <param name="invalidfile"></param>
/// <param name="EndDtmf">EndDtmf:按键结束条件,比如"#"表示按#号结束输入,""表示没有结束按键条件//支持最大3个结束按键 比如 EndDtmf="*0#" 表示按 0,* 或者#都可以结束</param>
/// <param name="MaxDtmf">MaxDtmf:最大按键个数结束条件,0表示没有按键个数结束条件</param>
/// <param name="MaxTimer">MaxTimer:按键最大时间结束条件,单位秒,0表示没有最大时间结束条件</param>
/// <param name="TwoDtmfTimer">TwoDtmfTimer:两个按键间的间隔时间结束条件,单位秒,0表示没有两个按键间的间隔时间结束条件</param>
/// <returns>返回的字符串</returns>
public static string Check_dtmf_event(ESLconnection eslCon, string filename, string invalidfile, string EndDtmf, int MaxDtmf, int MaxTimer, int TwoDtmfTimer)
{
long t_stime = TimeStampTran.GetTimeStamps(); // 开始监视代码运行时间
string DtmfKeys = "";
try
{
while (true)
{
long t_etime = TimeStampTran.GetTimeStamps();
long spantime = t_etime - t_stime;
if (spantime > MaxTimer * 1000)
{
break;
}
ESLevent eslEvent = eslCon.RecvEvent();
if (eslEvent != null && eslEvent.GetHeader("Event-Name", -1) == "DTMF")
{
string currDtmf = eslEvent.GetHeader("DTMF-Digit", -1);
if (currDtmf == EndDtmf)
{
break;
}
DtmfKeys = DtmfKeys + currDtmf;
if (DtmfKeys.Length >= MaxDtmf)
{
break;
}
}
Thread.Sleep(50);
}
return DtmfKeys == null ? "" : DtmfKeys;
}
catch (Exception ex)
{
return "";
}
}
说明: Check_dtmf_event()是我写的阻塞检测按键的方法.
我的微信:langant,我们可以提供关于fresswitch的开发经验,定制其他软件需求定制。