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

介绍

为了实现动态组合拨号方案避免重复配置,把拨号方案拆分成了2个部分,一个是cti_dialplan_extensio@domain,保存单个拨号方案配置,一个是cti_dialplan_context@domain把多个拨号方案组合一个路由表。拨号方案和路由配置修改后会自动生效。生效时间是cti.json 的gui->dialplan_cacheable”配置的,默认配置是1分钟之内自动生效,如果测试过程要实时生效可以改成0,就是每次拨号方案都会从redis中获取。

用法

条件

把变量和正则表达式匹配,如果匹配,就执行对应的动作。详细参考 https://developer.signalwire.com/freeswitch/FreeSWITCH-Explained/Dialplan/XML-Dialplan/

动作

也叫APP,就是一个功能函数,常见的APP参考 https://developer.signalwire.com/freeswitch/FreeSWITCH-Explained/Modules/mod_dptools_1970333

通道变量

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

设置通道变量的方法

action=“set” data=“变量=值” ,详细参考 https://developer.signalwire.com/freeswitch/FreeSWITCH-Explained/Modules/mod-dptools/6586661

action=“export” data=“变量=值” 详细参考 https://developer.signalwire.com/freeswitch/FreeSWITCH-Explained/Modules/mod-dptools/6586592/

set和export的区别是set设置的变量只作用于本通道,export设置的变量会带入到后续桥接的通道。

如果只需要给后续桥接的通道设置变量,不需要作用于本通道export设置的变量名前面加一个nolocal:前缀或者_nolocal_前缀。

action=“bridge_export” data=“变量=值” 详细参考https://developer.signalwire.com/freeswitch/FreeSWITCH-Explained/Modules/mod-dptools/6586489/

bridge_export和export的区别,export只能导出到拨号方案中bridge的通道(export其实就是switch_ivr_originate中处理的),bridge_export可以导出到任何能通话的通道,包含ESL调用的uuid_bridge(bridge_export其实就是switch_ivr_multi_threaded_bridge中处理的)。

呼入常用的通道变量

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

呼出常用的通道变量

  • origination_nested_vars=true 允许origiante参数不解析变量,变量格式\${变量名}。
  • absolute_codec_string 设置声音编码
  • call_timeout 设置呼叫超时 ,只作用于后续桥接的通道
  • effective_caller_id_number 设置主叫号码,只作用于后续桥接的通道
  • originate_timeout 设置呼叫超时 ,只作用于本端,一般添加在拨号串里,或者export设置
  • origination_caller_id_number 设置主叫号码,只作用于本端,一般添加在拨号串里,或者export设置
  • leg_timeout 为每条腿设置超时时间。可以用于单条腿上[]
  • origination_aleg_uuid a路UUID
  • originate_continue_on_timeout The originate_continue_on_timeout is set to true for this: if the bridge’s dial string specifies several destinations separated by the «|» (this is for failover), the bridge will time out on an unanswered destination and will attempt the next specified destination. Without originate_continue_on_timeout set to true, the bridge will time out on the first destination it tries and the bridge itself will fail.

转接常用的通道变量

  • ignore_early_media 【被叫设置】忽略早期媒体,可选的值 true:忽略 consume:忽略但是可以获取数据,ring_ready:183改成180

  • bridge_early_media 【被叫设置】 主叫可以听到早期媒体,透传还是转码,暂时未测试

  • ringback 【主叫设置】设置呼叫彩铃 ,中国标准的回铃:$${cn-ring} 实际值:%(1000,4000,450)

  • transfer_ringback 【主叫设置】设置转接彩铃,主叫接通之后值bridge,就算转接,未设置transfer_ringback,会使用ringback。

  • call_timeout 【主叫设置】设置呼叫超时

  • originate_timeout 【被叫设置】设置呼叫超时,会覆盖call_timeout

  • instant_ringback=true 【主叫和被叫设置都可以】发送假回铃(被叫没发送180,主叫就先发送嘟嘟的声音)

  • continue_on_fail=true 【主叫设置】转接失败不要挂断主叫

    添加自定义SIP头

    • sip_h_自定义头=值 添加自定义sip头到 INVITE
    • sip_rh_自定义头=值 添加自定义sip头到 200
    • sip_bye_h_自定义头=值 添加自定义sip头到 bye
    • sip_ph_自定义头=值 添加自定义sip头到 180 183

