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:字符串,语音文件或 TTS
  • engine:字符串,TTS 引擎,目前支持华为、讯飞、阿里、百度等。
  • voice:字符串,嗓音,由 TTS 引擎决定,默认为default
  • loop:正整数,重复次数,暂未实现。
  • offset:正整数,语音文件播放偏移量。以采样点为单位,如文件采样率为8000,则偏移80001秒。暂仅支持单个文件。对于file_string类型只对第一个文件起作用。
  • record: 录音设置参数,可选,值为IGNORE_READ(大小写不敏感),打开record后,如果放音的腿上开启了录音,放音开始后,录音文件里将只写入该放音的声音文件数据,不再写入收到的其他数据,放音结束后,录音数据写入将自动恢复正常,和Broadcast 接口record参数作用相同。

record参数举例说明:如果 a 和 b 在通话,a 开启了录音,a 调用Play接口放音,在不开启record参数的情况下,a 的录音文件中放音部分的数据,除了放音文件的声音,还同时会写入用户 a 自己的声音,这样会影响有些客户的录音质检,打开record参数则可以解决这一问题。

其中enginevoice为 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_STARTRECORD_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:正整数,未检测到语音超时,默认为5000ms。
  • speech_timeout:正整数,语音超时,即如果对方讲话一直不停超时,最大只能设置成6000ms,默认为6000ms。
  • 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:识别到的文本。
  • confidencedouble类型,结果可信度,跟具体引擎相关。
  • is_final:是否是最终结果。
  • engine_data:ASR 引擎原生返回的数据,适用于可以进一步获取更多信息。
  • error:错误,如no_inputspeech_timeout等。
  • type:结果类型,有DTMFSpeech.BeginSpeech.PartialSpeech.EndSpeech.MergedERROR等。
  • 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
  • typeTEXT 或者 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:文本内容。

接口数据格式

如果在调用本接口时 DetectSpeech 处于阻塞模式,则对于 C 语言可以在新线程中调用本接口,对于 Go 语言可以在新的 Go Routine 中调用本接口。

StopDetectSpeech

停止正在进行的 DetectSpeech。

  • uuid:当前通话 UUID。
  • ctrl_uuid:控制器 UUID。

DetectFace

人脸识别接口。本接口将在后台启动一个 Media Bug。并将通话置于 Echo 状态(即客户会看到当前自己的人脸)。

在人脸识别过程中,每隔1.5秒返回一张图片(PNG 格式经过 Base64 算法转成data-url)。业务侧可以将图片传到外部人脸识别系统中进行比对。

相关接口参考:

如果action为 TEXT,则有以下参数:

  • text:文本
  • font:字体文件路径
  • font_size:字体大小(像素)
  • fg_color:前景色
  • bg_color:背景色

结果:

  • uuid:UUID
  • picture: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。同振,默认为顺振。
  • global_params:FreeSWITCH 呼叫字符串{}里的参数,作用于所有的腿,具体请参见 FreeSWITCH 中相关定义。
  • call_params:呼叫参数,是一个数组,数组中的每个对象都代表一条腿。所有的键和值都必须是字符串。

呼叫参数定义:

  • uuid:新 Channel 的 UUID,必须由 Ctrl 生成,并且所有 Channel 生存周期内不能重复(建议永远不要重复),建议使用相关 UUID 算法生成。
  • cid_number:主叫号码。
  • cid_name:主叫名称。
  • dial_string:FreeSWITCH 原生呼叫字符串,如user/xxxsofia/gateway/gwx/xxxx等。以后的版本中可以增加相关的对象代替 FreeSWITCH 原生的字符串。详情参阅附录中「呼叫字符串」部分。
  • max_duration: 最长通话时间,单位是秒。最小 60 秒,最长 24 _ 3600 秒,即 24 个小时,缺省值为 24 _ 3600 秒。
  • params:新 Channel 的相关参数,对应 FreeSWITCH 中呼叫字符串的[]里面的定义,仅作用于这一条腿。此外的参数会被global_params中的同名参数覆盖。

外呼成功后,如果是同步请求,则可以直接返回结果,否则可以异步的获取结果,并等待有 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_onlyfind_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"
          }
        }
      ]
    }
  }
}

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的控制流程(这时在控制侧可以当成一路新通话处理)。

TransferTo

转移。如果当前uuid只有一路通话,则直接 Bridge destination,跟 Bridge 一样处理。

如果当前uuid处于 Bridge 状态,则挂断peer_uuid,然后执行 Bridge。

message TransferRequest {
	Ctrl ctrl_uuid = 1;
	string uuid = 2;
	string ringback = 3;
	Destination destination = 4;
}

