客户案例:使用点星PBX进行电话自助水费查询TTS语音播报原理

1. 功能环境说明

某市区送水公司安装点星PBX呼叫中心,基本的电话功能有:客户呼入请求送水服务,坐席呼出回访,微信公众号使客户可以关注后在线购买桶装水套餐。除了上述功能外,点星PBX还支持客户电话呼入,并通过IVR语音导航调用PHP程序查询客户套餐余额或剩余桶装水数量信息,并通过TTS引擎将查询结果转wav语音文件,再播报给来电客户。

本案例假设信息如下:

送水公司 已经安装点星PBX呼叫中心系统,且系统的对外服务热线号码为: 77778888

版本要求: 需要点星PBX v3.7或以上版本,点星PBX v3.7下载地址:

http://www.dotasterisk.cn/thread-2240-1-1.html

 

2. 由于我们只是给出实现上述功能的原理,所以先给出简单流程图,如下。

客户案例:使用点星PBX进行电话自助水费查询TTS语音播报原理_第1张图片

本文主要讨论上面绿色流程环节的实现原理和设置。

 

3. 呼叫中心设置

1)在呼叫中心后台菜单【PBX呼叫设置】——【可编程配置】——【可编程目的地】添加一个"自助查询套餐余额"的AGI脚本目的地,如下图。

客户案例:使用点星PBX进行电话自助水费查询TTS语音播报原理_第2张图片

请注意此处的 "dial分机字符串"字符串要按照规矩提示填写,该字符串必须符合点星PBX的拨号分机规则。后续操作需要自己编写基于该拨号字符串的拨号规则脚本,开发者需要略微懂一点asterisk的拨号规则。

2)新建IVR导航,指定按键3动作的下一步流程为"可编程目的地",如下图。

客户案例:使用点星PBX进行电话自助水费查询TTS语音播报原理_第3张图片

3)在点星PBX的拨号规则脚本中编写AGI脚本,实现相关功能。此处先编写拨号规则,需要自定义拨号规则的文件如下。

/opt/app/ast/asterisk/exten_program_custom.conf

加入内容如下:

[root@da36:~]#cat  /opt/app/ast/asterisk/exten_program_custom.conf 
[agi-program]
exten => **90000,1,NoOp(-----DEBUG: 来电手机号: ${CALLERID(num)})
exten => **90000,n,AGI(queryRestMoney.php)
exten => h,1,Hangup()

[root@da36:~]#

4)准备一张 测试数据表client_water,表的内容很简单: 三个主要的field为"客户手机号"、"剩余水费"、“剩余桶”。表结构如下。

客户案例:使用点星PBX进行电话自助水费查询TTS语音播报原理_第4张图片

创建sql表数据如下:

CREATE TABLE `client_water` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `telephone` varchar(16) NOT NULL COMMENT '客户电话',
  `rest_money` int(11) DEFAULT '0' COMMENT '剩余金额(元)',
  `rest_number` int(11) DEFAULT '0' COMMENT '剩余桶装水数量',
  PRIMARY KEY (`id`,`telephone`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
预先录入3条数据,以备后续测试,如下图。

客户案例:使用点星PBX进行电话自助水费查询TTS语音播报原理_第5张图片

上述呼叫流程框架基本设置完成,剩下的主要是php的AGI脚本 queryRestMoney.php 代码编写逻辑。

 

4. 编写AGI脚本 queryRestMoney.php 

1)首先需要安装点星PBX适配的TTS文本转语言引擎,下载地址和安装步骤如下。

下载地址: http://www.dotasterisk.cn/iso/tts-rpms.zip

2) 将下载文件上传到点星PBX,用unzip命令解压,并按照如下步骤安装,如下:

先安装依赖rpm包: rpm -ivh rpm-deps/*.rpm

再安装TTS引擎: rpm  -ivh TTS-2.0.0-2.x86_64.rpm 

如下图。

客户案例:使用点星PBX进行电话自助水费查询TTS语音播报原理_第6张图片

3). 有两种方式编写AGI脚本。

可以从 https://packagist.org/ 下载 phpagi,然后引入,如下图:

客户案例:使用点星PBX进行电话自助水费查询TTS语音播报原理_第7张图片

也可以用点星PBX自带的AGI类库进行AGI类对象的初始化,点星自带的AGI类库文件路径为: /opt/app/crm/Common/Libs/Asterisk/AGI.class.php ,原理一样,编码方法大同小异。

下面以 下载的 "d4rkstar/phpagi" 为例子进行代码编写。

首先请将phpagi库里面的 phpagi.php ,phpagi-asmanager.php 两个文件上传到点星PBX的 /opt/app/ast/agi-bin/目录,然后编写AGI脚本 TTS.conf.php 和 queryRestMoney.php,如下。【注意】php脚本务必给执行权限,简单点就是给777权限即可。

客户案例:使用点星PBX进行电话自助水费查询TTS语音播报原理_第8张图片

先看测试结果,在文章的最后会给出 TTS.conf.php 和 queryRestMoney.php 的源代码。

 

5 测试结果如下。

客户案例:使用点星PBX进行电话自助水费查询TTS语音播报原理_第9张图片

有php代码调用tts引擎生成的text文本文件和wav文件在目录 /dev/shm/tts/ 下面。

 

 客户案例:使用点星PBX进行电话自助水费查询TTS语音播报原理_第10张图片

 

6. 最后给出大家最期待的源码,代码比较简单,仅仅只是说明原理,仅供测试参考。

TTS.conf.php

&1";	//调试
		//file_put_contents('/dev/shm/tts/cmd.log',  __FILE__.':'.  $cmd.PHP_EOL, FILE_APPEND);	//调试
		
		$retStr = $retCode = NULL;
		exec($cmd,$retStr,$retCode);
		//file_put_contents('/dev/shm/tts/cmd.log',  __FILE__.':'.  var_export($retStr, true).PHP_EOL, FILE_APPEND);	//调试
		
		if(DELETE_TMP_TXT_FILE){
			unlink($tts_tmp_text);//成功转换成WAV音频文件后,就删掉原来的临时 txt文件
		}
		if($retCode == 0){
			return TRUE;
		}else{
			return FALSE;
		}
	}

	
	//repeat.wav 重新收听请按9,返回上一层请按星号键,返回主菜单请按井号键,如需帮助请按0
	//$lastMenu是上级菜单的功能码,$mainMenu是主菜单的功能码
	function playWavFile($tts_tmp,$cidnum,$playContent,$lastMenu=''){
		global $agi;
		$wav_file = $tts_tmp .".wav";
		$agi->stream_file($tts_tmp,'#');
		$dtmf = NULL; $try = 0;
		do{
			//repeat.wav 音频文件内容为: 重新收听请按9 ,返回上一层菜单请按*号键
			$dtmf = $agi->get_data("custom/repeat",TIMEOUT,1);
			if($dtmf['result'] == '9'){ //重新收听
				$try = 0;
				$agi->stream_file($tts_tmp,'#');
			}elseif($dtmf['result'] == '*'){//返回上一层菜单
				if(empty($lastMenu)){
					$agi->verbose("WARNING: lastMenu has no value,do nothing");
					$try++;//如果没有具体提供上级菜单,就什么也不做
				}else{
					if(DELETE_TMP_WAV_FILE){ //如果定义了删除临时tts生成的文件,那么就在这里删除
						unlink($wav_file);
					}
					$agi->verbose("debug--jump to:	$lastMenu");
					$agi->goto_dest('from-internal',$lastMenu,1);
					exit; //只要是goto语句,必须在下一行用exit;退出脚本,否则脚本继续执行
				}
			}elseif($dtmf['result'] == '' && $dtmf['data'] == ''){//返回主菜单(AGI的get_data函数只能用这种方法捕获井号键,别无他法)
				if(DELETE_TMP_WAV_FILE){ //如果定义了删除临时tts生成的文件,那么就在这里删除
					unlink($wav_file);
				}
				$agi->goto_dest('from-internal',MAIN_MENU_WELCOME,1);
				exit; //只要是goto语句,必须在下一行用exit;退出脚本,否则脚本继续执行
			}else{
				$try ++;
			}
			if($try == 3 && DELETE_TMP_WAV_FILE ){
				unlink($wav_file);
			}
		}while($dtmf['result'] == '9' || $try < 3);
	}
	
	

queryRestMoney.php

#!/opt/php/bin/php -q
request['agi_callerid']; //获得来电号码
		
		
		//查询数据库
		$result = $PDO->query("SELECT * FROM client_water WHERE telephone='{$cidnum}' LIMIT 1");
		$row = $result->fetch();
		
		
		//假设可以查询到数据
		$tts_tmp = $TTS_tmp_dir ."/" .$cidnum ."_" .time();
		$tts_tmp_text = $tts_tmp .'.txt';
		$tts_tmp_wav = $tts_tmp .'.wav';
		$playContent = '您的账号余额为' .$row['rest_money']. '元,剩余桶装水数量为' .$row['rest_number']. '桶。';
		
		file_put_contents($tts_tmp_text,$playContent);
		if( generateWAV($tts_tmp_text, $tts_tmp_wav) ){
			playWavFile($tts_tmp, $cidnum, $playContent, MAIN_MENU_WELCOME); //传参数必须是$tts_tmp,而不是$tts_tmp_wav,因为播放录音时不需要指出文件后缀.wav
		}
		

 

你可能感兴趣的:(asterisk呼叫中心,asterisk拨号计划,mysql,linux,centos,服务器,php)