其他常用变量

  • bridge_answer_timeout bridge时等待应答的超时时间,变量 continue_on_answer_timeout 可以控制超时时挂机,还是继续执行拨号方案。
  • sofia_session_timeout 覆盖sip profile配置session_timeout
  • continue_on_fail 呼叫失败后是否继续执行后面的拨号方案
  • hangup_after_bridge bleg挂断后是否挂断aleg。
  • transfer_after_bridge bleg挂断后,aleg transfer目的的。
  • park_after_bridge bleg挂断后,aleg是否park,esl开发接口非常有用。
  • exec_after_bridge_app bleg挂断后后,aleg执行一个APP。
  • api_after_bridge bleg挂断后后,aleg执行一个API。

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

通过通道变量绑定动作

  • execute_on_answer 应答时

  • execute_on_pre_answer 收到183时

  • execute_on_pre_bridge 桥接前

  • execute_on_post_bridge 桥接后

  • execute_on_media 建立媒体时

  • execute_on_ring 收到180时

  • execute_on_tone_detect 检测到信号音时

  • execute_on_originate 发送呼叫请求后

  • execute_on_post_originate 呼叫前

  • execute_on_pre_originate 呼叫完成(183或者200后)

    例子 应答的时候播放一个信号音

    execute_on_answer_play="playback tone_stream://%(10000,0,350,440)"

通过通道变量绑定API命令

  • api_on_answer 应答时
  • api_on_pre_answer 收到183时
  • api_after_bridge 桥接前
  • api_before_bridge 桥接后
  • api_on_media 建立媒体时
  • api_on_ring 收到180时
  • api_on_tone_detect 检测到信号音时
  • api_on_originate 发送呼叫请求后
  • api_on_post_originate 呼叫前
  • api_on_pre_originate 呼叫完成(183或者200后)
  • api_hangup_hook 挂机时
  • api_reporting_hook 生成报表时

例子 应答的时候播放一个信号音

api_on_answer_play="uuid_broadcast ${uuid} tone_stream://%(10000,0,350,440) [aleg|bleg|both]"

拨号方案中生成随机数

<!-- generate random number between 1 and 100 -->
<action application="set" data="rand_val=${expr(randomize(&x);ceil(random(0,100,&x)))}"/>

详细参考 mod_expr说明文档 https://developer.signalwire.com/freeswitch/FreeSWITCH-Explained/Modules/mod_expr_6587353

把外呼的通道变量同步到坐席端

比如是自动外呼转人工,在进入排队的拨号方案 cti_acd 前面加入一个action是 exprot, data是变量名=${变量名},这样就可以把外呼端设置的变量名传给分机了,如果需要单独设置被叫变量 action是 exprot, data是变量名=nolocal:${变量名}。

分机外呼拨号方案设置的数据未进入CDR

如果编码不匹配等呼入直接拒接的,可能还没进入动作就失败了,可以在拨号方案动作是set,和export 行勾选inline ,这样就避免这个问题。

拨号方案中调用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接口,根据返回的结果和正则表达式进行匹配。具体可以看下图的例子。注意返回的数据前后不要有空格换行等不可见字符,会导致和正则表达式匹配不上。如果返回的是json数据,expression 和json的body属性 进行正则匹配,如果返回的是非法json数据,expression 直接和返回的文本数据匹配。

image-20220830104137369

拨号方案中写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。

实现DID功能的例子

redis 创建一个 key 名字:cti_did@域名 ,类型:hash, filed 是DID号码, value为分机号。

匹配表达式写法 ${cti_extension_exists(${cti_hash_get(cti_did@${cti_domain} ${destination_number}}}))}

拨号方案例子,如果 cti_hash_get 没有设置获取value的变量名参数, 就会把获取到的数据 写入 默认变量 cti_hash_get_last_result。

image-20240611105917502

拨号方案从redis获取通道变量