注意:在呼叫流程上与上面的 Transfer 或 NativeAPI uuid_transfer 不同。前面两者作用是转入 Dialplan 进行处理。而 TransferTo 与 Bridge 处理流程一致,直接将uuid对应通话转接到destination。如果uuid是单腿的通道,会直接转走,如果原先处于与另一条腿(peer_uuid)的桥接状态,则另一条腿可能会自动挂断或被置于 PARK 状态(取决于之前的设定)。

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 听不到 C
  • ABC:三方模式,三方互相能听到其它两方,A 或 B 挂机后,全部挂机,C 挂机不影响 A 和 B
  • ABC3:功能同ABC,不同的是三方中任意成员挂机不影响其他,当只剩一个成员时,会自动挂机
  • AC:A 与 C 通,B 听 MOH
  • BC:B 与 C 通,A 听 MOH
  • TOA: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;
}

说明:directionABC时,可以搭配mode参数,值为conference,效果等同于ABC3,本质上都是会议模式,建议使用ABC3,mode 模式后续将会被淘汰。

conf_profile参数在 direction 为ABC3ABC搭配 mode 为conference的情况下使用(也就是会议模式下的可选参数),为会议 profile 的名字,缺省值为default

在 ThreeWay 的过程中,如果初始化状态为LISTENABC模式(其它状态无法自由转换),可以传入不同的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

在通话中听到自己发出的声音。

  • actionSTART(默认) | STOP,开始或停止
  • directionSELF(默认)| OTHER,听到自己的声音,或让对方听到自己的声音。

Mute

静音,在通话中静音

参数:

  • uuid: 当前 session a-leg 的 uuid
  • directionn:静音方向。WRITE:静音 a-leg 发送出去的声音;READ:静音 b-leg 发送过来的声音;BOTH:静音 a-leg 和 b-leg。
  • level: integer0 非静音,1 静音,大于 1 静音并发送舒适噪声数值代表舒适噪音的音量。
  • flag : media bug 插入顺序, FIRST代表插入到最头上,LAST代表插入到最尾。

WaterMark

通话过程中添加水印。

参数:

  • actionSTART | STOPRESTART,增加水印,移除水印及覆盖水印
  • marked_text:文字水印,显示在左上角
  • marked_with_time:时间水印,显示在左上角
  • marked_fsize:水印字体大小
  • marked_fcolor:水印字体颜色
  • marked_fface:水印字体,默认为 FreeMono
  • marked_file:文件水印,通常是图片
  • marked_file_mode:文件水印显示模式 - logo:显示在右下角,长宽占比不超过 1/4 - bottom:靠下侧居中显示 - top:靠上侧居中显示 - custom:自定义
  • marked_file_alphatrue | false,水印显示是否使用透明模式
  • marked_abs_x:文件水印自定义模式的横坐标
  • marked_abs_y:文件水印自定义模式的纵坐标

SetVar

设置通道变量(随路路数据),变量一经设置后在 Channel 生命周期内会一直有效。

参数:

  • uuid:当前 Channel 的的 UUID
  • data:数据,是一个对象,可以同时设置多个属性。
  • channel_params:字符串数组,同时订阅这些变量,以便以后的 Event.Channel 事件中携带。

如:

{
  "method": "XNode.SetVar",
  "params": {
    "data": {
      "var1": "value1",
      "var2": "value2"
    },
    "channel_params": ["var1", "var2", "source", "context"]
  }
}

其中、datachannel_params参数都是可选的这样设计的原因是可以在设置通道变量的同时进行订阅,而不需要再使用一个 API 订阅一次。如果只想订阅通道变量而不设置,则可以省略data参数。

GetVar

获取通道变量(随路路数据)。如果想临时获取一些通道变量,可以使用本函数。

FIFO

呼叫中心 FIFO 队列(先入先出)。

参数:

  • uuid:当前 Channel 的 UUID
  • name:队列名字
  • inoutin | out,入队列或出队列
  • wait_music:进去队列等待音
  • exit_announce:分配到坐席后退出队列提示音
  • priority:优先级,0 到 9,0 优先级最高,默认 0

Callcenter

呼叫中心 Callcenter。

参数:

  • uuid:当前 Channel 的 UUID
  • name:队列名字

Conference

会议。

参数:

  • uuid:当前 Channel 的 UUID
  • name:会议名称
  • 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 的 UUID
  • url:应用服务器 URL
  • data:随路数据,是一个对象,会全部发送至应用服务器,仅支持字符串

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 的 UUID
  • url:应用服务器 URL
  • data:随路数据,是一个对象,会全部发送至应用服务器,仅支持字符串

JSON 示例参考 AI。

Lua

参数:

  • uuid:当前 Channel 的 UUID
  • script: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 原生命令,如statussofia
  • args:FreeSWITCH 命令参数,如status命令没有参数,可以为空,sofia命令的参数status等。

NativeApp

message NativeRequest {
  string ctrl_uuid = 1;
  string cmd = 2;
  string args = 3;
  string uuid = 4;
}
  • cmd:FreeSWITCH 原生 App,如answerechoconference
  • 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"
}
XCC入门