AIAPI开发文档

简单机器人接口协议

接口使用背靠背 REST API 接口协议,适用于简单的机器人交互场景。

XSwitch 与第三方应用程序(App)之间采用背靠背 REST API 交互。即,来电后,XSwitch 会(主动)访问 App 指定的 URL,App Server(被动)返回相应的 JSON 指导 FS 下一步的流程。

交互流程

呼入流程

如下图所示:电话呼入 XSwitch 后,XSwitch 会向用户的 HTTP Server 发送 HTTP 请求(请求为 POST 方式,请求参数使用标准 JSON 格式);HTTP Server 接收到请求后需要回复一个 JSON,指示 XSwitch 要完成的动作(action,通常是播放提示音并接收 DTMF 或者是 TTS 指令);XSwitch 执行完毕相应的动作后,会再次请求 HTTP Server,返回执行的结果(如果带有 DTMF,结果会携带 DTMF 参数;如果有 ASR 识别结果,结果会携带识别的文本)。

外呼流程

如下图所示:由用户 HTTP Server 向 XSwitch 发出外呼的携带被叫号码信息的 HTTP 请求,XSwitch 接收请求后将发出呼叫,并将被叫应答的消息返回给用户 HTTP Server,在用户 HTTP Server 接到应答消息后发出携带指令信息的 HTTP 消息,指示 XSwitch 要完成的动作(action,通常是播放提示音并接收 DTMF 或者是 TTS 指令);XSwitch 执行完毕相应的动作后,会再次请求 HTTP Server,返回执行的结果

外呼 JSON 格式

外呼指令 JSON:

{
    "jsonrpc": "2.0",
    "method": "ai.dial",
    "params": {
        "from": "主叫号码",
        "to": "被叫号码"
        "outbound_gateway": "可选,网关,平台指定,默认为default",
        "dial_string": "XSwitch呼叫字符串,优先级最高,可选",
        "auto_answer": "自动应答",
        "application": "ai 或 httapi,呼通后执行的application,默认为前者",
        "url": "呼通后要访问的url",
        "private_data": {
            "随路数据"
        }
    }
    "id": null
}

其中:

  • dial_string中的 XSwitch 呼叫字符串仅为方便调试使用,或在需要呼叫 SIP 分机时使用。
  • outbound_gateway为外呼网关,由软交换侧配置,默认为default

外呼流程实例