cti_variable hash field ,cti模块定义了cti_variable 这个同名的API和APP,用来从redis的hash表获取通道变量.

  • hash 表的key

  • field hash表的 field

    {
    "set": {
    "变量名": "值"

    },
    "export": {
    "变量名": "值"
    },
    "bridge_export": {
    "变量名": "值"
    }
    }
    • set 用法同 set
    • exort 用法类似export,和export的区别,会直接扩展变量
    • bridge_export 用法类似bridge_export,和bridge_export的区别,会直接扩展变量

被叫和路由、目的地绑定的例子

redis 创建一个 key 名字:cti_inbound_rule@域名 ,类型:hash, filed 是DID号码, value为json格式的转接规则。

{
"set": {
"cti_inbound_dest": "555",
"cti_inbound_route": "internal"
}
}
  • cti_inbound_dest 转接目的地,如果要转接到分机,就是分机号,如果要转接给排队,就是排队号。

  • cti_inbound_route 转接路由,如果要转接给分机,就是internal,如果要转接给排队,就是 acd。

    拨号方案的匹配表达式写法${cti_variable(cti_inbound_rule@${cti_domain} ${destination_number})}

    如果找到了规则,就把cti_inbound_dest和cti_inbound_route设置到通道变量。

    image-20240712114253070

通过http接口返回动作

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

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

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

ivr例子

[
{
"application": "read",
"data": "1 1 /var/1.wav input_dtmf 5000"
},
{
"application": "cti_curl",
"data": "http://ip/app?number=${destination_number}&call=${uuid}&input_dtmf=\\${input_dtmf}"
}
]

read 放音并且读取DTMF,参数说明 <min> <max> <sound file> <variable name> <timeout> <terminators>

cti_curl 提交读取到的DTMF结果,继续返回新的放音。

如果需要实现按键错误提示音,可以使用 play_and_get_digits 代替 read, 具体可以看FreeSWITCH官方文档 https://developer.signalwire.com/freeswitch/FreeSWITCH-Explained/Modules/mod-dptools/6586933/

自动外呼输入分机号(比如隐私号)

再执行机器人或者进入排队的动作之前,拨号方案里面的动作cti_robot,或者cti_acd 之前,添加一个动作 cti_dial_exten,参数 exten <rfc2833|inband> <wait_prompt_time> <input_prompt> <wait_input_time>

  1. exten 分机
  2. rfc2833|inband 发送DTMF类型 ,有的线路不支持rfc2833需要用inband,有的又不支持inband需要rfc2833,建议用inband 兼容性更好,可以根据自己的线路情况测试。
  3. wait_prompt_time 等待请输入分机号的提示音时间 单位毫秒,比如设置10000,就是检测提示音最大时间10秒,检测到了提示音结束就发送按键,如果超过了10秒提示音也没播放或者还在播放提示音也发送按键。
  4. input_prompt 发送分机号之后播放的提示音,可选。比如循环拨号一个提示音。类如按任意键转人工
  5. wait_input_time 等待按键超时时间,可选。只有设置了播放提示音才有效

例子
action = cti_dial_exten data=1234 inband 10000

长签(坐席签入后不挂机等待来电)

长签就是坐席呼叫一个特别号码,接通后不挂机,一直等待接电话,没电话呼入的时候,听背景音乐。 一般用自动应答来实现呼入免操作直接接通,但是有的客户习惯长签模式,顶顶通呼叫中心中间件长签后,不光支持排队分配的电话直接接听,其他电话也一样可以呼入,做到了长签,却不占线。
例子:
action = cti_line_check_in data=linename moh

  • linename 线路名 如果不设置会使用拨打电话的来电作为线路名,长签绑定的线路,长签后,线路并发会强制改成1,退出长签(电话挂机)后恢复默认并发设置。
  • moh 保持音乐 如果不设置默认使用local_stream://default 配置文件->local_stream.conf 里面配置的默认保持音乐,也可以单独指定一个声音文件。

image-20231025114520458

并发限制

