当前位置: 首页 > news >正文

【顶顶通呼叫中心中间件(mod_cti 基于 FreeSWITCH)-拨号方案和路由配置】

介绍

为了实现动态组合拨号方案避免重复配置,把拨号方案拆分成了2个部分,一个是cti_dialplan_extensio@domain,保存单个拨号方案配置,一个是cti_dialplan_context@domain把多个拨号方案组合一个路由表。拨号方案和路由配置修改后会实时生效。

用法

通道变量

拨号方案的原理就是对通道变量执行正则表达式匹配,如果匹配上了,就执行对应的动作(APP)。fs的很多特性是通过设置通道变量来实现的。这里介绍一下常用的通道变量,更详细的说明参考 https://freeswitch.org/confluence/display/FREESWITCH/Channel+Variables 和 https://freeswitch.org/confluence/display/FREESWITCH/Variables+Master+List

  • caller_id_number 来电号码
  • network_addr 来电IP
  • destination_number DID

下面几个时设置系统特性常用的通道变量

  • absolute_codec_string 设置声音编码
  • call_timeout 设置呼叫超时 ,只作用于后续桥接的通道
  • effective_caller_id_number 设置主叫号码,只作用于后续桥接的通道
  • originate_timeout 设置呼叫超时 ,只作用于本端,一般添加在拨号串里,或者export设置
  • origination_caller_id_number 设置主叫号码,只作用于本端,一般添加在拨号串里,或者export设置

fs的通道变量非常多,怎么查看通话的通道变量呢,有2个方法 方法1 执行fs控制台命令 uuid_dump 通话UUID,方法2 拨号方案里面执行fs的动作info 也可以输出通道变量,info输出的通道变量有些名字和uuid_dump的不一样,文末复制了一个fs官方文档里面的对应关系。

拨号方案中调用http接口