此流程可参照外呼流程示例图。

  1. 由用户 HTTP Server 向 XSwitch 发出外呼的携带被叫号码信息的 HTTP 请求,XSwitch 接收请求后将发出呼叫,并将被叫应答的消息返回给用户 HTTP Server

    用户 HTTP Server 向 XSwitch 发出外呼的携带被叫号码信息的 HTTP 请求示例:

    curl -vvv --user "user:pass" \
    --data '{"jsonrpc": "2.0", "method": "ai.dial", "params": {"from": "1234", "to": "5678", "url": "localhost:9393/", "private_data": {}}, "id": 2}' \
    -H "content-type: application/json" \
    -H "X-XTRA-AUTH-ID: ec741840-9273-10b7-387e-728da01d8e80" \
    test.xswitch.cn:8081/v1
    

    上述请求发到 XSwitch 后,XSwitch 会返回 200 OK(如果出错则返回 500 等错误码并携带报错信息),并向被叫号码5678发起呼叫,主叫号码为1234(主叫号码是否能透传到手机侧显示由设置和运营商线路决定)。

  2. 如果用户应答,则 XSwitch 会向从 HTTP Server 收到请求参数params中的url所指向的服务地址发起 HTTP 请求,获取下一步的指令。

    此时发起的 HTTP 请求内容:

    • 请求:POST, application/json
    • 请求参数说明:

      • {
            "uuid": "该路通话,唯一标志", // 最大36字符
            "cid_number": "1234",
            "dest_number": "5678",
            "channel_data": {
                XSwitch相关数据
            },
            "private_data": {
                "customer_id": "1234",
                "what": "随路数据"
            }
            "其它": "如果有的话或需要的话",
        }
        
  3. HTTP Server 收到 XSwitch 的请求后,应该返回下一步的指令:

    此时发起的指令内容:

    {
        "action": "play",
        "file": "http://example.com/test.mp3",
        "loops": 3, // 可选
        "breakable": false, // 可选,是否可以被打断,默认为true
        "dtmf": "可选,正则表达式,如果有的话,则匹配才返回,否则超时返回",
        "asr": true, // 可选,默认为false
        "vadMode": 0, // 0 - 3
        "next": "next url, 如果没有则使用最后一个url",
        "callback_url": "返回", // 事件回调地址
        "actions": [ 可选数组,可以定义更多的action,如
            {
                action: play
                file: 1.mp3
            },
            {
                action: play
                file: 2.mp3
            },
            {
                action: say
                text: "你好"
            }
        ]
    }
    
    • 关于actions的说明:
      • 如果有actions,则 XSwitch 会首先依次执行 actions 里面的内容,如果内容是playspeak等,不可打断
      • action列表:
        • play 播放并等待结果
        • pause 暂停
        • hangup 挂机
        • dial 呼叫
        • ...
  4. XSwitch 会根据指令内容向用户放音,并检测用户按键或识别用户语音。如果检测到结果,XSwitch 会将结果发送到 HTTP Server,并等待下一步指令。

    • XSwitch 发送的结果格式:
    {
        "uuid": "唯一标志", // 最大36字符
        "cid_number": "1234",
        "dest_number": "5678",
        "asr_result": {
            检测到的语音,具体数据格式因ASR引擎而异,
        },
        "channel_data": {
            XSwitch相关数据
        },
        "private_data": {
            "customer_id": "1234",
            "what": "随路数据"
        }
        "其它": "如果有的话或需要的话",
    }
    
    • 关于示例结果中asr_result数据的说明:

      • 数据格式:

        {
          "engine": "ASR引擎,如baidu",
          "confidence": 0.0, // 0 - 100
          "text": "", // 检测到的文本
          "engine_data": "{\"err_msg\":\"speech quality error.\",\"err_no\":3301,\"sn\":\"126561734111542795937\"}\n"
        }
        

        其中,engine_data为 ASR 引擎返回的数据,字符串格式,不同的引擎返回的格式会有所不同。

    • :如果启用了事件回调,则 XSwitch 会发送事件回调消息(接通、挂机等):

      {
        "uuid": "1-2-3-4", // 唯一标志
        "event": "startTalking" // stopTalking, detectedSpeech
      }
      
  5. HTTP Server 收到事件后,只需简单回复200 OK,如果根据事件需要修改呼叫流程,则可以发送相关的 API:

    • 转移:

      PUT /v1/calls/$uuid
      
      {
          "action": "transfer",
          "dest": "..."
      }
      
    • 外呼:

      POST /v1/calls
      
      {
          "uuid": "唯一标志,最大36字符", // 可选,如果不选,则自动生成
          "cid_number": "1234",
          "dest_number": "5678",
          "gateway": "网关,由服务端指定" // 可选,
          "dest_ip": "对端IP", // 可选
          "dialstring": "XSwitch呼叫字符串",
          "url": "呼通后访问的地址",
          "callback_url": "呼叫过程中回调的地址, 振铃中、接通 ...",
          "private_ata": {
              ... 随路数据
          }
      }
      

    基本原则是,尽可能在 HTTP 上传递随路数据(通话状态机),以避免重复查询数据库等。

捷径

由于上述的流程需要多次 HTTP 交互,为节约交互流程,在更简单场景下可以直接将实际的指令放到application_data中,XSwitch 在呼通后会直接执行application_data中的指令。

{
    "jsonrpc": "2.0",
    "method": "ai.dial",
    "params": {
        "from": "主叫号码",
        "to": "被叫号码"
        "outbound_gateway": "可选,网关,平台指定,默认为default",
        "dial_string": "XSwitch呼叫字符串,优先级最高,可选",
        "auto_answer": "自动应答",
        "application": "ai 或 httapi,呼通后执行的application,默认为前者",
        "url": "呼通后要访问的url",
        "private_data": {
            "随路数据"
        },
        "application_data": {
            "action": "play",
            "file": "http://example.com/test.mp3",
            "loops": 3, // 可选
            "breakable": false, // 可选,是否可以被打断,默认为true
            "dtmf": "可选,正则表达式,如果有的话,则匹配才返回,否则超时返回",
            "asr": true, // 可选,默认为false
            "vad_mode": 0, // 0 - 3
            "next": "next url, 如果没有则执行使用外层url",
            "callbackURL": "返回", // 事件回调地址
            actions: [ 可选数组,可以定义更多的action,如
                {
                    action: play
                    file: 1.mp3
                },
                {
                    action: play
                    file: 2.mp3
                },
                {
                    action: say
                    text: "你好"
                }
            ]
        }
    }
    "id": null
}

理论上,简单接口应该能满足一般的 API 交互和控制。如果需要更多控制,则可以使用 AIAPI 接口。

接口说明