限制并发,app默认超过限制会自动挂机,api通过参数控制超过是否挂机
app cti_limit_inc 参数1:限制类型 参数2:最大并发
api cti_limit_inc 参数1:限制类型 参数2:最大并发 参数3:[hangup]
api uuid_cti_limit_inc 参数1:限制类型 参数2:最大并发 参数3:[hangup]
挂机后会自动把统计的并发降1,如果需要提前降1,可以执行通过cti_limit_dec。
api cti_limit_dec 参数1:限制类型
例子限制呼入并发

${cti_limit_inc(callin 30)} 如果超过30并发返回false,没超过返回true。

img

对接黑名单

api cti_http_blacklist url [caller] [callee]
app cti_http_blacklist url [caller] [callee]
如果不设置caller和callee自动从通道变量caller_id_number和destination_number获取。
例子

img

流对接(推流到第三方接口和同时播放流)

app: cti_audio_stream
参数 remote-ip:remote-port

  • native 可选参数 如果不设置,流格式为 8000hz 16位,如果设置了,就是原始的音频格式
  • param 自定义参数

推流协议

  1. 前面4字节 引导数据长度 网络字节顺序
  2. 时间戳 8字节
  3. 引导数据 {"uuid":"","codec":"","param":"自定义参数"}
  4. 数据流

连接断开后会自动重连,并且重发引导数据。
返回的放音流需要和推流的编码一样,不需要引导数据。

流对接(旁路)

app: cti_unicast_start 启动推流
参数 tcp|udp remote-ip remote-port <local-ip> <local-port> <play|mix>

  • tcp|udp 使用tcp还是udp协议推流
  • remote-ip 远端 ip
  • remote-port 远端端口,不设置用0.0.0.0
  • local-ip 本地端口,不设置好用0,随机端口
  • play|mix
    • play 支持播放远端返回的流,发送方必须是远端IP和远端端口
    • mix 把远端的流和本地放音混音

api uuid_cti_unicast_start 启动推流
参数 uuid tcp|udp remote-ip remote-port <local-ip> <remote-ip> <play|mix>

api uuid_cti_unicast_stop 停止推流
参数 uuid

按键触发动作

action: bind_digit_action
参数 name,按键,api:api命令,api参数 或者

比如按键1调用一个URL

action=bind_digit_action data=dtmfcallurl,1,api:cti_http_get,http://demo.ddrj.com/dtmf?uuid=c3129712-17da-4783-a8bf-530c91b84244

按键参数支持正则表达式,更详细的说明请看 https://developer.signalwire.com/freeswitch/FreeSWITCH-Explained/Modules/mod-dptools/6586414/

限制最大通话时间

<action application="sched_hangup" data="[+]<time>[ <hangup_cause>]"/>

例子

action =sched_hangup data=+60 ALLOTTED_TIMEOUT

呼入转接

比如要根据主叫号码被叫号码等信息把呼叫转接到分机、排队等,通过编写拨号方案就可以实现这样的功能,cti模块提供了通过redis设置规则来实现呼入转接的功能,提高性能和方便二次开发的对接。
condition ${cti_transfer(inbound_rule)} ^true$
action =cti_transfer

image-20231128165845058

inbound_rule是hash表的key为规则名字,value是规则配置。支持多个规则,只要成功匹配到一个规则,其他规则就不在匹配。

redis hash 表的 value(规则配置)格式如下