通过API cti_http_get url [connect_timeout] [response_timeout] [varname] 可以在拨号方案任意位置调用http接口,可以把通道变量作为 http接口的参数,传递给接口。

  • connect_timeout 连接超时
  • response_timeout 等待返回超时
  • varname 返回的数据写入这个变量,如果不设置,就会写入默认变量cti_http_get_last_result
  • 例子
    • 例子1 eval ${cti_http_get(http://ip?arg=${通道变量})}
      执行http请求,返回的结果会写入默认变量cti_http_get_last_result
    • 例子2 set myval=${cti_http_get(http://ip?arg=${通道变量})}
      把cti_http_get返回的结果写入myval变量
  • 接口返回数据说明
    • 返回文本数据
      返回文本数据不会进行解析和也不会去除空格换行,会把原始数据设置到变量里面。
    • 返回JSON数据
      {"header":{"value1":"1","value2":"2"},"body":""}
      head可用来设置自定义的变量,body会写入cti_http_get_last_result,或者自定义的变量名里面。

拨号方案的condition(条件),也可以调用http接口,根据返回的结果和正则表达式进行匹配。具体可以看下图的例子。注意返回的数据前后不要有空格换行等不可见字符,会导致和正则表达式匹配不上。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vMaJvNes-1661834141133)(dialplan/image-20220830104137369.png)]

拨号方案中写redis和读redis

cti_hash_get hash field [varname] ,cti模块定义了cti_hash_get这个同名的API和APP,用来读取redis的hash表.

  • hash 表的key

  • field hash表的 field

  • varname 读取到的value存放的变量

cti_hash_set hash field value cti模块定义了cti_hash_set这个同名的API和APP,用来设置redis的hash表

APP就是一个动作,拨号方案里面可以直接添加动作,拨号方案调用API就和使用变量一样${API名字(参数)},多个参数用空格隔开,可以用set 这个APP把API的返回结果写入变量。也可以嵌套使用比如${cti_extension_exists(${cti_hash_get(callhistory@${cti_domain} ${cti_mid_string(${caller_id_number} -11)})})},如果不需要把返回结果写入变量,只是想执行这个API,可以用eval ,这个什么也不做的APP去调用API。

通过http接口返回动作

APP cti_curl http://ip/app?number=${destination_number} cti_curl 这个APP会调用http,执行接口返回的动作。

返回例子说明,数组格式,支持多个动作。

[{"application":"log","data":"INFO 3text"}]

配置

  1. cti_dialplan_extensio@domain [哈希表]
  • key 拨号方案的名字
  • value
录音的例子
{
    "condition": [
        {
            "field": "${record_filename}",
            "description": "测试是否已经启动录音",
            "expression": ".+",
            "anti-action": [
                {
                    "application": "export",
                    "data": "RECORD_READ_ONLY=false",
                    "description": "是否只录音对方"
                },
                {
                    "application": "export",
                    "data": "RECORD_WRITE_ONLY=false",
                    "description": "是否只录音本方"
                },
                {
                    "application": "export",
                    "data": "RECORD_BRIDGE_REQ=false",
                    "description": "是否应答后开始录音"
                },
                {
                    "application": "export",
                    "data": "RECORD_STEREO=false",
                    "description": "是否双道录音"
                },
                {
                    "application": "export",
                    "data": "record_filename=$${recordings_dir}/${strftime(%Y-%m-%d)}/${caller_id_number}.${destination_number}.${strftime(%H-%M-%S)}.${uuid}.wav",
                    "description": "录音录音文件名"
                },
                {
                    "application": "record_session",
                    "data": "${record_filename}",
                    "description": "开始录音"
                }
            ]
        }
    ],
    "continue": true
}

外呼的例子
{
    "condition": [
        {
            "field": "destination_number",
            "expression": "^00\\d*$",
            "description": "静止呼叫国际长途",
            "action": [
                {
                    "application": "hangup",
                    "description": "00开始的号码挂断"
                }
            ],
            "break": "on-true"
        },
        {
            "field": "destination_number",
            "expression": "^\\d+$",
            "description": "允许全数字号码呼出",
            "action": [
                {
                    "application": "bridge",
                    "description": "通过default网关呼出",
                    "data": "sofia/gateway/default/${destination_number}"
                }
            ]
        }
    ]
}

这里就不做解释了,具体参考FreeSWITCH的拨号方案写法。
支持嵌套等XML拨号方案的所有功能。

  1. cti_dialplan_context@domain [list]
[
    "call extension",
    "call trunk",
    "testabc"
]

CTI模块根据顺序把cti_dialplan_extensio@domain里面的内容组合成一个拨号方案的XML文件。

呼叫路由规则

  1. 分机呼叫使用的呼叫路由规则
    如果分机配置了呼叫路由,就优先使用分机配置的呼叫路由,如果分机没单独配置呼叫路由,就使用SIP配置internal(分机注册的那个profile)的呼叫路由,如果sip的profile配置也没配置呼叫路由,就使用default这个呼叫路由。
  2. 网关呼入使用的呼叫路由
    如果网关配置了呼叫路由,就使用网关配置的呼叫路由,如果网关配置没配置呼叫路由,就使用SIp配置external(关联网关的那个profile)的呼叫路由,如果sip的profile配置也没配置呼叫路由,就使用default这个呼叫路由。
  3. 呼叫路由配置必须小心,防止给盗打,网关和external配置的呼叫路由不能配置呼叫外线的拨号方案。

Info Application Variable Names (variable_xxxx)

Some variables, as shown from the info app, may have variable_ in front of their names. For example, if you pass a header variable called type from the proxy server, it will get displayed as variable_sip_h_type in FreeSWITCH™. To access that variable, you should strip off the variable_, and just do ${sip_h_type}. Other variables shown in the info app are prepended with channel, which should be stripped as well. The example below show a list of info app variables and the corresponding channel variable names:

Info variable namechannel variable nameDescription
Channel-StatestateCurrent state of the channel
Channel-State-Numberstate_numberInteger
Channel-Namechannel_nameChannel name
Unique-IDuuiduuid of this channel’s call leg
Call-DirectiondirectionInbound or Outbound
Answer-Statestate-
Channel-Read-Codec-Nameread_codecthe read codec variable mean the source codec
Channel-Read-Codec-Rateread_ratethe source rate
Channel-Write-Codec-Namewrite_codecthe destination codec same to write_codec if not transcoded
Channel-Write-Codec-Ratewrite_ratedestination rate same to read rate if not transcoded
Caller-Usernameusername.
Caller-Dialplandialplanuser dialplan like xml, lua, enum, lcr
Caller-Caller-ID-Namecaller_id_name.
Caller-Caller-ID-Numbercaller_id_number.
Caller-ANIaniANI of caller, frequently the same as caller ID number
Caller-ANI-IIaniiiANI II Digits (OLI - Originating Line Information), if available. Refer to: http://www.nanpa.com/number_resource_info/ani_ii_digits.html
Caller-Network-Addrnetwork_addrIP address of calling party
Caller-Destination-Numberdestination_numberDestination (dialed) number
Caller-Unique-IDuuidThis channel’s uuid
Caller-SourcesourceSource module, i.e. mod_sofia, mod_openzap, etc.
Caller-ContextcontextDialplan context
Caller-RDNISrdnisRedirected DNIS info. See mod_dptools: transfer application
Caller-Channel-Namechannel_name.
Caller-Profile-Indexprofile_index.
Caller-Channel-Created-Timecreated_timeGMT microseconds timestamp when the channel was created
Caller-Channel-Answered-Timeanswered_timeGMT microseconds timestamp when the channel was answered
Caller-Channel-Hangup-Timehangup_timeGMT microseconds timestamp when the channel was hung up
Caller-Channel-Transfer-Timetransfer_timeGMT microseconds timestamp when the channel was transfered
Caller-Screen-Bitscreen_bit.
Caller-Privacy-Hide-Nameprivacy_hide_name.
Caller-Privacy-Hide-Numberprivacy_hide_numberThis variable tells you if the inbound call is asking for CLIR[Calling Line ID presentation Restriction] (either with anonymous method or Privacy:id method)
initial_callee_id_nameSets the callee id name during the 183. This allows the phone to see a name of who they are calling prior to the phone being answered. An example of setting this to the caller id name of the number being dialled:<action application="set" data="initial_callee_id_name='${user_data(${dialed_extension}@${domain_name} var effective_caller_id_name)}'"/>
variable_sip_received_ipsip_received_ip.
variable_sip_received_portsip_received_port.
variable_sip_authorizedsip_authorized.
variable_sip_mailboxsip_mailbox.
variable_sip_auth_usernamesip_auth_username.
variable_sip_auth_realmsip_auth_realm.
variable_mailboxmailbox.
variable_user_nameuser_name.
variable_domain_namedomain_name.
variable_record_stereorecord_stereo.
variable_accountcodeaccountcodeAccountcode for the call. This is an arbitrary value. It can be defined in the user variables in the directory, or it can be set/modified from dialplan. The accountcode may be used to force a specific CDR CSV template for the call; if the value of the accountcode variable matches the name of a template then that template will be used. This is valuable for having a specific template be used on a per-call basis. See mod_cdr_csv.
variable_user_contextuser_context.
variable_effective_caller_id_nameeffective_caller_id_name.
variable_effective_caller_id_numbereffective_caller_id_number.
variable_caller_domaincaller_domain.
variable_sip_from_usersip_from_user.
variable_sip_from_urisip_from_uri.
variable_sip_from_hostsip_from_host.
variable_sip_from_user_strippedsip_from_user_stripped.
variable_sip_from_tagsip_from_tag.
variable_sofia_profile_namesofia_profile_name.
variable_sofia_profile_domain_namesofia_profile_domain_name.
variable_sip_full_routesip_full_routeThe complete contents of the Route: header.
variable_sip_full_viasip_full_viaThe complete contents of the Via: header.
variable_sip_full_fromsip_full_fromThe complete contents of the From: header.
variable_sip_full_tosip_full_toThe complete contents of the To: header.
variable_sip_req_paramssip_req_params.
variable_sip_req_usersip_req_user.
variable_sip_req_urisip_req_uri.
variable_sip_req_hostsip_req_host.
variable_sip_to_paramssip_to_params.
variable_sip_to_tagsip_to_tag.
variable_sip_to_usersip_to_user.
variable_sip_to_urisip_to_uri.
variable_sip_to_hostsip_to_host.
variable_sip_contact_paramssip_contact_params.
variable_sip_contact_usersip_contact_user.
variable_sip_contact_portsip_contact_port.
variable_sip_contact_urisip_contact_uri.
variable_sip_contact_hostsip_contact_host.
variable_sip_invite_domainsip_invite_domain.
variable_channel_namechannel_name.
variable_sip_call_idsip_call_idSIP header Call-ID
variable_sip_user_agentsip_user_agent.
variable_sip_via_hostsip_via_host.
variable_sip_via_portsip_via_port.
variable_sip_via_rportsip_via_rport.
variable_presence_idpresence_id.
variable_sip_h_P-Key-Flagssip_h_p-key-flagsThis will contain the optional P-Key-Flags header(s) that may be received from calling endpoint.
variable_switch_r_sdpswitch_r_sdpThe whole SDP received from calling endpoint.
variable_remote_media_ipremote_media_ip.
variable_remote_media_portremote_media_port.
variable_write_codecwrite_codec.
variable_write_ratewrite_rate.
variable_endpoint_dispositionendpoint_disposition.
variable_dialed_extdialed_ext.
variable_transfer_ringbacktransfer_ringback.
variable_call_timeoutcall_timeout.
variable_hangup_after_bridgehangup_after_bridge.
variable_continue_on_failcontinue_on_fail.
variable_dialed_userdialed_user.
variable_dialed_domaindialed_domain.
variable_sip_redirect_contact_user_0sip_redirect_contact_user_0.
variable_sip_redirect_contact_host_0sip_redirect_contact_host_0.
variable_sip_h_Referred-Bysip_h_referred-by.
variable_sip_refer_tosip_refer_toThe full SIP URI received from a SIP Refer-To: response
variable_max_forwardsmax_forwards.
variable_originate_dispositionoriginate_disposition.
variable_read_codecread_codec.
variable_read_rateread_rate.
variable_openopen.
variable_use_profileuse_profile.
variable_current_applicationcurrent_application.
variable_ep_codec_stringep_codec_stringThis variable is only available if late negotiation is enabled on the profile. It’s a readable string containing all the codecs proposed by the calling endpoint. This can be easily parsed in the dialplan.
variable_rtp_disable_holdrtp_disable_holdThis variable when set will disable the hold feature of the phone.
variable_sip_acl_authed_bysip_acl_authed_byThis variable holds what ACL rule allowed the call.
variable_curl_response_datacurl_response_dataThis variable stores the output from the last curl made.
variable_drop_dtmfdrop_dtmfSet on a channel to drop DTMF events on the way out.
variable_drop_dtmf_masking_filedrop_dtmf_masking_fileIf drop_dtmf is true play specified file for every tone received.
variable_drop_dtmf_masking_digitsdrop_dtmf_masking_digitsIf drop_dtmf is true play specified tone for every tone received.
sip_codec_negotiationsip_codec_negotiationsip_codec_negotiation is basically a channel variable equivalent of inbound-codec-negotiation. sip_codec_negotiation accepts “scrooge” & “greedy” as values. This means you can change codec negotiation on a per call basis.
Caller-Callee-ID-Name--
Caller-Callee-ID-Number--
Caller-Channel-Progress-Media-Time--
Caller-Channel-Progress-Time--
Caller-Direction--
Caller-Profile-Created-Timeprofile_createdGMT microseconds timestamp when the caller profile was created
Caller-Transfer-Source--
Channel-Call-State-Current state of the call
Channel-Call-UUID--
Channel-HIT-Dialplan--
Channel-Read-Codec-Bit-Rate--
Channel-Write-Codec-Bit-Rate--
Core-UUID--
Event-Calling-File--
Event-Calling-Function--
Event-Calling-Line-Number--
Event-Date-GMT--
Event-Date-Local--
Event-Date-Timestamp--
Event-Name--
Event-Sequence--
FreeSWITCH-Hostname--
FreeSWITCH-IPv4--
FreeSWITCH-IPv6--
FreeSWITCH-Switchname--
Hunt-ANI--
Hunt-Callee-ID-Name--
Hunt-Callee-ID-Number--
Hunt-Caller-ID-Name--
Hunt-Caller-ID-Number--
Hunt-Channel-Answered-Time--
Hunt-Channel-Created-Time--
Hunt-Channel-Hangup-Time--
Hunt-Channel-Name--
Hunt-Channel-Progress-Media-Time--
Hunt-Channel-Progress-Time--
Hunt-Channel-Transfer-Time--
Hunt-Context--
Hunt-Destination-Number--
Hunt-Dialplan--
Hunt-Direction--
Hunt-Network-Addr--
Hunt-Privacy-Hide-Name--
Hunt-Privacy-Hide-Number--
Hunt-Profile-Created-Timeprofile_created-
Hunt-Profile-Index--
Hunt-RDNIS--
Hunt-Screen-Bit--
Hunt-Source--
Hunt-Transfer-Source--
Hunt-Unique-ID--
Hunt-Username--
Presence-Call-Direction--
variable_DIALSTATUS--
variable_absolute_codec_string--
variable_advertised_media_ip--
variable_answersec
variable_answermsec
variable_answerusec
variable_billsec
variable_billmsec
variable_billusec
variable_bridge_channel--
variable_bridge_hangup_cause--
variable_bridge_uuid--
variable_call_uuid--
variable_current_application_response--
variable_direction--
variable_duration
variable_mduration
variable_uduration
variable_inherit_codec--
variable_is_outbound--
variable_last_bridge_to--
variable_last_sent_callee_id_name--
variable_last_sent_callee_id_number--
variable_local_media_ip--
variable_local_media_port--
variable_number_alias--
variable_originate_early_media--
variable_originating_leg_uuid--
variable_originator--
variable_originator_codec--
variable_outbound_caller_id_number--
variable_progresssec
variable_progressmsec
variable_progressusec
variable_progress_mediasec
variable_progress_mediamsec
variable_progress_mediausec
variable_recovery_profile_name--
variable_rtp_audio_in_mosMean Opinion Score; read-only, available in CS_REPORTING state, published by CHANNEL_DESTROY event
variable_rtp_use_ssrc--
variable_session_id--
variable_sip_2833_recv_payload--
variable_sip_2833_send_payload--
variable_sip_P-Asserted-Identity--
variable_sip_Privacy--
variable_sip_audio_recv_pt--
variable_sip_cid_type--
variable_sip_cseq--
variable_sip_destination_url--
variable_sip_from_displaysip_from_display‘User’ element of SIP From: line
variable_sip_from_port--
variable_sip_gateway--
variable_sip_gateway_name--
variable_sip_h_P-Charging-Vector--
variable_sip_local_network_addr--
variable_sip_local_sdp_str--
variable_sip_network_ip--
variable_sip_network_port--
variable_sip_number_alias--
variable_sip_outgoing_contact_uri--
variable_sip_ph_P-Charging-Vector--
variable_sip_profile_name--
variable_sip_recover_contact--
variable_sip_recover_via--
variable_sip_reply_host--
variable_sip_reply_port--
variable_sip_req_port--
variable_sip_to_port--
variable_sip_use_codec_name--
variable_sip_use_codec_ptime--
variable_sip_use_codec_rate--
variable_sip_use_pt--
variable_sip_via_protocol--
variable_switch_m_sdp--
variable_transfer_history--
variable_transfer_source--
variable_uuid--
variable_waitsec
variable_waitmsec
variable_waitusec

相关文章:

  • M1Mac使用UTM虚拟机最小化安装x86_64架构的Archlinux
  • sql2java:WhereHelper基于Beanshell(bsh)动态生成SQL语句
  • 谷歌推广详细教程,Google Ads广告投放指南
  • 蔡甸17万亩粮田丰收 国稻种芯:夏汛蓄洪水护住28天抗旱期
  • 比赛团队队名及口号
  • MECT4CNER 代码遇到的问题
  • 18. SAP ABAP OData 服务嵌套创建功能的实现步骤(Create Deep)
  • 优炫软件中标西南民族大学项目,护航教育行业主机安全
  • 网课搜题公众号免费搭建
  • 【深度学习】——深度学习中基本的网络结构(1)
  • 神经网络如何避免过拟合,人工神经网络过拟合
  • 大学生搜题公众号如何搭建
  • 人工智能神经网络是什么,人工神经网络应用范围
  • sql2java-excel(二):基于apache poi实现数据库表的导出的spring web支持
  • 神经网络方法研究及应用,神经网络研究主要内容
  • Android 架构优化~MVP 架构改造
  • Golang-长连接-状态推送
  • golang中接口赋值与方法集
  • HTTP 简介
  • Java 网络编程(2):UDP 的使用
  • JAVA并发编程--1.基础概念
  • php中curl和soap方式请求服务超时问题
  • vagrant 添加本地 box 安装 laravel homestead
  • Vim 折腾记
  • vue--为什么data属性必须是一个函数
  • 回顾2016
  • 基于HAProxy的高性能缓存服务器nuster
  • 罗辑思维在全链路压测方面的实践和工作笔记
  • 如何优雅地使用 Sublime Text
  • 事件委托的小应用
  • 项目实战-Api的解决方案
  • 一个项目push到多个远程Git仓库
  • MyCAT水平分库
  • 树莓派用上kodexplorer也能玩成私有网盘
  • ​【原创】基于SSM的酒店预约管理系统(酒店管理系统毕业设计)
  • ​RecSys 2022 | 面向人岗匹配的双向选择偏好建模
  • ​软考-高级-信息系统项目管理师教程 第四版【第19章-配置与变更管理-思维导图】​
  • (4)通过调用hadoop的java api实现本地文件上传到hadoop文件系统上
  • (Forward) Music Player: From UI Proposal to Code
  • (pt可视化)利用torch的make_grid进行张量可视化
  • (分布式缓存)Redis分片集群
  • (附源码)springboot家庭装修管理系统 毕业设计 613205
  • (附源码)ssm高校志愿者服务系统 毕业设计 011648
  • (附源码)计算机毕业设计ssm基于B_S的汽车售后服务管理系统
  • (理论篇)httpmoudle和httphandler一览
  • (论文阅读23/100)Hierarchical Convolutional Features for Visual Tracking
  • (七)c52学习之旅-中断
  • (亲测成功)在centos7.5上安装kvm,通过VNC远程连接并创建多台ubuntu虚拟机(ubuntu server版本)...
  • (全部习题答案)研究生英语读写教程基础级教师用书PDF|| 研究生英语读写教程提高级教师用书PDF
  • (一)Thymeleaf用法——Thymeleaf简介
  • (转)利用ant在Mac 下自动化打包签名Android程序
  • ***原理与防范
  • .NET 中使用 Mutex 进行跨越进程边界的同步
  • .NET下ASPX编程的几个小问题
  • .Net下C#针对Excel开发控件汇总(ClosedXML,EPPlus,NPOI)