AIAPI开发文档
简介
本手册提供 XSwitch AIAPI 运行说明,帮助开发者体验 AIAPI 流程,供使用 AIAPI 进行开发的开发者参考。
AIAPI 由mod_ai
模块实现。参见: https://git.xswitch.cn/xyt/mod_ai
原理
呼入和呼出流程中最主要的部分都是 XSwitch 通过 mod_ai 向指定的地址发送 POST 请求,HTTP 服务器接收到请求后需要返回相应的 JSON 告诉 XSwitch 下一步怎么处理。其中呼入流程为用户呼叫 XSwitch,通过 mod_ai 向服务器请求服务并处理后续;而呼出流程则为服务器通过 JSON-RPC 调用 XSwitch 向用户发起呼叫,呼叫接通后再向服务器请求服务并处理后续。详细交互流程可参考protocol
快速入门
呼入流程
启动 HTTP 服务
服务器代码及启动命令请参考附件 HTTP 服务代码示例。注:服务器示例代码中调用的 AI 引擎为mod_ali
,可根据实际需要更换。
XSwitch 配置
需要加载 TTS/ASR 模块,如
mod_ali
等 AI 模块XSwitch 界面上新建路由:【呼叫】⇨【路由】⇨【新建】
其他属性如【被叫字冠】等按需要设定,其中【目的地类型】选择【系统】,输入如下内容:
answer ai {url=http://192.168.1.25:9393/asr_test}
注:其中的
url
是指定的 HTTP 服务器地址,指向下文中示例服务器代码运行的地址
操作流程
用户客户端呼叫指定的【被叫字冠】即可。
预期流程
- 用户拨打被叫字冠呼入指定路由,通话接通后 XSwitch 向接收到的路由中
url
指定的 HTTP 服务器的url/asr_test
接口发送请求,HTTP 服务器接收到请求后向 XSwitch 发送动作指令play
播放:say:尊敬的客户,您好,请说一句话
,XSwitch 接收到动作指令后会调用 TTS 合成并播放给客户端,此时客户端用户听到尊敬的客户,您好,请说一句话
这句 TTS 合成音; - 之后 XSwitch 调用 ASR 接口等待用户说话,用户说完一句话后,XSwitch 会将 ASR 分析的结果发送到上次动作指令中附带的 url 地址
url/asr_result
接口,url/asr_result
接口根据接收到的 ASR 分析结果拼接文本,并向 XSwitch 发送动作指令播放分析结果,XSwitch 接收到指令后执行完并向客户端播放,此时客户端会听到 TTS 合成音:您说的是+ASR分析结果
或者没有收到分析结果的时候为对不起,我没听清您说什么
- 之后 XSwitch 会发送请求到
url/asr_result
接口返回的指令里url
中指向的url/hangup
接口,服务器接收到请求后向 XSwitch 发送动作指令:hangup
,之后通话挂断。
呼出流程
呼出流程也是通过 HTTP 接口实现,此时,HTTP 服务器需要向 XSwitch 发送附带通话信息的请求。呼出的请求分ai.dial
和ai.dial2
两种,前者适用于发起单独一路呼叫,呼叫后成功后再转接到服务的场景,后者适用于同时发起两路呼叫并桥接。
启动 HTTP 服务
服务器代码及启动命令请参考附件 HTTP 服务代码示例。
XSwitch 配置
- 需要加载 TTS/ASR 模块,如
mod_ali
等 AI 模块 - 配置需要呼叫的用户,需要外呼网关的需要额外设置
ai.dial
操作流程
这里使用 postman 模拟 HTTP 服务器向 XSwitch(一般端口为 8081,url 为v1
)发送 POST 请求调用ai.dial
方法:
POST http://192.168.1.25:8081/v1 Content-Type:application/json X-XTRA-AUTH-ID:309fd439-4e79-4b26-a911-735e6204b187 { "jsonrpc": "2.0", "method": "ai.dial", "id": 1, "params": { "application": "ai", "from": "8888", "dial_string": "user/1011", "url": "http://192.168.1.25:9393/asr_test", "private_data": { "param1": "1", "seq": "2" } } }
参数说明:
jsonrpc
:"2.0",请求 JSONRPC 请求 body 的固定格式method
:请求的 JSONRPC 方法id
:请求序列 id,此处模拟自己指定。实际应用中应由服务器生成application
:呼叫成功后 XSwitch 执行的 applicationfrom
:主叫显示的号码dial_string
:呼叫字符串,可以指定呼叫的用户。说明:如果需要呼叫外线,可在
dial_string
中包含网关和被叫号码名称,如"dial_string": "gateway/vos/95555"
可以与
user_gateway
,outbound_gateway
替换使用,即三种参数选一种生效,用以适应不同呼叫场景:指定
user_gateway
呼叫 user: 需要注意的是, 这里 to 和 user_gateway 的内容需要一致,不再需要指定dial_string
"from": "8888", "user_gateway": "1001", "to":"1001",
指定
outbound_gateway
呼叫外线:outbound_gateway
指定网关名称,to
指定被叫号码,此时同样不再需要指定dial_string
"from": "8888", "to": "95555", "outbound_gateway": "vos",
url
:呼叫接通后请求服务的地址private_data
:服务器指定的随路数据
预期流程
postman 模拟发送请求后:
- XSwitch 接收并分析指令,根据
method
指定的方法调用ai.dial
发起外呼请求,此时请求中dial_string
指向的用户分机响铃; - 通话接通后 XSwitch 向接收到的指令中
url
指定的 HTTP 服务器的url/asr_test
接口发送请求,HTTP 服务器接收到请求后向 XSwitch 发送动作指令play
播放say:尊敬的客户,您好,请说一句话
,XSwitch 接收到动作指令后会调用 TTS 合成并播放给客户端,此时客户端用户听到尊敬的客户,您好,请说一句话
这句 TTS 合成音; - 之后 XSwitch 调用 ASR 接口等待用户说话,用户说完一句话后,XSwitch 会将 ASR 分析的结果发送到上次动作指令中附带的 url 地址
url/asr_result
接口,url/asr_result
接口根据接收到的 ASR 分析结果拼接文本,并向 XSwitch 发送动作指令播放分析结果,XSwitch 接收到指令后执行完并向客户端播放,此时客户端会听到 TTS 合成音:您说的是+ASR分析结果
或者没有收到分析结果的时候为对不起,我没听清您说什么
- 之后 XSwitch 会发送请求到
url/asr_result
接口返回的指令里url
中指向的url/hangup
接口,服务器接收到请求后向 XSwitch 发送动作指令:hangup
,之后通话挂断。
ai.dial2
案例一:呼叫 dial_string(user/1001),成功后再 transfer 到 to (19999)
新建路由
XSwitch 界面上新建路由:【呼叫】⇨【路由】⇨【新建】
【被叫字冠】设置为
19999
,其中【目的地类型】选择【系统】,输入如下内容:answer sleep 1000 playback welcome.wav
注:需要确保 welcome.wav 文件路径存在音频文件
操作流程
这里使用 postman 模拟 HTTP 服务器向 XSwitch(一般端口为 8081,url 为v1
)发送 POST 请求调用ai.dial2
方法:
POST http://192.168.1.25:8081/v1 Content-Type:application/json X-XTRA-AUTH-ID:309fd439-4e79-4b26-a911-735e6204b187 { "jsonrpc": "2.0", "method": "ai.dial2", "id": 11, "params": { "application": "ai", "to": "19999 XML context-1", "cid_name": "test", "cid_number": "8888", "from": "8888", "dial_string": "user/1011", "early_media": true, "auto_answer": true, "external_tracking_id": "123-456-789", "callback_url": "http://192.168.1.25:9393/ai_dial2", "callback_method": "POST", "private_data": { "aaa": "111", "bbb": "2222" } } }
预期流程
postman 模拟发送请求后,XSwitch 发起调用ai.dial2
发起外呼请求,呼叫dial_string
指向的分机,此时请求 body 中没有添加b
参数,通话接通后 XSwitch 将调用transfer
,参数为to
中指向的路由,同时会发送 POST 请求到 HTTP 服务器的url/ai_dial2
接口。
案例二:呼叫 user/1011, 再 bridge user/1005
{ "jsonrpc": "2.0", "method": "ai.dial2", "id": 100, "params": { "application": "ai", "from": "8888", "to": "9999", "cid_name": "test", "cid_number": "8888", "dial_string": "user/1011", "early_media": true, "auto_answer": true, "external_tracking_id": "123-456-789", "callback_url": "http://192.168.1.25:9393/ai_dial2", "callback_method": "POST", "b": { "dial_string": "user/1005", "cid_name": "FreeSWITCH", "cid_number": "9999", "auto_answer": "true" }, "private_data": { "aaa": "111", "bbb": "2222" } } }
预期流程
postman 模拟发送请求后,XSwitch 发起调用ai.dial2
发起外呼请求,首先呼叫dial_string
指向的分机,通话接通后会呼叫b
参数指向的分机,同时会发送 POST 请求到 HTTP 服务器的url/ai_dial2
接口。
附件:服务器代码示例
代码示例
示例服务器代码语言使用Ruby
,使用Sinatra
框架。 安装好环境,下载好框架后,可使用shotgun server.rb -o IP -p PORT
运行服务器示例代码。
1 require 'sinatra' 2 require 'json' 3 4 BASEURL="http://IP:PORT" 5 6 before do 7 if (request.content_type && request.content_type.include?("application/json") && (request.content_length.to_i > 1)) 8 request.body.rewind 9 @params = JSON.parse(request.body.read.to_s) 10 end 11 end 12 13 get '/' do 14 'Hello AI' 15 end 16 17 post '/asr_test' do 18 content_type 'application/json' 19 20 puts "---------- request -------------" 21 puts params.to_s 22 23 obj = { 24 :action => "play", 25 :file => "say:尊敬的客户,您好,请说一句话", 26 :loops => 1, 27 :breakable => false, 28 :asr_engine => "ali", 29 :asr_grammar => "{accent=mandarin, barge-in=true, start-input-timers=true,no-input-timeout=4000,speech-timeout=2500}default", 30 :asr => true, 31 :next => "#{BASEURL}/asr_result", 32 :variables => { 33 :tts_engine => "ali", 34 :tts_voice => "default" 35 }, 36 :private_data => { 37 :data1 => "a", 38 :data2 => 2 39 } 40 } 41 42 puts "========== response =============" 43 puts obj.to_json 44 puts 45 46 obj.to_json 47 end 48 49 post '/asr_result' do 50 content_type 'application/json' 51 text = nil 52 53 puts "---------- request -------------" 54 puts params.to_s 55 56 if params["asr_result"] && params["asr_result"]["text"] 57 text = params["asr_result"]["text"]; 58 end 59 60 if text == nil || text == "" 61 text = "对不起,我没听清您说什么" 62 else 63 text = "您说的是:" + text 64 end 65 66 obj = { 67 :action => "play", 68 :file => "say:" + text, 69 :loops => 1, 70 :next => "#{BASEURL}/hangup", 71 :variables => { 72 :tts_engine => "ali", 73 :tts_voice => "default" 74 }, 75 :private_data => { 76 :data1 => "a", 77 :data2 => 2 78 } 79 } 80 81 puts "========== response =============" 82 puts obj.to_json 83 84 obj.to_json 85 end 86 87 post '/hangup' do 88 content_type 'application/json' 89 90 puts "---------- request -------------" 91 puts params.to_s 92 93 obj = {:action => "hangup"} 94 95 puts "========== response =============" 96 puts obj.to_json 97 98 obj.to_json 99 end 100 101 post '/ai_dial2' do 102 content_type 'application/json' 103 104 json = <<EOF 105 { 106 "resp": "ok" 107 } 108 EOF 109 puts json 110 json 111 end
接口示例详解
这里以asr_test
接口为例详细讲解。下面接口讲解中用Ln
表示第n
行。更详细的说明请参考 aiapi 文档。
当前示例中,asr_test
接口的功能为使用 TTS 播放提示音,等待用户说完一句话后,调用 ASR 处理用户说的话,并将 ASR 的结果发送到next
中 url 指向的接口。
17 post '/asr_test' do 18 content_type 'application/json' 19 20 puts "---------- request -------------" 21 puts params.to_s 22 23 obj = { 24 :action => "play", 25 :file => "say:尊敬的客户,您好,请说一句话", 26 :loops => 1, 27 :breakable => false, 28 :asr_engine => "ali", 29 :asr_grammar => "{accent=mandarin, barge-in=true, start-input-timers=true,no-input-timeout=4000,speech-timeout=2500}default", 30 :asr => true, 31 :next => "#{BASEURL}/asr_result", 32 :variables => { 33 :tts_engine => "ali", 34 :tts_voice => "default" 35 }, 36 :private_data => { 37 :data1 => "a", 38 :data2 => 2 39 } 40 } 41 42 puts "========== response =============" 43 puts obj.to_json 44 puts 45 46 obj.to_json 47 end
L18:指定返回的消息里 Header 的
Content-Type
属性为application/json
L20~L21:打印请求参数,即 XSwitch 发送到 HTTP 服务器的 POST 请求中附带的参数
L23~L40:构造返回给 XSwitch 的 JSON 数据
obj
,- 组成 JSON 的数据里面一般需要包括:
action
:里面包含接下来 XSwitch 需要执行的动作next
:下一次请求的接口地址variables
:需要在 XSwitch 中设置的通道变量private_data
:用户的私有数据
- 这个过程使用的
action
为"play",为了完成接口功能需要增加的其他参数说明:file
:需要播放的语音文件,此处为调用 TTS 播放提示音loops
:指定播放文件的循环次数breakable
:指定 ASR 识别是否连续asr_engine
:指定 ASR 引擎asr_grammar
:指定 ASR 语法asr
:是否启用 ASR 识别
- 组成 JSON 的数据里面一般需要包括:
L42~L44:打印 response 消息