{
"conditions": [
[
{
"variable": "destination_number",
"method": "=",
"value": "5555"
},
{
"variable": "caller_id_number",
"method": "=",
"value": "122"
}
],
[
{
"variable": "caller_id_number",
"method": "=",
"value": "124"
}
]
],
"variables": {
"custom_variables": "test"
},
"exports": {
"custom_variables": "test"
},
"applications": [
{
"application": "bridge",
"data": "user/120"
}
],
"priority": 10
}
  • conditions

    根据这个里面设置的条件,如果命中就执行 variables、exports、applications等配置。

    是二维数组, 用于实现or和and。第一维为or,就是只需要匹配上任意一个就算命中。第二唯为and,就是必须全部匹配才算命中。

    [["条件1","条件2"],["条件3"]] 这个例子中 条件1和条件2都满足才算匹配,如果条件1和条件2有一个不满足,但是条件3满足也算匹配成功。相当于(条件1 and 条件2) or 条件3)

    • variable 用来比较的通道变量

    • value 要比较的值

    • method 比较方法

      • =EQUAL

      • ==EQUAL

      • EQUAL variable等于value,区分大小写,匹配成功

      • equal variable等于value,不区分大小写,匹配成功

      • > variable大于value 匹配成功

      • >= variable大于等于value 匹配成功

      • < variable小于value 匹配成功

      • <= variable小于等于value 匹配成功

      • contain variable包含value,不区分大小写,匹配成功

      • CONTAIN variable包含value,区分大小写, 匹配成功

      • prefix variable前缀是value,不区分大小写,匹配成功

      • PREFIX variable前缀是value,区分大小写, 匹配成功

      • suffix variable后缀缀是value,不区分大小写,匹配成功

      • SUFFIX variable后缀是value,区分大小写, 匹配成功

      • regexp 使用正则表达式匹配

  • variables

    要设置的变量,变量只设置到本段。{"变量名字":"变量值"} 这样的格式,变量的值必须是字符串。

  • exports

    要导出的变量,就是变量会设置到本端和后续bridge的新通道。

  • applications

    ​ 多个APP按顺序执行。

    • application app的名字
    • data app的参数
  • priority 规则优先级,如果有多个规则,按优先级匹配

人工坐席主动接管机器人对话的电话

  1. 人工坐席直接呼入接管

    添加拨号方案,并且在internal路由中启用,放到呼叫外线前面。

    answer
    log info uuid_cti_stop_robot ${uuid_cti_stop_robot($1 intercept)}
    intercept $1

    img

    sip软件直接呼叫 intercept通话callid 进入接管

  2. http接口先呼叫坐席,然后执行接管拨号方案

    http://127.0.0.1:88/cli?key=abc&cmd=bgapi&arg=originate user/1000 intercept通话callid XML internal

拨号方案redis配置

  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 name channel variable name Description
