XCC API
API 列表
本系统提供的 API 称为 XCC API。XCC API 也支持调用 FreeSWITCH 底层原生的 API,但原生 API 可能失去 XCC 的控制,请尽量使用 XCC API。
XCC API 使用 Google Protocol Buffers 描述,参考xctrl.proto以及协议参考文档。
- Accept:用于来话,接管该呼叫然后什么也不做。
- Ring:用于给来话播放回铃音。
- Answer:应答。
- Play:播放一个文件或 TTS。
- Stop:中断当前的 API(如放音等)。暂未实现。
- Broadcast:播放一个文件或 TTS 到通话中的双方。
- Record:录音。
- Hangup:挂机。
- Dial:外呼。
- Log:日志打印。
- Bridge:用于将当前通话(来话或去话)桥接(呼叫)另一路通话。
- ChannelBridge:桥接两部已经存在的通话,当桥接的通话完毕后返回消息。
- ChannelBridge2:桥接两部已经存在的通话,当桥接成功后马上返回消息。
- ReadDTMF: 播放一个语音并获取用户按键信息。
- DetectSpeech:播放一个语音并获取语音识别结果。
- StopDetectSpeech:停止语音检测。
- RingBackDetection:回铃音检测。
- DetectFace:人脸识别。
- SendDTMF: 发送 DTMF。
- SendInfo:发送 SIP INFO。
- Mute: 通话静音
- WaterMark:添加水印。
- SetVar:设置通道变量(随路数据)。
- GetVar:获取通道变量(随路数据)。
- FIFO:呼叫中心 FIFO。
- Callcenter:呼叫中心 Callcenter。
- Conference:会议。
- AI:JSON 格式 HTTP 交互。
- HttAPI:XML 格式 HTTP 交互
- Lua:执行 Lua 脚本
- Shutdown:关闭节点
通用参数:
ctrl_uuid
: 当前 Controller 的 UUID。
Accept
接管来话,当前通话信息以后所有的事件都将会发到接管的 Ctrl 上。
uuid
: 当前 Channel 的 UUID。takeover
:true|false
。用于多个 Ctrl 的场景,另一个 Ctrl 可以接替原来的 Ctrl 处理呼叫。
在呼入场景中,这应该是 Ctrl 在收到 Event.Channel(state = START
)后发送的第一个消息。否则,后续的 API 可能失败,但 Answer 除外,Answer 会隐含 Accept,这主要是为 Ctrl 在开发时提供一些便利。
Ring
用于播放回铃音。调用ring_ready
发送 SIP 180 消息。
Answer
应答。
Play
播放本地的语音文件,或存放在 HTTP 服务器上的文件,或 TTS 等。
media
:媒体
media
参数定义:
type
:枚举字符串,文件类型,见下文data
:字符串,语音文件或 TTSengine
:字符串,TTS 引擎,目前支持华为、讯飞、阿里、百度等。voice
:字符串,嗓音,由 TTS 引擎决定,默认为default
。loop
:正整数,重复次数,暂未实现。offset
:正整数,语音文件播放偏移量。以采样点为单位,如文件采样率为8000
,则偏移8000
即1
秒。暂仅支持单个文件。对于file_string
类型只对第一个文件起作用。record
: 录音设置参数,可选,值为IGNORE_READ
(大小写不敏感),打开record
后,如果放音的腿上开启了录音,放音开始后,录音文件里将只写入该放音的声音文件数据,不再写入收到的其他数据,放音结束后,录音数据写入将自动恢复正常,和Broadcast 接口中record
参数作用相同。
record
参数举例说明:如果 a 和 b 在通话,a 开启了录音,a 调用Play
接口放音,在不开启record
参数的情况下,a 的录音文件中放音部分的数据,除了放音文件的声音,还同时会写入用户 a 自己的声音,这样会影响有些客户的录音质检,打开record
参数则可以解决这一问题。
其中engine
和voice
为 TTS 参数。
文件类型有:
FILE
:文件TEXT
:TTS,即语音合成SSML
:TTS,SSML 格式支持(并非所有引擎都支持 SSML)
在播放的过程中,会检测 DTMF 并以事件(Event.DTMF
)形式发出。
Stop
停止播放。
Broadcast
播放本地的语音文件,或存放在 HTTP 服务器上的文件,或 TTS 等。如果uuid
处于BRIDGE
状态,则播放到通话的双方。
uuid
:当前 UUID。media
:媒体,参见 Play。option
:参数,默认为BOTH
。record
: 录音设置参数,可选,值为IGNORE_READ
(大小写不敏感),打开record
后,如果放音的腿上开启了录音,放音开始后,录音文件里将只写入该放音的声音文件数据,不再写入收到的其他数据,放音结束后,录音数据写入将自动恢复正常。apps
:用于在放音结束后,执行 FreeSWITCH 的 Application,可以执行多个。
record 参数:
举例说明:如果 a 和 b 在通话,a 开启了录音,a 调用Broadcast
放音,在不开启record
参数的情况下,a 的录音文件中放音部分的数据,除了放音文件的声音,还同时会写入用户 a 自己的声音,这样会影响有些客户的录音质检,打开record
参数则可以解决这一问题。
option 参数:
BOTH
:双方。ALEG
:只有当前 UUID 能听到。BLEG
:当前 UUID 的对端能听到。AHOLDB
:同ALEG
,同时对 B 放保持音乐(如果配置了的话)。BHOLDA
:同BLEG
,同时对 A 放保持音乐。
apps 参数:
由于Broadcast
接口本身是异步的,因此如果想执行完放音后想再执行一些 Application,则可以使用该参数,例如:
{ "method": "XNode.Broadcast", "params": { "media": { "type": "FILE", "data": "/tmp/test.wav" }, "option": "BOTH", "apps": { "playback": "/tmp/test1.wav", "hangup": "NORMAL_CLEARING" } } }
Record
录音。传入相同的path
可以开始和结束录音。录音将存储在 FreeSWITCH 本地文件,Ctrl 收到相关信息后可以通过其它方式下载录音。具体录音文件的存储不在本文档范围内。
录音有两种情况:
非阻塞录音:后台在单独的线程中启动录音,不影响当前操作,如可以继续 Play 或 Bridge。
阻塞录音:适用于单腿的,语言留言之类的情况。
path
:文件路径。limit
:可选,时长,单位为秒。action
:动作。
动作可以有:
RECORD
:阻塞录音。START
:开始录音。STOP
:结束录音。MASK
:屏蔽敏感信息,如 DTMF 或密码等。UNMASK
:停止屏蔽。
非阻塞录音
在非阻塞录音会立即返回,可以在腿上执行后续的操作如 Play 或 Bridge 等。非阻塞录音无法获取录音结果,但相关结果可以通过监听RECORD_START
和RECORD_STOP
事件获取。
阻塞录音
阻塞录音有以下参数:
beep
:播放一个“嘀”声,可以输入default
,或者任何合法的TGML 。terminators
:字符串如1234
,按键可以打断录音。thresh
:VAD 声音检测阈值,0
为禁用。1~100000
,值越大声音越小,即越敏感。silence_seconds
:静音时长,如果检测到静音超过这个时长则自动停止录音。
阻塞录音将在录音结束后返回结果。
返回值
terminator
:如果录音被打断,则返回相关按键。path
:文件路径。
Hangup
挂机。
flag
integer
值为0
:挂断自己1
:挂断对方2
:挂断双方
cause:挂机原因,参见
Dial
中相关定义。data:是一个对象,可以同时设置多个属性。如果挂机前需要设置 channel 变量,可以使用该字段。该字段设置后,会自动订阅,不需要再修改配置文件或者使用 SetVar 接口去专门订阅。可选。
uuid:当前通话的 UUID,必选。
例子:
{ "jsonrpc": "2.0", "method": "XNode.Hangup", "id": "fake-uuid-hangup", "params": { "flag": 0, "ctrl_uuid": "3ff4dbf3-9593-42f0-8454-8a65b574049e", "uuid": "06d9250c-20c6-4f5a-afbd-66b6822d7d61", "data": { "var1": "value1", "var2": "value2" } } }
ReadDTMF
播放一个语音并获取用户按键信息,将在收到满足条件的按键后返回。
min_digits
:最小位长。max_digits
:最大位长。timeout
:超时,默认5000ms
。digit_timeout
:位间超时,默认2000ms
。terminators
:结束符,如#
。media
: 播放的媒体,可以是语音文件或 TTS。type
:string
TEXT|SSML 当 type 为空时表示当前为语音文件data
:string
文本内容或 SSML 内容,type 为空时表示当前为语音文件,当表示为语音文件时,空值代表静音engine
:string
当 type 为 TEXT 或 SSML 时添加,TTS 引擎voice
:string
当 type 为 TEXT 或 SSML 时添加,TTS 发音人默认为 default
返回结果:
dtmf
:收到的按键。terminator
:结束符,如果有的话。
本接口将在收到第一个 DTMF 按键后打断当前的播放。
DetectSpeech
检测语音,可以同时检测 DTMF。如果不需要检测语音,仅检测 DTMF,请使用 ReadDTMF 接口。
media
:媒体,参见 Play。dtmf
:DTMF 参数,参见 ReadDTMF 中的定义,如果不需要同时检测 DTMF,可以不传该参数。speech
:对象,语音识别请求。
speech
定义:
engine
:字符串,ASR 引擎。no_input_timeout
:正整数,未检测到语音超时,默认为5000
ms。speech_timeout
:正整数,语音超时,即如果对方讲话一直不停超时,最大只能设置成6000
ms,默认为6000
ms。max_speech_timeout
:正整数,语音最大超时,和参数speech_timeout
作用相同,如果max_speech_timeout
的值大于speech_timeout
,则以max_speech_timeout
为主,用于一些特殊场景的语音时长设置。partial_events
:Bool,是否返回中间结果。有些引擎支持返回中间识别结果。以事件形式发出。nobreak
:Bool,禁止打断。用户讲话不会打断放音。放音期间识别到用户讲话的内容将全部缓存。多“句”话之间使用“。
”拼接成一个text
字段发出。其它字段如confidence
等将使用第一个返回的结果,可能没有代表性。merge_delimiter
:String,合并分隔符。暂未实现。默认为“。
”。在nobreak
状态下,如果需要拼接结果中插入分隔符。disable_detected_data_event
:Bool,默认会发送Event.DetectedData
事件,如果为true
则不发送。params
:不同引擎特定的参数,全部为字符串键值对,由具体的引擎定义。break_from_partial
:Bool,当收到 ASR 中间识别结果时开始打断。默认为false
,从begin-speaking
开始打断。不是所有的 ASR 引擎都支持begin-speaking
,调用方需要根据使用的 ASR 引擎决定是否开启该参数。break_delay
:正整数,打断延迟时间,单位为毫秒。检测到说话时,延迟指定时间后打断当前放音,默认立即打断。如果开启了break_from_partial
延迟时间从第一个 partial 开始计时,否则从begin-speaking
开始计时。break_ignore_regex
:字符串,打断时过滤掉的识别结果,可以过滤掉语气词等,防止过早的打断放音。比如"^(嗯|嗯。|啊|啊。)$"
或者"^嗯$|^嗯。$|^啊$|^啊。$"
,由于 ASR 引擎可能返回标点,正则中最好添加一份带标点的词。开启该参数会隐含启用break_from_partial
。该参数只会影响打断的行为,不会影响识别结果。
识别结果:
uuid
:当前 Channel 的 UUID。text
:识别到的文本。confidence
:double
类型,结果可信度,跟具体引擎相关。is_final
:是否是最终结果。engine_data
:ASR 引擎原生返回的数据,适用于可以进一步获取更多信息。error
:错误,如no_input
、speech_timeout
等。type
:结果类型,有DTMF
、Speech.Begin
、Speech.Partial
、Speech.End
,Speech.Merged
、ERROR
等。offset
:如果是文件播放过程中被打断,则该值为打断时的偏移量。可以在打断位置继续播放。
默认情况下,本接口将在第一时间检测到语音后打断当前的播放。可以通过 nobreak
来控制是否打断。
正常情况下,本接口会在检测到结果后返回,以便进行下一轮交互。
本接口也可以支持连续识别。如果在调用时不传任何media
参数,则会启动后台识别,识别到的结果以事件(Event.DetectedData
)形式发出。在连续识别过程中,可以继续进行放音操作。(本操作需要相应的后台设置)。
分段录音:
分段录音在 ASR 引擎上实现,因此做为引擎的参数(params
)传入。
segment-recording-prefix
:分段录音路径前缀,将与真正的文件名拼接。如果前缀是一个目录,必须以/
结尾,如/tmp/
,建议使用带时间戳的前缀,如/tmp/20200202-121212-
。文件名后半部分暂时使用引擎相关的唯一值,如阿里云的引擎中我们使用header.message_id
作为文件名。
媒体播放事件:
当指定 media
媒体参数时,语音播放结束后会以事件(Event.Play
)形式发出。
{ "jsonrpc": "2.0", "method": "Event.Play", "params": { "node_uuid": "c33213b3-2818-4772-84d7-2ee40ec89c8c", "action": "STOP", "uuid": "9ed13c24-2de5-4335-8c92-0cbbc2e30ca7", "type": "TEXT", "data": "您好,欢迎致电", "engine": "ali", "voice": "default", "id": "1", "break": true } }
uuid
:当前 Channel 的 UUID。action
:目前只有播放结束后才会触发该事件,固定为STOP
。type
:TEXT
或者FILE
,跟media
参数保持一致。data
:TTS 文本或者文件路径。id
:对应DetectSpeech
或者DetectSpeechFeedTTS
中的id
。engine
:TTS 引擎voice
:TTS 发音人break
:当前媒体的播放是否被打断。
Event.Play
事件目前只有 DetectSpeech
才会触发,正常的 Play
不会触发该事件。
DetectSpeechFeedTTS
在 DetectSpeech 执行的过程中补充新的 TTS。可用于在与 ChatGPT 对话的情况。ChatGPT 流式 API(stream=true
)会通过 SSE 渐进地返回结果。在实际使用时,可以根据标点符号将收到的结果切开,一句一句的把收到的文本内容喂给 DetectSpeech。DetectSpeech 会缓存收到的 TTS 内容,在下一次执行 DetectSpeech 前会丢弃所有以前收到的内容。建议使用该 API 时自己实现一个状态机,只有在 DetectSpeech 在执行的过程中才调用该接口,在其他情况下对该接口的调用会被忽略。
uuid
:当前通话 UUID。ctrl_uuid
:控制器 UUID。engine
:字符串,ASR 引擎。voice
:当前发音人噪音。text
:文本内容。preheat
:Bool,是否预热该文本,为true
时系统将提前缓存text
对应的语音,提升放音速度。
如果在调用本接口时 DetectSpeech 处于阻塞模式,则对于 C 语言可以在新线程中调用本接口,对于 Go 语言可以在新的 Go Routine 中调用本接口。
JSON示例:
{ "jsonrpc": "2.0", "method": "XNode.DetectSpeechFeedTTS", "params": { "ctrl_uuid": "c33213b3-2818-4772-84d7-2ee40ec89c8c", "uuid": "9ed13c24-2de5-4335-8c92-0cbbc2e30ca7", "text": "您好,欢迎致电", "engine": "ali", "voice": "default", "preheat": true } }
StopDetectSpeech
停止正在进行的 DetectSpeech。
uuid
:当前通话 UUID。ctrl_uuid
:控制器 UUID。
DetectFace
人脸识别接口。本接口将在后台启动一个 Media Bug。并将通话置于 Echo 状态(即客户会看到当前自己的人脸)。
在人脸识别过程中,每隔1.5
秒返回一张图片(PNG 格式经过 Base64 算法转成data-url
)。业务侧可以将图片传到外部人脸识别系统中进行比对。
相关接口参考:
uuid
:当前通话 UUID,必填。mask
:PNG 图片作为人脸型的框架,一般为透明图片,默认为/usr/local/freeswitch/images/mask.png
。action
:字符串。START
:开始。STOP
:结束。TEXT
:写文字。CLEAR
:清除文字。
如果action
为 TEXT,则有以下参数:
text
:文本font
:字体文件路径font_size
:字体大小(像素)fg_color
:前景色bg_color
:背景色
结果:
uuid
:UUIDpicture
:data-url 格式的字符串width
:图像宽度height
:图像高度
本接口为非阻塞接口,调用者在首次调用action = START
后,将收到code = 202
消息。然后调用者应该循环待,后续的结果中将有picture
返回,然后可以将picture
传给第三方接口进行比对或识别。识别完毕可以STOP
结束识别。
识别过程中,可以调用action = TEXT
在图片上添提提示文本(如请转头、请眨眼等)。
SendDTMF
uuid
:当前通话 UUID,必填。dtmf
:DTMF 字符串,必须是合法的 DTMF。
合法的 DTMF 如下:
0~9
:数字*
:星号键#
:井号键A~D
:特殊按键w
:停顿 500 毫秒W
:停顿 1 秒
SendInfo
uuid
:当前通话 UUID,必填。content_type
:可选,字符串,默认为text/plain
。data
:可选,字符串,默认为空字符串。
使用该功能需要设置通道变量fs_send_unsupported_info=true
,或直接开启全局的变量。
Dial
外呼。直接同时发起多个呼叫,其中任意一个接听后,其它的呼叫都将挂机。
ringall
:true
|false
。同振,默认为顺振。cancel_uuid
: 可选。任意非空,唯一的呼叫字符串(可以与uuid
相同),用于使用Cancel
接口取消呼叫。global_params
:FreeSWITCH 呼叫字符串{}
里的参数,作用于所有的腿,具体请参见 FreeSWITCH 中相关定义。call_params
:呼叫参数,是一个数组,数组中的每个对象都代表一条腿。所有的键和值都必须是字符串。
呼叫参数(call_params
)定义:
uuid
:新 Channel 的 UUID,必须由 Ctrl 生成,并且所有 Channel 生存周期内不能重复(建议永远不要重复),建议使用相关 UUID 算法生成。cid_number
:主叫号码。cid_name
:主叫名称。dial_string
:FreeSWITCH 原生呼叫字符串,如user/xxx
、sofia/gateway/gwx/xxxx
等。以后的版本中可以增加相关的对象代替 FreeSWITCH 原生的字符串。详情参阅附录中「呼叫字符串」部分。max_duration
: 最长通话时间,单位是秒。最小 60 秒,最长 24 _ 3600 秒,即 24 个小时,缺省值为 24 _ 3600 秒。params
:新 Channel 的相关参数,对应 FreeSWITCH 中呼叫字符串的[]
里面的定义,仅作用于这一条腿。此外的参数会被global_params
中的同名参数覆盖。所有params
键和值均是字符串形式,部分参数示例如下:leg_timeout
:呼叫超时时间,单位为秒。ignore_early_media
:是否忽略早期媒体,true
或false
。在PSTN呼叫场景中,一般会返回早期媒体(回铃音,对应SIP183
),Dial将在收到媒体后返回,以便进行下一步的动作。如果希望在对方应答后才返回,则该参数应该设为true
。xcc_no_cid_flip
:true
|false
,默认为false
。在呼叫应答中,XSwitch会自动反转主被叫号码,会造成话单中主被叫号码都相同。设为true
可以防止主被叫号码翻转。该参数影响呼叫进展事件以及话单中的主被叫号码。- 其他通话变量可以参见 https://rts.cn/docs/Channel-Variables-Catalog/ 。
外呼成功后,如果是同步请求,则可以直接返回结果,否则可以异步的获取结果,并等待有 Event.Channel(state = READY
)消息后开始下一步操作。
注意: 该命令会在成功收到媒体后返回,比如在 SIP 消息中,收到183
时就返回,以便进行后续的操作。如果需要在对方接听后返回,则可以使用ignore_early_media=true
参数。
呼叫过程中相应的呼叫进展后有相关的Event.Channel
事件发送到当前 Ctrl 上,如cn.xswitch.ctrl.<ctrl_uuid
>。
外呼的呼叫会自动接管,不需要发送Accept
。
外呼的结果中cause
为成功或失败原因,列表如下:
SUCCESS
:成功,可以进行下一步操作。USER_BUDY
:被叫忙。CALL_REJECTED
:被叫拒接。NO_ROUTE_DESTINATION
:找不到路由。
更多定义参见常用挂机原因说明。
JSON 示例:
{ "jsonrpc": "2.0", "method": "XNode.Dial", "id": "call1", "params": { "ctrl_uuid": "950e1501-577d-41e8-9123-fce9fe8e0aef", "sync": true, "destination": { "ringall": true, "global_params": { "ignore_early_media": "true" }, "call_params": [ { "uuid": "efed526f-4851-4c30-80f5-cf442e7dd750", "dial_string": "user/1000", "cid_name": "Test-Call", "cid_number": "10000210" }, { "uuid": "b13975dd-eb27-41d8-a8bc-114dc8ecff2e", "dial_string": "sofia/gateway/test/1000", "cid_name": "Test-Call2", "cid_number": "100002102", "params": { "leg_timeout": "20", "ignore_early_media": "true" } } ] } } }
当 SIP 和 WebRTC 分机注册同一分机号时,如果使用user/分机号
形式,则在 XSwitch 中,当分机类型为 SIP 时,只有 SIP 分机振铃,如果有多个 SIP 设备注册同一分机号且在 SIP Profile 中开启了 SIP 分机,则所有 SIP 分机会同振。
如果想让 SIP 和 WebRTC(Verto)分机同振,则可以将分机类型设为WebRTC
。
如果想让 SIP 和 WebRTC 分机顺振,可以使用如下方式:
ringall: false
- 添加两个 CallParam,分别使用
find_sip_device_only
和find_webrtc_device_only
参数限制相应的振铃分机。
示例如下:
{ "jsonrpc": "2.0", "method": "XNode.Dial", "id": "call1", "params": { "ctrl_uuid": "79fc27d8-90fe-4696-a424-9575c74411a7", "sync": true, "destination": { "ringall": false, "global_params": { "ignore_early_media": "true" }, "call_params": [ { "uuid": "1d23b703-25b3-4c5e-8933-46e15482dd5e", "dial_string": "user/1022", "cid_name": "Test-Call", "cid_number": "10000210", "params": { "leg_timeout": "20", "find_sip_device_only": "true" } }, { "uuid": "2a9c4ef2-fad2-49ed-8646-c4b3521502a5", "dial_string": "user/1007", "cid_name": "Test-Call2", "cid_number": "100002102", "params": { "leg_timeout": "20", "find_webrtc_device_only": "true" } } ] } } }
对于顺振的呼叫,可以使用 Cancel
接口取消正在进行(未接听)的呼叫。
Cancel
取消由 Dial 发起的未接听的呼叫。
cancel_uuid
:与Dial
中的cancel_uuid
对应,取消正在进行的呼叫。
在使用 Dial 使用顺振模式同时呼叫多个号码的情况下,可以使用该接口取消未接听的呼叫(后面未拨打的部分将不再拨打)。
注意:由于存在竞争条件(Race Condition),在调用该接口时,可能在调用的瞬间呼叫被接听,此时该接口无效,已被接听的呼叫应该使用 Hangup
或 uuid_hangup
挂机。
Log
日志打印。
通过调用本接口可实现在 XSwitch 内打印想要输出的日志信息。该接口不依赖于通话,可在任意处进行调用。
level
:日志级别。字符串类型。可从以下级别中任选其一。默认为DEBUG
。- DISABLE
- CONSOLE
- ALERT
- CRIT
- ERR
- WARNING
- NOTICE
- INFO
- DEBUG
function
:调用该接口代码所在函数名称。file
:调用该接口代码所在文件名称。line
:调用该接口代码行数。整型。log_uuid
:任意字符串。可选。建议为当前通话UUID
。data
:想要打印的日志信息。
注意,以上六个参数中,只有log_uuid
为可选参数,其他均为必填
JSON 示例:
{ "jsonrpc": "2.0", "method": "XNode.Log", "params": { "ctrl_uuid": "f8a02eed-3ea6-42a2-838d-856f529d3fbc", "level": "ALERT", "function": "xnode_status", "file": "log.js", "log_uuid": "", "line": 69, "data": "Hello, this is a test" }, "id": "fake-log" }
XSwitch 内日志打印如下: 2022-07-14 13:04:07.427643 98.80% [ALERT] log.js:69 Hello, this is a test
StartDTMF
开启带内 DTMF 检测。
force
:可选参数,是否强制开启带内 DTMF 检测。
本接口将可能或者强制开启带内 DTMF 检测。使用本接口时,如果不带force
参数或者其值为flase
的情况下,只有实际通话协商 DTMF 不是 2833 的情况下,才会开启带内 DTMF 检测,因为对于大部分通话来说,DTMF 都是 2833,这种情况是没必要开启带内检测的,如果开启会增加相应的 CPU 开销。当参数force
值为true
时,将强制开启带内 DTMF 的检测,因此一般情况下不建议开启此参数。
Bridge
将当前通话桥接(发起)另一个呼叫。
该功能会发起一个新的呼叫(在a-leg
的基础上创建b-leg
)。呼叫参数与Dial
相同。a-leg
会听到b-leg
的回铃音。也可以通过ignore_early_media=true
参数抵制回铃音。
flow_control
:呼叫控制,跟程控交换机中的控制方式类似,略有不同。NONE
:互不控制,任意方挂机不影响其它一方CALLER
:主叫控制,a-leg
挂机后b-leg
自动挂机CALLEE
:被叫控制,b-leg
挂机后a-leg
自动挂机ANY
:主被叫控制,任一方挂机后另一方也挂机
continue_on_fail
:字符串类型。该参数控制在 Bridge 失败的情况下的逻辑。如果 Bridge 失败(如空号、被叫忙等),则是否继续:true
:继续,继续保持 PARK 状态false
:挂机USER_BUSY,NO_ANSWER...
:逗号分隔的字符串列表,如果遇到列表中的挂机原因则继续(即白名单),否则会自动挂机。
Bridge 会成桥接成功或失败后返回。什么是桥接成功呢?桥接成功以收到b-leg
的媒体为准,即: - 如果没有ignore_early_media
参数,则在b-leg
应答后(收到200 OK
)返回。 - 如果有ignore_early_media
参数,则在b-leg
返回媒体时(收到带 SDP 的183
)返回(注:有的180
消息里也有 SDP,会当作 183 处理)。
Bridge 失败的原因有对方线路故障、对方忙、拒接等。注意:在 PSTN 或 IMS 线路中,如果对方忙等情况,PSTN 线路会返回带 SDP 的183
消息,返回语音如“您拨打的号码正在通话中,请稍后再拨……”,这时候,在没有ignore_early_media
的情况下,会认为是桥接成功。而如果加了ignore_early_media
参数,则主叫无法听到回铃音(因为被忽略了)。
总之,桥接成功的标志是收到b-leg
的媒体,不管是早期媒体还是应答后的媒体。如果有ignore_early_media
参数,则早期媒体被忽略,以应答后的媒体为准。一般的 SIP 话机都不会返回早期媒体(返回不带 SDP 的180 RINGING
)消息。所谓媒体是以 SIP 消息中的媒体描述为准(即 SDP),而不是真正收到 RTP 媒体。
在实际使用时,如果在桥接成功后需要播放提示音,可以在桥接成功后调用Play
接口,也可以调在 Bridge 时通过以下通道变量使用底层的机制直接播放,如:
以下参数可以设到a-leg
和/或b-leg
上:
execute_on_answer=playback:/tmp/test.wav
:在应答后播放提示音。
以下参数设到a-leg
上(如使用SetVar
):
bridge_pre_execute_aleg_app
:在a-leg
应答执行 App,如playback
。bridge_pre_execute_aleg_data
:在a-leg
应答执行 App 的参数,如/tmp/test.wav
。bridge_pre_execute_bleg_app
:在b-leg
应答执行 App,如playback
。bridge_pre_execute_bleg_data
:在b-leg
应答执行 App,如/tmp/test.wav
。
详见 XSwitch 底层 App 及通道变量相关文档。
ChannelBridge
桥接两个uuid
,两个 Channel 必须为未 Bridge 状态,且处于 PARK 状态(没有执行其它 App)。 当 unbridge 之后返回这个 api 调用的回复消息。
uuid
:当前uuid
,为a-leg
。peer_uuid
:对方uuid
,为b-leg
。flow_control
:桥接成功后是否自动挂机,参见 Bridge 中相关定义。
ChannelBridge2
桥接两个uuid
,两个 Channel 必须为未Bridge
状态,且处于PARK
状态(没有执行其它 App)。 当桥接完成后马上返回 api 调用的回复消息
- 参数与 ChannelBridge 相同
UnBridge
A 与 B 通话中。将 A 与 B 分离,分别 park。
Hold
将通话置于保持状态。
内部要在controller
中记住状态。
Unhold
解保持,清除保持状态。
Transfer
转移,重路由。如果当前uuid
只有一路通话,则根据将通话转移到呼叫源为context
且被叫字冠为extension
的自定义路由内。
如果当前uuid
处于 Bridge 状态,则另一条腿可能会自动挂断或被置于 PARK 状态(取决于之前的设定),然后再转移到自定义路由内。
示例如下:
extension
:被叫号码,对应为路由界面被叫字冠dialplan
:此处固定为XML
context
:呼叫源,对应为路由界面呼叫源
{ "jsonrpc": "2.0", "method": "XNode.Transfer", "id": "transfer_id", "params": { "ctrl_uuid": "41f54dd7-dedb-452b-956f-86c911f62dc6", "uuid": "f6f8a912-3757-469c-a14f-bd512e51ad5b", "extension": "9196", "dialplan": "XML", "context": "context-1" } }
注意:当前uuid
会重新进入 Dialplan 进入路由流程,同时 XCC 会失去控制权,路由流程可能会路由到另一个目的地,也可能通过另一个xcc
命令重新进入xcc
的控制流程(这时在控制侧可以当成一路新通话处理)。
ThreeWay
三方。A 与 B 通话,用 Dial 呼叫 C 或 C 呼入,然后通过该 API 建立三方。其中uuid
为 C,target_uuid
为 A 或 B。
direction
有以下取值(下文中,C 为uuid
,A 为target_uuid
,B 为target_uuid
的对端):
LISTEN
:监听模式,C 能听到 A 和 B,A 和 B 听不到 CABC
:三方模式,三方互相能听到其它两方,A 或 B 挂机后,全部挂机,C 挂机不影响 A 和 BABC3
:功能同ABC
,不同的是三方中任意成员挂机不影响其他,当只剩一个成员时,会自动挂机AC
:A 与 C 通,B 听 MOHBC
:B 与 C 通,A 听 MOHTOA
:C 听 AB,A 听 BC,B 听 A,即 A 与 B 正常通话,但 C 可以单独跟 A 讲话(耳语)TOB
:C 听 AB,B 听 AC,A 听 B,即 A 与 B 正常通话,但 C 可以单独跟 B 讲话(耳语)ACOB
:C 和 A 正常通话,B 只能听 A 和 C 的讲话,A 和 C 听不到 B 的讲话,A 和 C 任意一方挂机,整个通话结束,B 挂机,不影响 A 和 C 的通话,通常用于坐席抢话业务STOP
:停止三方
message ThreeWayRequest { Ctrl ctrl_uuid = 1; string uuid = 2; string target_uuid = 3; string direction = 4; string mode = 5; string conf_profile = 6; }
说明:direction
为ABC
时,可以搭配mode
参数,值为conference
,效果等同于ABC3
,本质上都是会议模式,建议使用ABC3
,mode 模式后续将会被淘汰。
conf_profile
参数在 direction 为ABC3
或ABC
搭配 mode 为conference
的情况下使用(也就是会议模式下的可选参数),为会议 profile 的名字,缺省值为default
。
在 ThreeWay 的过程中,如果初始化状态为LISTEN
或ABC
模式(其它状态无法自由转换),可以传入不同的direction
并改变通话逻辑。如,最开始使用LISTEN
模式兼听,然后改成使用TOA
模式跟 A 耳语,然后改成ABC
模式三方,最后STOP
停止。
Intercept
强插。A 与 B 通话中。C 呼入或者通过 Dial 呼通 C,uuid
为 C,然后target_uuid
为 A 或 B,建立通话后挂掉另一方。
message InterceptRequest { Ctrl ctrl_uuid = 1; string uuid = 2; string target_uuid = 3; }
Echo2
在通话中听到自己发出的声音。
action
:START
(默认) |STOP
,开始或停止direction
:SELF
(默认)|OTHER
,听到自己的声音,或让对方听到自己的声音。
Mute
静音,在通话中静音
参数:
uuid
: 当前 session a-leg 的 uuiddirectionn
:静音方向。WRITE
:静音 a-leg 发送出去的声音;READ
:静音 b-leg 发送过来的声音;BOTH
:静音 a-leg 和 b-leg。level
:integer
,0
非静音,1
静音,大于 1 静音并发送舒适噪声数值代表舒适噪音的音量。flag
: media bug 插入顺序,FIRST
代表插入到最头上,LAST
代表插入到最尾。
WaterMark
通话过程中添加水印。
参数:
action
:START
|STOP
|RESTART
,增加水印,移除水印及覆盖水印marked_text
:文字水印,显示在左上角marked_with_time
:时间水印,显示在左上角marked_fsize
:水印字体大小marked_fcolor
:水印字体颜色marked_fface
:水印字体,默认为 FreeMonomarked_file
:文件水印,通常是图片marked_file_mode
:文件水印显示模式 -logo
:显示在右下角,长宽占比不超过 1/4 -bottom
:靠下侧居中显示 -top
:靠上侧居中显示 -custom
:自定义marked_file_alpha
:true
|false
,水印显示是否使用透明模式marked_abs_x
:文件水印自定义模式的横坐标marked_abs_y
:文件水印自定义模式的纵坐标
SetVar
设置通道变量(随路路数据),变量一经设置后在 Channel 生命周期内会一直有效。
参数:
uuid
:当前 Channel 的的 UUIDdata
:数据,是一个对象,可以同时设置多个属性。channel_params
:字符串数组,同时订阅这些变量,以便以后的 Event.Channel 事件中携带。
如:
{ "method": "XNode.SetVar", "params": { "data": { "var1": "value1", "var2": "value2" }, "channel_params": ["var1", "var2", "source", "context"] } }
其中、data
和channel_params
参数都是可选的这样设计的原因是可以在设置通道变量的同时进行订阅,而不需要再使用一个 API 订阅一次。如果只想订阅通道变量而不设置,则可以省略data
参数。
GetVar
获取通道变量(随路路数据)。如果想临时获取一些通道变量,可以使用本函数。
FIFO
呼叫中心 FIFO 队列(先入先出)。
参数:
uuid
:当前 Channel 的 UUIDname
:队列名字inout
:in
|out
,入队列或出队列wait_music
:进去队列等待音exit_announce
:分配到坐席后退出队列提示音priority
:优先级,0 到 9,0 优先级最高,默认 0
Callcenter
呼叫中心 Callcenter。
参数:
uuid
:当前 Channel 的 UUIDname
:队列名字
Conference
会议。
参数:
uuid
:当前 Channel 的 UUIDname
:会议名称profile
:会议模板,默认default
flags
:入会 flags,字符串数组
JSON 示例:
{ "jsonrpc": "2.0", "id": "fake-id", "method": "XNode.Conference", "params": { "uuid": "some-uuid", "name": "3000", "profile": "example", "flags": ["mute", "vmute", "deaf", "moderator", "mintwo"] } }
注意:由于设计原理不同,上述接口实现的会议可使用 NativeAPI conference <conf-name> hangup [<member_id>|all]
将通话挂断,但无法使用 NativeAPI conference <conf-name> hup [<member_id>|all]
将通话挂断。
AI
参数:
uuid
:当前 Channel 的 UUIDurl
:应用服务器 URLdata
:随路数据,是一个对象,会全部发送至应用服务器,仅支持字符串
JSON 示例:
{ "jsonrpc": "2.0", "id": "fake-id", "method": "XNode.AI", "params": { "uuid": "some-uuid", "url": "http://localhost:3000", "data": { "var1": "value1", "var2": "value2" } } }
HttAPI
参数:
uuid
:当前 Channel 的 UUIDurl
:应用服务器 URLdata
:随路数据,是一个对象,会全部发送至应用服务器,仅支持字符串
JSON 示例参考 AI。
Lua
参数:
uuid
:当前 Channel 的 UUIDscript
:Lua 脚本
TTSPreheat
语音合成 TTS 预热,提前把文本缓存成语音文件,提升播放速度。
参数:
engine
:TTS 引擎voice
:发音人data
:字符串数组,需要预热的文本,每个对象都会被缓存为一个文件
注意:对应的 TTS 模块需要开启 cache 功能。引擎、发音人和文本只要一个不相同都会被缓存为新的文件。
JSON 示例:
{ "jsonrpc": "2.0", "id": "fake-id", "method": "XNode.TTSPreheat", "params": { "engine": "ali", "voice": "default", "data": [ "您好,欢迎致电xxx", "这里是xxx", "我们这里xxxx" ] } }
FreeSWITCH 原生 API
系统提供执行 FreeSWITCH 原生 API 的能力,用于在 XCC API 不够用的情况下使用。如果某 NativeApi 使用频繁,建议包装成 XCC API。
- NativeAPI:可执行所有的 FreeSWITCH 原生的 API
- NativeApp:可执行所有的 FreeSWITCH 原生的 App
- NativeJSAPI:可执行所有的 FreeSWITCH 原生的 JSON API
NativeAPI
message NativeRequest { string ctrl_uuid = 1; string cmd = 2; string args = 3; }
cmd
:FreeSWITCH 原生命令,如status
、sofia
等args
:FreeSWITCH 命令参数,如status
命令没有参数,可以为空,sofia
命令的参数status
等。
NativeApp
message NativeRequest { string ctrl_uuid = 1; string cmd = 2; string args = 3; string uuid = 4; }
cmd
:FreeSWITCH 原生 App,如answer
、echo
、conference
等args
:FreeSWITCH 命令参数,如echo
命令没有参数,可以为空,conference
的参数可以是一个会议室名称,如3000
。
NativeJSAPI
message NativeJSRequest { string ctrl_uuid = 1; message NativeJsData { string command = 1; // a string or a native JSON struct to google.protobuf.Any or .Struct string data = 2; } NativeJsData data = 2; }
原生的 JSAPI。
command
:JSAPI 命令,如conferenceInfo
data
:JSAPI 命令参数,可以是字符串形式,也可以是 JSON 形式,必须是一个 Object,如:{}
示例请求:
{ "jsonrpc": "2.0", "id": "status", "method": "XNode.NativeJSAPI", "params": { "ctrl_uuid": "test-nodejs-controller", "data": { "command": "status", "data": {} } } }
响应:
{ "jsonrpc": "2.0", "id": "status", "result": { "code": 200, "message": "OK", "node_uuid": "xcc-node-1", "data": { "systemStatus": "ready", "uptime": { "years": 0, "days": 0, "hours": 2, "minutes": 54, "seconds": 23, "milliseconds": 607, "microseconds": 581 }, "version": "1.10.7-dev git b208d55 2021-06-15 03:52:14Z 64bit", "sessions": { "count": { "total": 5, "active": 0, "peak": 1, "peak5Min": 0, "limit": 20000 }, "rate": { "current": 0, "max": 20000, "peak": 1, "peak5Min": 0 } }, "idleCPU": { "used": 0, "allowed": 95.36666666666666 }, "stackSizeKB": { "current": 240, "max": 8192 } } } }
Shutdown
节点关闭
该接口可以优雅的控制 FreeSWITCH 节点的关闭,该接口不受通话影响,调用此接口之后,该 FreeSWITCH 将不会收到新的呼叫请求,但对于正在进行的通话不受影响,等所有通话结束后,FreeSWITCH 节点将会被 Shutdown。可用于处理故障的节点或者升级节点等场景操作。为了安全起见,该接口会做校验检查,当请求参数中的node_uuid
符合本节点的节点 id 后,才会处理该请求。
JSON 示例:
{ "jsonrpc": "2.0", "method": "XNode.Shutdown", "params": { "node_uuid": "node-uuid-test" }, "id": "fake-node-shutdown" }