XCC API
XCC事件说明
事件订阅可以直接使用 NATS 提供的 subscribe 功能实现,可以订阅 FreeSWITCH 中原生的事件,如,订阅所有原生事件:cn.xswitch.ctrl.event.>。事件的 Subject 以及所需的事件类型可以在系统的 xcc 配置界面上指定。原生事件以 JSON-RPC 格式发出,可以在各种语言中很简单的解析其中的内容。
原始事件订阅说明
分机注册事件
cn.xswitch.ctrl.event.custom.sofia::register分机注册信息cn.xswitch.ctrl.event.custom.sofia::unregister分机注销信息
通话事件
系统有来话或去话时,将生成一个新的 Channel,并产生 channel_create 事件,该事件包含 Channel 的 UUID,主叫号码、被叫号码、Channel 的创建时间等信息。
如果通话正常进行,则会产生 channel_progress 事件(如,收到对方的 100 或 180 消息),如果应答前收到 183 消息,则产生 channel_progress_media 事件。
如果通话被应答,则产生 channel_answer 事件。
如果一个 channel 与另一个 channel bridge 成功则产生 channel_bridge 事件。
如果通话结束挂机,则产生 channel_hangup 和 channel_hangup_complete 事件。其中 channel_hangup_complete 事件内容更丰富,带有 variable_duration(通话时长)以及 variable_billsec(计费时长)等信息。
cn.xswitch.ctrl.event.channel_create通话开始事件cn.xswitch.ctrl.event.channel_state通话状态事件,其中Answer-State表示呼叫状态,如 ringing、answered 等cn.xswitch.ctrl.event.channel_answer通话应答事件cn.xswitch.ctrl.event.channel_bridge通话桥接事件cn.xswitch.ctrl.event.channel_hangup_complete通话结束事件cn.xswitch.ctrl.event.record_start通话录音开始事件cn.xswitch.ctrl.event.record_stop通话录音结束事件
会议事件
cn.xswitch.ctrl.event.custom.conference::maintenance会议所有事件
事件参数说明
会议事件中 Action 为事件动作名,其中主要事件名解释如下:
- conference-create 会议开始
- add-member 成员加入
- del-member 成员离开
- mute-member 成员静音
- unmute-member 成员解除静音
- deaf-member 成员禁听
- undeaf-member 成员解除禁听
- conference-destroy 会议结束
- start-recording 开始会议录制
- stop-recording 结束会议录制
- conference-destroy 会议结束
事件中部分重要参数说明:
- "Conference-Name": "710894413-gaofei.cn" 会议名(号码)会议的唯一标识
- "Conference-Size": "1" 会议总人数
- "Unique-ID": "ee16e182-b298-48f7-8f3e-11c6638c4411" 本次通话 UUID,会话唯一标志
- "Caller-Direction": "inbound" 呼叫方向,inbound 表示呼入,outbound 呼出
- "Caller-Caller-ID-Name": "819" 主叫名称
- "Caller-Caller-ID-Number": "819" 主叫号码
- "Video": "false", 是否开启视频
- "Hear": "true", 是否可听状态
- "See": "true", 是否可看状态
- "Member-ID": "22", 加入会议后的 ID,成员唯一标识
- "Action": "add-member" 事件名
成员加入完整事件如下:
{ "jsonrpc": "2.0", "method": "Event.NativeEvent", "params": { "node_uuid": "6b7532d6-9d2a-4cfe-bf3c-87a353256de0", "event": { "Event-Name": "CUSTOM", "Core-UUID": "6b7532d6-9d2a-4cfe-bf3c-87a353256de0", "FreeSWITCH-Hostname": "gao", "FreeSWITCH-Switchname": "gao", "FreeSWITCH-IPv4": "172.19.0.3", "FreeSWITCH-IPv6": "::1", "Event-Date-Local": "2022-07-08 09:34:07", "Event-Date-GMT": "Fri, 08 Jul 2022 01:34:07 GMT", "Event-Date-Timestamp": "1657244047352956", "Event-Calling-File": "conference_member.c", "Event-Calling-Function": "conference_member_add", "Event-Calling-Line-Number": "965", "Event-Sequence": "126921", "Event-Subclass": "conference::maintenance", "Conference-Name": "710894413-gaofei.cn", //会议名(号码)会议的唯一标识 "Conference-Domain": "gaofei.cn", "Conference-Size": "1", //会议总人数 "Conference-Ghosts": "0", "Conference-Profile-Name": "default", "Conference-Unique-ID": "3b937b30-2d76-44dc-acf7-61d652eb3a5f", "Conference-Rate": "8000", "Conference-Interval": "20", "Floor": "false", "Channel-State": "CS_EXECUTE", "Channel-Call-State": "ACTIVE", "Channel-State-Number": "4", "Channel-Name": "sofia/default/819@gaofei.cn", "Unique-ID": "ee16e182-b298-48f7-8f3e-11c6638c4411", // 本次通话 UUID,会话唯一标志 "Call-Direction": "inbound", "Presence-Call-Direction": "inbound", "Channel-HIT-Dialplan": "true", "Channel-Presence-ID": "819@gaofei.cn", "Channel-Call-UUID": "ee16e182-b298-48f7-8f3e-11c6638c4411", "Answer-State": "answered", "Channel-Read-Codec-Name": "L16", "Channel-Read-Codec-Rate": "48000", "Channel-Read-Codec-Bit-Rate": "768000", "Channel-Write-Codec-Name": "opus", "Channel-Write-Codec-Rate": "48000", "Channel-Write-Codec-Bit-Rate": "0", "Caller-Direction": "inbound", //呼叫方向,inbound 表示呼入,outbound 呼出 "Caller-Logical-Direction": "inbound", "Caller-Username": "819", "Caller-Dialplan": "XML", "Caller-Caller-ID-Name": "819", //主叫名称 "Caller-Caller-ID-Number": "819", //主叫号码 "Caller-Orig-Caller-ID-Name": "819", //原始主叫名称 "Caller-Orig-Caller-ID-Number": "819", //原始主叫号码 "Caller-Network-Addr": "112.237.150.183", "Caller-ANI": "819", "Caller-Destination-Number": "710894413", "Caller-Unique-ID": "ee16e182-b298-48f7-8f3e-11c6638c4411", "Caller-Source": "mod_sofia", "Caller-Context": "context-22", "Caller-Channel-Name": "sofia/default/819@gaofei.cn", "Caller-Profile-Index": "1", "device_id": "819", "Caller-Profile-Created-Time": "1657244047307959", "Caller-Channel-Created-Time": "1657244047307959", "Caller-Channel-Answered-Time": "1657244047345952", "Caller-Channel-Progress-Time": "0", "Caller-Channel-Progress-Media-Time": "1657244047330954", "Caller-Channel-Hangup-Time": "0", "Caller-Channel-Transfer-Time": "0", "Caller-Channel-Resurrect-Time": "0", "Caller-Channel-Bridged-Time": "0", "Caller-Channel-Last-Hold": "0", "Caller-Channel-Hold-Accum": "0", "Caller-Screen-Bit": "true", "Caller-Privacy-Hide-Name": "false", "Caller-Privacy-Hide-Number": "false", "Video": "false", //是否开启视频 "Hear": "true", // 是否可听状态 "See": "true", // 是否可看状态 "Speak": "true", "Talking": "false", "Mute-Detect": "false", "Hold": "false", "Member-ID": "22", // 加入会议后的 ID,成员唯一标识 "Member-Type": "moderator", "Member-Ghost": "false", "Energy-Level": "0", "Current-Energy": "0", "Action": "add-member" // 事件名 } } }
呼叫中心
cn.xswitch.ctrl.event.custom.callcenter::infomod_callcenter 队列模块事件
事件参数说明
事件中 CC-Action 表明事件所属的动作,部分说明如下:
- agent-add:坐席加入队列
- agent-del:坐席签出队列
- agent-contact-change:坐席呼叫字符串发生改变
- agent-status-change:当坐席的逻辑状态 status 改变时候对应的事件
- agent-state-change:当坐席的电话呼叫有关状态 state 改变的时候对应的事件
- agent-offering:将坐席分配给队里中的某个来电成员,坐席还没接听时候的事件
- bridge-agent-start:来电成员连接坐席成功
- bridge-agent-end:来电成员和坐席连接断开
- bridge-agent-fail:呼叫坐席失败时产生的事件
- members-count:有通话(主叫来电者)进入或者离开队列时产生的事件,即:排队数。
- member-queue-start:有通话(主叫来电者)呼入加入队列事件
- member-queue-end:有通话(主叫来电者)离开队列事件
坐席状态
一个座席有两个状态标志,分别是 Status 和 States,如下所示:
Status 是一个座席逻辑上的状态,它有以下几种取值:
- Logged Out:退出服务状态;
- Available:可用状态,可以接电话;
- Available (On Demand):一种特殊的可用状态;
- On Break:座席已登录,但不可以接电话。
States 是跟电话呼叫有关的状态,它有以下几种取值:
- Idle:空闲;
- Waiting:等待接受呼叫;
- Receiving:正在接受呼叫,响铃;
- In a queue call:当前正在一个队列呼叫中。
- Reserved:被分配
js 代码示例
const NATS = require('nats') let nats_url = "nats://xcc-nats:4222"; //这个从系统 xcc 界面里查看 nats-url 的值 console.log("Connecting to " + nats_url) const nc = NATS.connect(nats_url); console.log("Event started, waiting ...") // controller handler const events_subject = "cn.xswitch.ctrl.event.custom.conference::maintenance"; //订阅的事件 nc.subscribe(events_subject, function (msg, reply, subject, sid) { console.log('Received a message: ' + subject) console.log(msg) }) function wait() { // console.log('tick ... '); setTimeout(wait, 3000); } wait();
其他事件
cn.xswitch.ctrl.event.dtmf系统收到按键信息cn.xswitch.ctrl.event.detected_speech语音识别结果事件
话单事件
cn.xswitch.cdrXCC 话单事件
Event.CDR 事件为 XCC 特别处理后的事件,该话单仅包含话单主要字段,如需更多字段可通过 xcc 配置页面修改。
在通话完毕后发出。每一个 Channel 都会有一个 CDR 事件,如果参与通话的是两条腿(aleg、bleg),则会有两个 CDR 事件,并分别有 leg 标志。CDR 事件一般会在 Event.Destroy 之前发出。
CDR 事件默认会送到与 Event.Channel 相同的 Subject 上,但也可以通过全局配置参数 cdr-subject 配置单独的 Subject。
比如开启了 cdr-subject,则订阅 cn.xswitch.cdr 即可收到话单事件。
{ "jsonrpc": "2.0", "method": "Event.CDR", "params": { "node_uuid": "6b7532d6-9d2a-4cfe-bf3c-87a353256de0", "node_ip": "172.19.0.3", "cdr": { "sip_hangup_disposition": "recv_bye", "direction": "inbound", "answer_stamp": "2022-07-07 10:19:52", "start_stamp": "2022-07-07 10:19:52", "uuid": "9c780905-b058-4e64-a183-11d535bbfeb6", "abs_path": "/usr/local/freeswitch/storage/recordings/auto-record-20220708-9c780905-b058-4e64-a183-11d535bbfeb6.wav", "billsec": "3", "caller_id_name": "819", "caller_id_number": "819", "destination_number": "710894413", "hangup_cause": "NORMAL_CLEARING", "account_code": "819", "context": "context-1", "duration": "3", "end_stamp": "2022-07-07 10:19:55", "leg": "a", "logical_direction": "inbound" }, "uuid": "9c780905-b058-4e64-a183-11d535bbfeb6" } }
默认 XCC-CDR 字段说明
| 话单字段 | 中文说明 |
|---|---|
| caller_id_name | 主叫名称 |
| start_stamp | 开始时间 |
| billsec | 计费时长 |
| account_code | 计费号码 |
| network_addr | 网络地址 |
| abs_path | 录音文件绝对路径 |
| answer_stamp | 应答时间 |
| sip_hangup_disposition | SIP 相关 |
| context | 呼叫源 |
| duration | 总时长 |
| end_stamp | 结束时间 |
| uuid | 通话 UUID |
| bleg_uuid | B 腿 UUID |
| direction | 方向,inbound 为向内,outbound 向外 |
| destination_number | 被叫号码 |
| network_port | 网络端口 |
| realm | 域 |
| caller_id_number | 主叫号码 |
| hangup_cause | 挂机原因 |
常用挂机原因说明
: 挂机原因表
| 挂机原因 | 中文说明 |
|---|---|
| ORIGINATOR_CANCEL | 主叫挂机 |
| NORMAL_CLEARING | 正常释放 |
| NORMAL_TEMPORARY_FAILURE | 临时故障 |
| WRONG_CALL_STATE | 呼叫状态异常 |
| USER_BUSY | 用户忙 |
| LOSE_RACE | 别处应答 |
| MEDIA_TIMEOUT | 媒体超时 |
| CALL_REJECTED | 拒绝呼叫 |
| UNALLOCATED_NUMBER | 空号 |
| NO_ROUTE_DESTINATION | 无法路由 |
| NO_USER_RESPONSE | 久叫不应 |
| NO_ANSWER | 无应答 |
| NORMAL_UNSPECIFIED | 未定义 |
| NETWORK_OUT_OF_ORDER | 网络异常 |
| RECOVERY_ON_TIMER_EXPIRE | 呼叫超时 |
| USER_NOT_REGISTERED | 用户未注册 |
| SUBSCRIBER_ABSENT | 用户缺席 |
| GATEWAY_DOWN | 网关故障 |
| MANDATORY_IE_MISSING | SIP 消息不全 |
| SYSTEM_SHUTDOWN | 系统关机 |
| INCOMPATIBLE_DESTINATION | 目的地不兼容 |
| EXCHANGE_ROUTING_ERROR | 交换路由错误 |
| MANAGER_REQUEST | 强制挂机 |
| DESTINATION_OUT_OF_ORDER | 目的地异常 |
| SERVICE_NOT_IMPLEMENTED | 服务未实现 |