Channel-State state Current state of the channel
Channel-State-Number state_number Integer
Channel-Name channel_name Channel name
Unique-ID uuid uuid of this channel’s call leg
Call-Direction direction Inbound or Outbound
Answer-State state -
Channel-Read-Codec-Name read_codec the read codec variable mean the source codec
Channel-Read-Codec-Rate read_rate the source rate
Channel-Write-Codec-Name write_codec the destination codec same to write_codec if not transcoded
Channel-Write-Codec-Rate write_rate destination rate same to read rate if not transcoded
Caller-Username username .
Caller-Dialplan dialplan user dialplan like xml, lua, enum, lcr
Caller-Caller-ID-Name caller_id_name .
Caller-Caller-ID-Number caller_id_number .
Caller-ANI ani ANI of caller, frequently the same as caller ID number
Caller-ANI-II aniii ANI II Digits (OLI - Originating Line Information), if available. Refer to: http://www.nanpa.com/number_resource_info/ani_ii_digits.html
Caller-Network-Addr network_addr IP address of calling party
Caller-Destination-Number destination_number Destination (dialed) number
Caller-Unique-ID uuid This channel’s uuid
Caller-Source source Source module, i.e. mod_sofia, mod_openzap, etc.
Caller-Context context Dialplan context
Caller-RDNIS rdnis Redirected DNIS info. See mod_dptools: transfer application
Caller-Channel-Name channel_name .
Caller-Profile-Index profile_index .
Caller-Channel-Created-Time created_time GMT microseconds timestamp when the channel was created
Caller-Channel-Answered-Time answered_time GMT microseconds timestamp when the channel was answered
Caller-Channel-Hangup-Time hangup_time GMT microseconds timestamp when the channel was hung up
Caller-Channel-Transfer-Time transfer_time GMT microseconds timestamp when the channel was transfered
Caller-Screen-Bit screen_bit .
Caller-Privacy-Hide-Name privacy_hide_name .
Caller-Privacy-Hide-Number privacy_hide_number This 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_name Sets 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_ip sip_received_ip .
variable_sip_received_port sip_received_port .
variable_sip_authorized sip_authorized .
variable_sip_mailbox sip_mailbox .
variable_sip_auth_username sip_auth_username .
variable_sip_auth_realm sip_auth_realm .
variable_mailbox mailbox .
variable_user_name user_name .
variable_domain_name domain_name .
variable_record_stereo record_stereo .
variable_accountcode accountcode Accountcode 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_context user_context .
variable_effective_caller_id_name effective_caller_id_name .
variable_effective_caller_id_number effective_caller_id_number .
variable_caller_domain caller_domain .
variable_sip_from_user sip_from_user .
variable_sip_from_uri sip_from_uri .
variable_sip_from_host sip_from_host .
variable_sip_from_user_stripped sip_from_user_stripped .
variable_sip_from_tag sip_from_tag .
variable_sofia_profile_name sofia_profile_name .
variable_sofia_profile_domain_name sofia_profile_domain_name .
variable_sip_full_route sip_full_route The complete contents of the Route: header.
variable_sip_full_via sip_full_via The complete contents of the Via: header.
variable_sip_full_from sip_full_from The complete contents of the From: header.
variable_sip_full_to sip_full_to The complete contents of the To: header.
variable_sip_req_params sip_req_params .
variable_sip_req_user sip_req_user .
variable_sip_req_uri sip_req_uri .
variable_sip_req_host sip_req_host .
variable_sip_to_params sip_to_params .
variable_sip_to_tag sip_to_tag .
variable_sip_to_user sip_to_user .
variable_sip_to_uri sip_to_uri .
variable_sip_to_host sip_to_host .
variable_sip_contact_params sip_contact_params .
variable_sip_contact_user sip_contact_user .
variable_sip_contact_port sip_contact_port .
variable_sip_contact_uri sip_contact_uri .
variable_sip_contact_host sip_contact_host .
variable_sip_invite_domain sip_invite_domain .
variable_channel_name channel_name .
variable_sip_call_id sip_call_id SIP header Call-ID
variable_sip_user_agent sip_user_agent .
variable_sip_via_host sip_via_host .
variable_sip_via_port sip_via_port .
variable_sip_via_rport sip_via_rport .
variable_presence_id presence_id .
variable_sip_h_P-Key-Flags sip_h_p-key-flags This will contain the optional P-Key-Flags header(s) that may be received from calling endpoint.
variable_switch_r_sdp switch_r_sdp The whole SDP received from calling endpoint.
variable_remote_media_ip remote_media_ip .
variable_remote_media_port remote_media_port .
variable_write_codec write_codec .
variable_write_rate write_rate .
variable_endpoint_disposition endpoint_disposition .
variable_dialed_ext dialed_ext .
variable_transfer_ringback transfer_ringback .
variable_call_timeout call_timeout .
variable_hangup_after_bridge hangup_after_bridge .
variable_continue_on_fail continue_on_fail .
variable_dialed_user dialed_user .
variable_dialed_domain dialed_domain .
variable_sip_redirect_contact_user_0 sip_redirect_contact_user_0 .
variable_sip_redirect_contact_host_0 sip_redirect_contact_host_0 .
variable_sip_h_Referred-By sip_h_referred-by .
variable_sip_refer_to sip_refer_to The full SIP URI received from a SIP Refer-To: response
variable_max_forwards max_forwards .
variable_originate_disposition originate_disposition .
variable_read_codec read_codec .
variable_read_rate read_rate .
variable_open open .
variable_use_profile use_profile .
variable_current_application current_application .
variable_ep_codec_string ep_codec_string This 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_hold rtp_disable_hold This variable when set will disable the hold feature of the phone.
variable_sip_acl_authed_by sip_acl_authed_by This variable holds what ACL rule allowed the call.
variable_curl_response_data curl_response_data This variable stores the output from the last curl made.
variable_drop_dtmf drop_dtmf Set on a channel to drop DTMF events on the way out.
variable_drop_dtmf_masking_file drop_dtmf_masking_file If drop_dtmf is true play specified file for every tone received.
variable_drop_dtmf_masking_digits drop_dtmf_masking_digits If drop_dtmf is true play specified tone for every tone received.
sip_codec_negotiation sip_codec_negotiation sip_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-Time profile_created GMT 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-Time profile_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_mos Mean 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_display sip_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