我们使用开源软交换机(open-source IPBX)Asterisk实现Web callback功能,用户体验方式为:
1. 在首页输入您的电话号码:
<shapetype id="_x0000_t75" stroked="f" filled="f" path="m@4@5l@4@11@9@11@9@5xe" o:preferrelative="t" o:spt="75" coordsize="21600,21600"><stroke joinstyle="miter"></stroke><formulas><f eqn="if lineDrawn pixelLineWidth 0"></f><f eqn="sum @0 1 0"></f><f eqn="sum 0 0 @1"></f><f eqn="prod @2 1 2"></f><f eqn="prod @3 21600 pixelWidth"></f><f eqn="prod @3 21600 pixelHeight"></f><f eqn="sum @0 0 1"></f><f eqn="prod @6 1 2"></f><f eqn="prod @7 21600 pixelWidth"></f><f eqn="sum @8 21600 0"></f><f eqn="prod @7 21600 pixelHeight"></f><f eqn="sum @10 21600 0"></f></formulas><path o:connecttype="rect" gradientshapeok="t" o:extrusionok="f"></path><lock aspectratio="t" v:ext="edit"></lock></shapetype><shape id="_x0000_i1027" style="WIDTH: 306.75pt; HEIGHT: 67.5pt" type="#_x0000_t75"><imagedata o:title="" src="file:///C:%5CDOCUME~1%5CGAOLIN~1%5CLOCALS~1%5CTemp%5Cmsohtml1%5C09%5Cclip_image001.png"></imagedata></shape>
2.点击“立即拨打”按钮:
<shape id="_x0000_i1028" style="WIDTH: 307.5pt; HEIGHT: 67.5pt" type="#_x0000_t75"><imagedata o:title="" src="file:///C:%5CDOCUME~1%5CGAOLIN~1%5CLOCALS~1%5CTemp%5Cmsohtml1%5C09%5Cclip_image003.png"></imagedata></shape>
3在弹出页面输入您朋友的电话号码(固定电话加区号)
<shape id="_x0000_i1029" style="WIDTH: 242.25pt; HEIGHT: 315pt" type="#_x0000_t75"><imagedata o:title="" src="file:///C:%5CDOCUME~1%5CGAOLIN~1%5CLOCALS~1%5CTemp%5Cmsohtml1%5C09%5Cclip_image005.png"></imagedata></shape>
4点击绿色“呼叫”按钮
上面弹出来的对话框,是基本用户的体验方式考虑的,它还是一个网页,不是Skype客户端,由于这是一个免费的活动,所以没有考虑作为一个标准的基于Web的callback认证功能,另外,用户也不需要输入用户名与密码等信息。直接就可以在网页中输入主叫与被叫号码来体验。
Ø 系统组件:
<shape id="_x0000_i1025" style="WIDTH: 353.25pt; HEIGHT: 373.5pt" filled="t" type="#_x0000_t75" o:ole=""><font size="3"><fill opacity="0" color2="black"></fill><imagedata o:title="" src="file:///C:%5CDOCUME~1%5CGAOLIN~1%5CLOCALS~1%5CTemp%5Cmsohtml1%5C09%5Cclip_image007.emz"></imagedata></font></shape>
Ø 系统网络图
<shapetype id="_x0000_t75" stroked="f" filled="f" path="m@4@5l@4@11@9@11@9@5xe" o:preferrelative="t" o:spt="75" coordsize="21600,21600"><stroke joinstyle="miter"></stroke><formulas><f eqn="if lineDrawn pixelLineWidth 0"></f><f eqn="sum @0 1 0"></f><f eqn="sum 0 0 @1"></f><f eqn="prod @2 1 2"></f><f eqn="prod @3 21600 pixelWidth"></f><f eqn="prod @3 21600 pixelHeight"></f><f eqn="sum @0 0 1"></f><f eqn="prod @6 1 2"></f><f eqn="prod @7 21600 pixelWidth"></f><f eqn="sum @8 21600 0"></f><f eqn="prod @7 21600 pixelHeight"></f><f eqn="sum @10 21600 0"></f></formulas><path o:connecttype="rect" gradientshapeok="t" o:extrusionok="f"></path><lock aspectratio="t" v:ext="edit"></lock></shapetype><shape id="_x0000_i1025" style="WIDTH: 414.75pt; HEIGHT: 375pt" type="#_x0000_t75"><imagedata o:title="未命名10" src="file:///C:%5CDOCUME~1%5CGAOLIN~1%5CLOCALS~1%5CTemp%5Cmsohtml1%5C17%5Cclip_image001.png"></imagedata></shape>
<shape id="_x0000_i1026" style="WIDTH: 7in; HEIGHT: 455.25pt" filled="t" type="#_x0000_t75" o:ole=""><font size="3"><fill opacity="0" color2="black"></fill><imagedata o:title="" src="file:///C:%5CDOCUME~1%5CGAOLIN~1%5CLOCALS~1%5CTemp%5Cmsohtml1%5C09%5Cclip_image009.emz"></imagedata></font></shape>
Ø 安装、部署思路
l Web trigger层
1. 配置文件config.php,在这个文件里说明了callback.php中将要通过AMI连接Asterisk的连接端口(5038),用户名、密码等(这个在Callback engine层的manager.conf配置文件中说明)。
2. 服务器处理文件callback.php,在这个外部文件中执行对应主叫与被叫的拨号方案,先后拨通主叫与被叫。
l Callback engine层
AMI层的配置(为了在外部程序中执行Asterisk,需要赋予权限,就在manager.conf中设置)
在manager.conf中添加结点
;用户名
[admin]
;密码
secret = 123456
;不同级别的认证信息
read = system,call,log,verbose,command,agent,user
write = system,call,log,verbose,command,agent,user
拨号方案的配置
/etc/asterisk/目录上新建了一个专用于这个项目的IVR配置文件web_callback.conf:
;对应主叫方的拨号方案
[skype-web-callback-dial]
;在主叫方的手机上来电显示被叫的手机号
exten => s,1,Set(CALLERID(all)=${CALLED})
;先拨通主叫,如果主叫没通,被叫的输出通道(不存在被叫Sip通道),即被叫的拨号方
;案(a.b.c.d为落地网关的IP地址)
exten => s,2,Dial(SIP/${CALLING}@a.b.c.d||gjA(Welcome))
;如果主叫接听了,记录下主叫是在响铃后主动挂断
exten => s,3,Set(CDR(userfield)=Hangupcause:${HANGUPCAUSE})
exten => s,4,Hangup()
;如果是主叫在响铃一段时间后又不响了,记录下是否由于发生了500的服务器错误。
exten => h,1,Set(CDR(userfield)=Hangupcause:${HANGUPCAUSE})
;对应被叫的拨号方案
[skype-web-callback-answer]
;在被叫方的手机上来电显示主叫的手机号
exten => s,1,Set(CALLERID(all)=${CALLING})
;对于被叫来说需要满足以下需求:
;1.与主叫的通话时间保持5分钟,所以L()这个Dial应用的option选项恰能满足,其中L()第一个参数300000(ms)是总的通话时间,5分钟,第二个参数20000表示还剩下20秒时主叫方将听到timeleft系统提示音(由三个语音文件组成: vm-youhave.gsm
[你还有],20.gsm [20],queue-seconds.gsm[秒通话时间])
有关L()几个参数的说明:
'L(x[:y][:z])' -- Limit the call to 'x' ms warning when 'y' ms are left (repeated every 'z'ms)
--Only 'x' is required, 'y' and 'z' are optional.
--The following special variables are optional:
**LIMIT_PLAYAUDIO_CALLER (default yes) Play sounds to the caller.
**LIMIT_PLAYAUDIO_CALLEE Play sounds to the callee.
**LIMIT_TIMEOUT_FILE File to play when time is up.
**LIMIT_CONNECT_FILE File to play when call begins.
**LIMIT_WARNING_FILE File to play as warning if 'y' is defined.
--'timeleft' is a special sound macro to auto-say the time left and is the default.
;2.${ANSWEREDTIME} 为通道变量,利用被叫方的这个通道变量,可以获取到被叫总的通话时间,根据${ANSWEREDTIME}的值是否等于5分钟,如果通话时间还未到时,被叫方挂断电话,此时转到执行exten => s,7,Playback(PartnerHangup)主叫听到 PartnerHangup[对方已挂机...],如果通话时间已到,转到执行exten=> s,5,Playback(TimeoutHangup)[通话时间到...]
;3.利用另外一个通道变量${HANGUPCAUSE},它将记载从落地网关返回的与PSTN级错误有关的信息,查找 Asterisk wiki上的Recommended SIP <-> ISDN Cause codes部分:
http://www.voip-info.org/wiki/index.php?page=Asterisk+variable+hangupcause
如被叫无人接听返回的是18或19:no answer from the user,转换成Sip返回码为:
480 Temporarily unavailable,如果Dial未成功(被叫响铃一会就断了,或者根本没响铃等异常情况),此时记载下错误码,然后转到相应的执行方案,如无人接听[s-19]。
exten =>s,2,
Dial(SIP/${CALLED}@ a.b.c.d ||gjL(300000:20000:20000:0:1:timeleft::timeleft))
exten => s,3,Set(CDR(userfield)=Hangupcause:${HANGUPCAUSE})
exten => s,4,GotoIf($[${ANSWEREDTIME} = 300]]?5:7)
exten => s,5,Playback(TimeoutHangup)
exten => s,6,Hangup()
exten => s,7,Playback(PartnerHangup)
exten => s,8,Hangup()
exten => s,103,Goto(s-${HANGUPCAUSE},s,1)
exten => h,1,Goto(s-${HANGUPCAUSE},s,1)
;系统忙
;503 Service unavailable
[s-38]
exten => s,1,Playback(SystemBusy)
exten => s,2,Hangup()
;用户忙,拒绝接听此次来电
;call rejected
;403 Forbidden
[s-21]
exten => s,1,Playback(PartnerBusy)
exten => s,2,Hangup()
;电话无人接听
;no user responding
[s-18]
exten => s,1,Playback(PartnerAway)
exten => s,2,Hangup()
;电话无人接听
;no answer from the user
;480 Temporarily unavailable
[s-19]
exten => s,1,Playback(PartnerAway)
exten => s,2,Hangup()
l 系统日志层
CDR记录的保存
Asterisk可以存储CDR记录到一个MYSQL数据库中,也可以选择以CSV文本文件的形式保存起来,在Tom-Skype callback系统中,我们选择了保存到MYSQL数据库。由于Mysql客户端开发库的版权问题,Mysql billing应用程序不再作为Asterisk标准发布版本中的其中一部分来发布,而是以附加内容的形式存在:asterisk-addons,为了让Asterisk支持把CDR日志保存到mysql数据库中,必须下载asterisk-addons包,然后编译与mysql有关的几个模块,并且装载到Asterisk服务器中。
一.下载asterisk-addons包。
有两种方式:
1:官方网站上发布的:
http://downloads.digium.com/pub/asterisk/,如果你当前使用的asterisk是.14版本而且是最新的,这时候从目录中找到最新的asterisk-addons包。
2:从SVN库中检出
svncheckout http://svn.digium.com/svn/asterisk-addons/branches/1.4/,用这种方法要注意几点:
http://svn.digium.com/svn/asterisk-addons/,这个根目录下面,有
branches/
tags/
team/
trunk/
这几个目录,如果你当前使用的asterisk是.14版本而且是最新的,这时候应该要从branches分支目录中找到最新的版本下载,注意:不要直接check out trunk/目录。
二. 编译安装asterisk addons
1. 修改Makefile文件
在编译asterisk addons之前,必须修改asterisk addons源文件下的Makefile文
件:
CFLAGS+=-fPIC
ifeq ($(OSARCH),SunOS)
ASTETCDIR=/var/etc/asterisk
ASTLIBDIR=/opt/asterisk/lib
else
ASTLIBDIR=/usr/lib/asterisks (对应asterisk安装后的模块目录上一级目录)
ASTETCDIR=/home/asterisk-<chsdate w:st="on" year="1899" month="12" day="30" islunardate="False" isrocdate="False">1.4.11</chsdate>(对应asterisk的源代码目录)
endif
MODULES_DIR=$(ASTLIBDIR)/modules
2.执行三部曲
确定已经有了zlib-devel、mysql-devel(/usr/lib/mysql/),
#makeclean
#make
#makeinstall
三. 修改所有配置文件
1:编辑cdr_manager.conf:enabled = yes
2:编辑modules.conf,在[modules],
增加:load => cdr_addon_mysql.so
3:编辑cdr_mysql.conf,如果目前还没有这个文件,新创建一个
[global]
hostname=localhost (Mysql数据库服务器)
dbname=skypecallback (数据库名)
user=root
password=123456
port=3306
sock = /var/run/mysqld/mysqld.sock
userfield=1
四.在Mysql数据库中新建数据数据库、表
CREATE DATABASE skypecallback;
CREATE TABLE `cdr` (
`calldate` datetime NOT NULL default '0000-00-00 00:00:00',
`clid` varchar(80) NOT NULL default '',
`src` varchar(80) NOT NULL default '',
`dst` varchar(80) NOT NULL default '',
`dcontext` varchar(80) NOT NULL default '',
`channel` varchar(80) NOT NULL default '',
`dstchannel` varchar(80) NOT NULL default '',
`lastapp` varchar(80) NOT NULL default '',
`lastdata` varchar(80) NOT NULL default '',
`duration` int(11) NOT NULL default '0',
`billsec` int(11) NOT NULL default '0',
`disposition` varchar(45) NOT NULL default '',
`amaflags` int(11) NOT NULL default '0',
`accountcode` varchar(20) NOT NULL default '',
`uniqueid` varchar(32) NOT NULL default '',
`userfield` varchar(255) NOT NULL default ''
);
ALTER TABLE `cdr` ADD INDEX ( `calldate` );
ALTER TABLE `cdr` ADD INDEX ( `dst` );
ALTER TABLE `cdr` ADD INDEX ( `accountcode` );
系统运行的即时监控
C++后台即时监控程序,根据CDR信息,它对数据库中的CDR记录表进行了二次统计,抽取出了有用信息,存到了另外一个表skypecallback.利用这个表,我们将决定用户的主叫号码是否可以再次参加我们的活动。
分享到:
相关推荐
普博Callback回拨系统-1.3+注册
Ansible-ansible-callback-grafana-annotations.zip,执行剧本时自动在grafana中发布注释!不推荐:这个插件是Ansible 2.6版的一部分。修补应在那里进行。,ansible是一个简单而强大的自动化引擎。它用于帮助配置管理...
本文将详细探讨标题中提及的资源——"pl-minio-callback-1.0.4.tar.gz",这是一款基于Python的库,可以从PyPI官网下载。通过解析其名称,我们可以推断出这个库可能与MinIO服务以及回调功能有关。 首先,让我们了解...
基于回调函数的通用冒泡排序_Callback-function
repeated string names = 2; } ``` 在C语言中,protobuf-c会为每个`repeated`字段生成一个`pb_field_t`数组,你可以通过这个数组来访问和操作这些字段。对于`numbers`字段,protobuf-c会生成一个`int32_t`类型的...
在IT领域,Unigui是一个基于Web的开发框架,它允许开发者创建富客户端应用程序,而无需深入了解复杂的前端技术。这个框架特别适用于那些需要构建高效、跨平台的企业级应用的开发者。"unigui_ajax Post Callback - ...
在开发Java Web应用程序时,`web.xml`是一个关键配置文件,它定义了Web应用的行为和结构。本篇文章将深入探讨如何使用`web.xml`来控制Web应用的各种特性。 1. **定义头和根元素** `web.xml`文件通常以`<web-app>`...
`requestIdleCallback` 是一个Web API,由W3C定义,主要用于调度低优先级的任务。它的工作原理是,当浏览器在完成所有渲染和用户交互后还有额外的时间时,就会调用开发者注册的回调函数。这种方式确保了高优先级的...
官方离线安装包,亲测可用
Evernote iOS x-callback-url 支持 Evernote iOS 应用从 7.5 版开始支持 x-callback-url。 一些应用程序已经在使用这种集成,例如和 。 这是的示例 写了很棒的关于 Evernote iOS 中的 x-callback-url 支持以及我们...
在IT行业中,回调机制是一种常见的编程模式,尤其在C和C++这样的低级语言中,它们经常被用来处理异步操作或实现不同...这种技术在游戏开发、脚本系统、插件架构等领域非常常见,它能帮助我们构建灵活、可扩展的系统。
官方离线安装包,测试可用。使用rpm -ivh [rpm完整包名] 进行安装
总之,异步Web方法调用在Java中具有重要的应用价值,通过AXIS2这样的框架,可以方便地实现异步Web服务的开发和调用,提高系统性能和用户体验。在实际项目中,根据需求选择合适的异步调用策略,并确保正确处理回调和...
只需执行以下命令即可将插件添加到您的项目中: npm install callback-form-email-notifier安装首先,不要忘记: yarn install / nmp installcomposer install将dist / email / settings-example.ini复制到dist / ...
2. **性能优化**:由于CBFS允许在内存中构建文件系统,因此开发者应考虑性能影响,合理设计数据结构和操作流程,避免过度消耗系统资源。 3. **错误处理**:在实现回调文件系统时,必须处理可能出现的各种错误情况,...
回调承诺npm install --save fn-callback-promisify用法 import { promisify } from 'fn-callback-promisify' ; const fnObj = { print : ( content , callback ) => { callback ( content === 'fail' ? 'new error'...
通过阅读《基于java的进程间异步通信系统的设计与实现》这份文档,你将能深入了解如何在Java环境中构建高效、可靠的进程间通信解决方案,并了解这些技术在Android平台上的具体应用。同时,文档中的实例和代码示例将...
CallbackURLKit-应用间通信 开始将URL方案集成到应用程序中,为什么不符合。 CallbackURLKit. register ( action : " play " ) { parameters, ... in self . player . play () } 想要与已经实现的众多其他应用...
在Windows编程中,回调函数(CALLBACK-function)是一种重要的机制,它允许系统或者另一个程序调用我们提供的函数。本文将深入探讨如何实现一个Windows回调函数,并结合提供的源码文件进行详细解析。 首先,Windows...