话单及事件推送
零、注意事项:
0.1 格式说明
所有API,若未特殊注明,Content-Type
全部使用 application/json
。
0.2 出参约定格式
如无特殊说明,出参固定为以下格式:
参数 | 类型 | 说明 |
---|---|---|
code | int | 状态码,0 - 成功, 其余为失败 |
message | string | 提示信息 |
data | mixed | 数据 |
data 具体格式见每个接口具体说明
0.3 域名
如果无特殊说明,以下 API 中,所有域名均为: https://autocall.icsoc.net
一、呼叫前推送
1.1 接口
POST 客户提供的推送地址
1.2 推送参数
参数名称 | 类型 | 说明 | 是否必须 |
---|---|---|---|
type | int | 固定值:2 | 是 |
sign | string | 推送签名 | 是 |
timestamp | string | 推送时间(格式Y-m-d H:i:s) | 是 |
data | Data[] | 数据 | 是 |
1.2.1 Data
参数名称 | 类型 | 说明 | 是否必须 |
---|---|---|---|
project_id | int | 项目ID | 是 |
task_id | int | 任务ID | 是 |
ext_id | string | 自定义数据 | 是 |
phone | string | 电话号码 | 是 |
1.3 返回响应
1.3.1 禁止呼叫
此响应用于表示推送的数据是否允许呼叫,如果在 reject 数据里,则将忽略该数据,不进行呼叫。
参数名称 | 类型 | 说明 | 是否必须 |
---|---|---|---|
code | int | 0 视为响应成功,非0数据将自动忽略,数据仍然将进行正常呼叫 | 是 |
message | string | 响应提示 | 是 |
data | object | 数据响应 | 是 |
data.reject | Reject[] | 禁止呼叫数据 | 是 |
1.3.1.1 Reject 格式
参数名称 | 类型 | 说明 | 是否必须 |
---|---|---|---|
project_id | int | 项目ID | 是 |
task_id | int | 任务ID | 是 |
1.3.2 设置主叫号码
此响应用于动态设置推送数据的主叫号码
参数名称 | 类型 | 说明 | 是否必须 |
---|---|---|---|
code | int | 0 视为响应成功,非0数据将自动忽略,数据仍然将按兜底逻辑正常呼叫 | 是 |
message | string | 响应提示 | 是 |
data | object | 数据响应 | 是 |
data.caller | Caller[] | 主叫号码 | 是 |
1.3.2.1 Caller 格式
参数名称 | 类型 | 说明 | 是否必须 |
---|---|---|---|
project_id | int | 项目ID | 是 |
task_id | int | 任务ID | 是 |
caller | string | 主叫号码 | 是 |
1.4 举例
1.4.1 禁止呼叫
1.4.1.1 请求
{
"type":2,
"sign":"123fsafsaf4123321312",
"timestamp":"2000-01-01 00:00:00",
"data":[
{
"project_id":1,
"task_id":1,
"ext_id":"123",
"phone":"18512345678"
}
]
}
1.4.1.2 响应
{
"code":0,
"message":"success",
"data":{
"reject": [
{
"project_id":1,
"task_id":1
}
]
}
}
1.4.2 设置主叫号码
1.4.2.1 请求
{
"type":2,
"sign":"123fsafsaf4123321312",
"timestamp":"2000-01-01 00:00:00",
"data":[
{
"project_id":1,
"task_id":1,
"ext_id":"123",
"phone":"18512345678"
}
]
}
1.4.2.2 响应
{
"code":0,
"message":"success",
"data":{
"caller": [
{
"project_id":1,
"task_id":1,
"caller": "01012345678"
}
]
}
}
二、呼叫结束推送(cdr 话单推送)
该接口为 cdr 话单推送业务接口,需客户提供推送地址。
推送格式为 JSON。 推送参数支持加密,签名算法,加密算法,解密算法,详见 附录
注意
请您注意,由于网络不稳定等原因,您需要自行处理接口幂等性问题,可根据 call_id 进行唯一标识。
如果在任务中开启重呼时,每次外呼都会进行一次回调推送,例如任务中配置了重呼3次,即最多会呼叫4次,那么就会最多推送4条记录
如果中间外呼接通的话,那么就不会进行额外的重呼,例如重呼第一次就接通了,那么就不会再进行重呼了
推送记录中的user_data.ext_id
(即在数据导入时传递的 extId
)是一样的即代表推送的是同一条数据的外呼记录
所以需要在接收回调的接口中做对应的逻辑处理,也可以根据推送记录数来记录每条数据的外呼次数
Q1. 怎么判断哪条是最后的推送记录呢? A1. 可以判断推送记录中的呼叫结果是否是接通的或者根据接收到的推送记录是否已经达到重呼次数的上限了
Q2. 怎么判断推送的记录是哪一条数据的外呼记录?
A2. 根据推送记录中的user_data.ext_id
来判断数据的唯一标识
2.1 接口
POST 客户提供的推送地址
2.2 推送参数
参数名称 | 类型 | 说明 | 是否必须 |
---|---|---|---|
type | int | 固定值:1 | 是 |
sign | string | 推送签名 | 是 |
timestamp | string | 推送时间(格式Y-m-d H:i:s) | 是 |
data | object/string | 数据,加密时返回类型为 string | 是 |
data.caller | string | 主叫号码 | 是 |
data.called | string | 被叫号码 | 是 |
data.sipcode | string | SIP挂机码 | 是 |
data.trans_sipcode | string | 转接SIP挂机码 | 是 |
data.trans_caller | string | 呼叫坐席主叫 | 是 |
data.call_id | string | 呼叫 ID | 是 |
data.trans_phone | string | 呼叫坐席的电话号码 | 是 |
data.call_time | string | 呼叫时间 | 是 |
data.called_areacode | string | 被叫区号 | 是 |
data.called_areaname | string | 被叫地区 | 是 |
data.called_type | string | 被叫号码类型 | 是 |
data.called_vendor | string | 被叫运营商 | 是 |
data.start_time_ee | string | 第二方(机器人外呼时代表 机器人;预测式外呼/自动外呼时代表 坐席)呼叫时间(如果有转人工、技能组等操作,则为最后一次转接呼叫时间),时间戳格式 | 是 |
data.ring_time_ee | string | 第二方(机器人外呼时代表 机器人;预测式外呼/自动外呼时代表 坐席)振铃时间(如果有转人工、技能组等操作,则为最后一次转接振铃时间) ,时间戳格式 | 是 |
data.answer_time_ee | string | 第二方(机器人外呼时代表 机器人;预测式外呼/自动外呼时代表 坐席)应答时间(如果有转人工、技能组等操作,则为最后一次转接应答时间),时间戳格式 | 是 |
data.end_time_ee | string | 第二方(机器人外呼时代表 机器人;预测式外呼/自动外呼时代表 坐席)结束时间(如果有转人工、技能组等操作,则为最后一次转接结束时间),时间戳格式 | 是 |
data.start_time | string | 第一方(即,客户)呼叫时间,时间戳格式 | 是 |
data.ring_time | string | 第一方(即,客户)振铃时间,时间戳格式 | 是 |
data.ans_time | string | 第一方(即,客户)应答时间,时间戳格式 | 是 |
data.link_time | string | 转人工时,客户和坐席通话时间,时间戳格式 | 是 |
data.end_time | string | 客户挂机时间,时间戳格式 | 是 |
data.ans_secs | string | 客户应答时长 | 是 |
data.link_secs | string | 转人工时,客户和坐席通话时间 | 是 |
data.all_secs | string | 总时长 | 是 |
data.callresult | string | 呼叫结果 0客户未接通 1仅客户接通 2客户和坐席都接通 | 是 |
data.endresult | string | 11第一方(即,客户)挂机 12第二方挂断 13转接(可能发生过电话条的盲转,转坐席,转技能组,转IVR) | 是 |
data.trans_mark | string | 转接标识,位运算 1转技能组,2转坐席,4转电话,8转机器人。如果机器人转坐席,则为 10(8+2),如果转技能组后无坐席则为9(8+1),如果转技能组后转到坐席则为11(8+1+2) | 是 |
data.user_data | object | 自定义数据 | 是 |
data.record_file | string | 录音url | 否 |
data.dialogues | object | 机器人外呼通话详情(机器人外呼任务时存在) | 否 |
data.dialogues.interact_count | int | 通话轮次 | 是 |
data.dialogues.useful_interact_count | int | 有效通话轮次 | 是 |
data.dialogues.no_speak_count | int | 无声次数 | 是 |
data.dialogues.unknown_count | int | 未知问题次数 | 是 |
data.dialogues.hang_side | int | 挂机方 0用户 1机器人 | 是 |
data.dialogues.labels | array | 对话所有命中的标签 | 是 |
data.dialogues.records | array | 对话信息 | 是 |
data.dialogues.records.start | int | 开始时间 毫秒 | 是 |
data.dialogues.records.end | int | 结束时间 毫秒 | 是 |
data.dialogues.records.content | string | 内容 | 是 |
data.dialogues.records.speaker | int | 对话方 1机器人 0用户 | 是 |
data.dialogues.records.msg_num | int | 消息序号 | 是 |
data.dialogues.records.labels | array | 命中标签 | 是 |
data.dialogues.records.is_unknown | bool | 是否是未知问题 | 是 |
data.dialogues.records.is_hang | bool | 是否挂机 | 是 |
data.dialogues.records.is_none_speak | bool | 是否无声 | 是 |
data.dialogues.tags.name | string | 命中的标签名称 | 否 |
data.dialogues.tags.sign | string | 命中的标标识 | 否 |
data.dialogues.judgement_intention | int | 判定的意向等级 | 否 |
data.dialogues.judgement_intention_name | string | 判定的意向的等级名称 | 否 |
data.asr | object | asr 回铃识别信息。当推送时,可能会因为识别时效多次推送,请做好幂等(可根据 call_id 进行) | 否 |
data.asr.asr_int | int | 枚举:1-用户忙、2-无法接通、3-关机、4-停机、5-空号、11-呼叫限制 | 否 |
data.asr.asr_text | string | 解释 | 否 |
data.called_times | int | 呼叫次数 | 是 |
data.call_fail_result | string | 呼叫失败结果:-1 其他异常,0 风控拦截,1 企业黑名单拦截,2 外部黑名单拦截,3 webhook 拦截 | 否 |
data.call_fail_result_text | string | 呼叫失败结果枚举释义 | 否 |
data.is_last_call | bool | 是否是最后一次呼叫 | 是 |
2.3 返回响应
参数名称 | 类型 | 说明 | 是否必须 |
---|---|---|---|
code | int | 0 视为推送成功 | 是 |
返回的 json 中必须包含 code 字段,且值必须为 0 ,否则系统将视为推送失败,失败后,将以 15/15/30/180/1800/1800/1800/1800/3600(单位:秒)的频率重试通知客户端,如果所有的重试完成后仍然失败,则自动放弃通知。
2.4 举例
未加密
{
"type":1,
"data":{
"vcc_id": "777",
"call_id": "6811535818021285888",
"caller": "01212345674",
"called": "156xxxx6818",
"called_areacode": "0376",
"called_areaname": "\u6cb3\u5357 \u4fe1\u9633",
"called_type": "MOBILE",
"called_vendor": "MOBILE",
"trans_caller": "",
"trans_phone": "",
"trans_areacode": "",
"trans_areaname": "",
"trans_type": "",
"trans_vendor": "",
"start_time_ee": "0",
"ring_time_ee": "0",
"answer_time_ee": "0",
"end_time_ee": "0",
"start_time": "1623996691",
"ring_time": "1623996696",
"ans_time": "0",
"link_time": "0",
"end_time": "1623996721",
"ans_secs": "0",
"link_secs": "0",
"all_secs": "30",
"callresult": "0",
"endresult": "12",
"call_context": "mc_transque",
"call_exten": "ivr_in",
"call_vars": "trans_que=660,trans_pro=10195",
"record_file": "",
"is_last_call": true,
"user_data": {
"_tag": "autocall:poc",
"ext_id": "buer",
"template_data": null,
"proid": "10195",
"taskid": "7"
},
"trans_agent": {},
"dialogues": {
"interact_count": 0,
"no_speak_count": 0,
"unknown_count": 0,
"hang_side": 0,
"records": [
{
"callId": 6933322005202764000,
"start": 0,
"end": 0,
"content": "请问你是张三吗,测试2222",
"speaker": 1,
"msg_num": 1,
"labels": [
"测试1",
"KJCS",
"WTQ",
"测试2"
],
"is_unknown": false,
"is_hang": false,
"is_none_speak": false,
"extData": null
}
],
"labels": [
"测试1",
"KJCS",
"WTQ",
"测试2"
],
"tags": [
{
"name": "测试1",
"sign": "default"
},
{
"name": "KJCS",
"sign": "explain"
}
],
"useful_interact_count": 0,
"judgement_intention": 20,
"judgement_intention_name": "A+"
}
},
"sign":"1c9cc7470803e5605b88a4132cad021a",
"timestamp": "2021-01-01 00:00:00"
}
加密
{
"type":1,
"data":"tAMpIJPIwcmRXahctUdRZYCBi0RBPqymmx/bPvk0PtdXDaKokoycyaOC0o6ed6l6iCzoGdrySft1qVGeCGnF1X+5j0OPI6MqlZJ3b120jj4NkrbVQ3hwbiYUbv3fMb162qdVo2ku5bWQvGmBzR7UOhkaKVRH7VVXq7CZoCMz9RnuvMC1SVOKSdLABfsCi0Qtxh4llxdsrMMESIm8RxMgYZuTVlW5M0nwIIHZLLu9dcISO94nQ9Y2T89/W/L8FijnWEdowPP2ZsbrfH1lm0UgkJ8FEbI2tRGkCy5TOytH40wZmkXq/bF4lIx574I8i+Nox03PPMx48BzFv25OpfI/4FJvwT6O2cyY2URezai3KdEqnA/QURfHZIeU7klxzA0jSl/jRdRVDFg8ACYoBmC4U43+NY+5VZPDeltJvaVUUFpyv/4LJe/mum6Ofqh+m2ytoUpLIQnDZvCWJqa/g4LHMmu2aPG7LXjUK1nq30l2gakucSNvAvMr8bv8fuelP7/VU8ttPPnr7Zf0fCz2ZEg8R5jNbElym8g7NA5qJev+R7J6oC3IOnwJUDTDO/YMCj4=",
"sign":"1c9cc7470803e5605b88a4132cad021a",
"timestamp": "2021-01-01 00:00:00"
}