中通天鸿开发者平台

中通天鸿开发者平台

  • 开发文档
  • API文档

›外呼机器人

快速入门

  • 如何认证

wincall

    wincall V2

    • 快速入门
    • CTIPlus实例对象
    • 坐席操作
    • 会话对象
    • 监听强插操作
    • 基础信息获取
    • 事件

toolbar

  • 电话工具条

在线客服

  • APP SDK推送接口
  • im-api
  • iOS SDK 开发指南
  • Android SDK 开发指南

CTI-PLUS

  • 接口文档
  • 参考手册
  • WS消息参考手册

外呼机器人

  • 外呼机器人对外接口文档_v1.0
  • 外呼机器人对外接口文档_v2.0
  • 媒体库对外接口文档_v1.0
  • 外呼机器人NLP接口参考手册_v1.0

MakeCall

  • MakeCall外呼发起及事件订阅服务_v1.0

自定义报表

  • 新老报表指标映射

媒体库对外接口文档_v1.0

发行/变更日志

2019-02-18

  • v1.0文档初稿

2019-02-25

  • 完善列表拉取的分页操作及模糊查询
  • 完善测试结果

验证方式

接入时平台会把appId、appSecret给到业务方

签名计算方式

appSecret="123456"; //appId 对应的 appSecret,需要业务方高度保密
timestamp="1545372991205"; //毫秒时间戳字符串
sig=sha256(appSecret=123456&timestamp=1545372991205) = c9f8f271384322fda0dfa65b3bcefc3608c46a3c707234171a5d296cbeb5d826

header

字段字段类型说明
sigstring签名
appIdstringappId
timestampstring时间戳

时效性

timestamp会和服务器时间做对比,如果相差超过 10 分钟则会返回失败

API参数和输出

编码(encoding)

  • 全部为UTF-8
  • HTTP header中的声明Content-Type:application/json

输出 不支持协商,仅支持json。无视HTTP header中Accept的要求。 如无特殊说明,API不支持If-Modified-Since/If-None-Match,始终输出完整结果。

数据类型或格式

  • JSON代码中出现的时间格式,如无特殊说明,均采用时间戳。

文档编辑

文中json代码为了书写方便,属性名也许存在未带双引号的情况(也可能在文档升级时解决该问题),编码时请全部按照含双引号的规范方式理解。

公共返回值

{
    "code" : 200,          // 请求返回码 200成功,其他返回码为失败
    "msg" : "",            // 错误信息
    "data" : {}            // 请求返回数据 json
}

服务地址

  • 测试服务地址:http://robot-mm-test.icsoc.net
  • 生成环境地址:http://robot-mm.icsoc.net

项目管理接口

获取项目列表

URL

/project/list

请求方式

POST

请求参数

{
    "page":1,
    "pageSize":10,
    "projectName":"1"
 }

说明

参数类型说明必选约束
pageint页数否非负整数,默认1
pageSizeint项目Id否非负整数,默认10
projectNamestring项目名称[模糊查询]否长度1-30

返回结果

{
    "code" : 200 ,
    "msg" : "操作成功" ,
    "data" : {
        "total": 1,
        "list": [
            { 
                "projectId" : 255 ,
                "projectName" : "瓜子NLP话术A"
             }     
        ]
    }
}

说明:

返回字段字段类型说明
projectIdint项目ID
projectNamestring项目名称

新增项目

URL

/project/create

请求方式

POST

请求参数

{
    "projectName" : "瓜子NLP话术A"
}

说明:

参数类型说明必选约束
projectNamestring项目名称是长度1~32位

返回结果

{
    "code" : 200 ,
    "msg" : "操作成功" ,
    "data" : {
        "projectId" : 255
    }
}

说明:

返回字段字段类型说明
projectIdint项目ID

修改项目

URL

/project/update

请求方式

PUT

请求参数

{
    "projectId" : 255 ,
    "projectName" : "瓜子NLP话术A"
}

说明:

参数类型说明必选约束
projectIdint项目Id是非负整数
projectNamestring项目名称是长度1~32位

返回结果

{
    "code" : 200 ,
    "msg" : "操作成功" ,
    "data" : null
}

删除项目

URL

/project/del/{projectId}

请求方式

DELETE

请求参数 说明:

参数类型说明必选约束
projectIdint项目Id是非负整数

返回结果

{
    "code" : 200 ,
    "msg" : "操作成功" ,
    "data" : null
}

语音管理接口

获取媒体语音列表

URL

/media/list

请求方式

POST

请求参数

{
    "page":1,
    "pageSize":10,
    "projectId":1,
    "mediaContent":"1"
 }

说明:

参数类型说明必选约束
pageint页数否非负整数,默认1
pageSizeint项目Id否非负整数,默认10
projectIdint项目Id否非负整数
mediaContentstring媒体内容[模糊查询]否长度1-100

返回结果

{
    "msg": "操作成功",
    "code": 200,
    "data": {
        "total": 1,
        "list": [
            {
                "mediaId": 1,
                "projectId": 1,
                "vccId": "1018",
                "mediaContent": "10",
                "mediaUrl": "http://api.test"
            }
        ]
    }
}

说明:

返回字段字段类型说明
mediaIdint语音ID
mediaContentstring语音文字描述
mediaUrlstring语音地址

语音上传

URL

/media/upload

请求方式

POST

请求参数 文件流

返回结果

{
    "code" : 200 ,
    "msg" : "操作成功" ,
    "data" :{
        "mediaUrl" : "https://domain/..."
    }
}

说明:

返回字段字段类型说明
mediaUrlstring语音地址

Java客户端调用

/**
 * <p>
 * 媒体库文件上传测试
 * </p>
 *
 * @author : Qianlu
 * @since : 2019-02-22
 */
@Slf4j
@SpringBootTest(classes = Media.class)
@RunWith(SpringJUnit4ClassRunner.class)
public class TestLocalUpload {

    @Autowired
    private RestTemplate restTemplate;

    /**
     * App auth 请求头 签名
     */
    private String APP_AUTH_HEADER_SIG = "sig";

    /**
     * App auth 请求头 应用ID
     */
    private String APP_AUTH_HEADER_APPID = "appId";

    /**
     * App auth 请求头 时间戳
     */
    private String APP_AUTH_HEADER_TIMESTAMP = "timestamp";

    /**
     * 上传接口地址
     */
    private String uploadUrl = "http://127.0.0.1:8888/media/upload";

    /**
     * 待上传文件路径
     */
    private String filePath = "C://Users//Qianlu//Downloads//test1.png";

    /**
     * 测试本地文件上传
     */
    @Test
    public void TestLocalFileUpload() {
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        headers.add(APP_AUTH_HEADER_APPID, "132985e9550fb81ddc60760f9328142b");
        headers.add(APP_AUTH_HEADER_SIG, "0b5cd7de90a2733aed44156fbaf542ded57434fc6b57fdce33250a7d6d478328");
        headers.add(APP_AUTH_HEADER_TIMESTAMP, "1550825461180");

        File file = new File(filePath);
        FileSystemResource fileSystemResource = new FileSystemResource(filePath);
        MediaType type = MediaType.parseMediaType("multipart/form-data");
        headers.setContentType(type);
        String cd = "filename=\"" + file.getName() + "\"";
        headers.add("Content-Disposition", cd);
        MultiValueMap<String, Object> form = new LinkedMultiValueMap<>();
        form.add("file", fileSystemResource);

        HttpEntity<MultiValueMap<String, Object>> request = new HttpEntity<>(form, headers);
        ResponseEntity<String> response = restTemplate.postForEntity(uploadUrl, request, String.class);
        log.info(response.toString());
    }

    /**
     * MultipartFile文件上传
     */
    @Test
    public void TestMultipartFileUpload() throws IOException {
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        headers.add(APP_AUTH_HEADER_APPID, "132985e9550fb81ddc60760f9328142b");
        headers.add(APP_AUTH_HEADER_SIG, "0b5cd7de90a2733aed44156fbaf542ded57434fc6b57fdce33250a7d6d478328");
        headers.add(APP_AUTH_HEADER_TIMESTAMP, "1550825461180");

        MockMultipartFile multipartFile = new MockMultipartFile("tmp.png", new FileInputStream(new File(filePath)));

        FileSystemResource fileSystemResource = new FileSystemResource(filePath);
        MediaType type = MediaType.parseMediaType("multipart/form-data");
        headers.setContentType(type);
        String cd = "filename=\"" + multipartFile.getOriginalFilename() + "\"";
        headers.add("Content-Disposition", cd);
        MultiValueMap<String, Object> form = new LinkedMultiValueMap<>();
        form.add("file", fileSystemResource);

        HttpEntity<MultiValueMap<String, Object>> request = new HttpEntity<>(form, headers);
        ResponseEntity<String> response = restTemplate.postForEntity(uploadUrl, request, String.class);
        log.info(response.toString());
    }
}

Go客户端调用

package main

import (
    "net/http"
    "os"
    "bytes"
    "mime/multipart"
    "path/filepath"
    "io"
    "fmt"
    "github.com/Qianlu5110/logrus"
)

const (
    AppAuthHeaderSig       = "sig"
    AppAuthHeaderAppid     = "appId"
    AppAuthHeaderTimestamp = "timestamp"
)

var (
    mediaUploadUrl = "http://127.0.0.1:8888/media/upload"
    filePath       = "C://Users//Qianlu//Downloads//test1.png"
)

func MediaUploadRequest(uri string, path string) (*http.Request, error) {
    file, err := os.Open(path)
    if err != nil {
        return nil, err
    }
    defer file.Close()

    body := &bytes.Buffer{}
    writer := multipart.NewWriter(body)
    part, err := writer.CreateFormFile("file", filepath.Base(path))
    if err != nil {
        return nil, err
    }
    _, err = io.Copy(part, file)

    err = writer.Close()
    if err != nil {
        return nil, err
    }

    request, err := http.NewRequest("POST", uri, body)
    request.Header.Add("Content-Type", writer.FormDataContentType())
    request.Header.Add(AppAuthHeaderSig, "132985e9550fb81ddc60760f9328142b")
    request.Header.Add(AppAuthHeaderSig, "6e40eff62381b1042bdd09a45a89f1451d70438e897327cf5da0ab2d3165c059")
    request.Header.Add(AppAuthHeaderTimestamp, "1550821258073")
    return request, err
}

func main() {
    request, err := MediaUploadRequest(mediaUploadUrl, filePath)
    if err != nil {
        logrus.Error(err)
    }
    client := &http.Client{}
    resp, err := client.Do(request)
    if err != nil {
        logrus.Error(err)
    } else {
        body := &bytes.Buffer{}
        _, err := body.ReadFrom(resp.Body)
        if err != nil {
            logrus.Error(err)
        }
        resp.Body.Close()
        fmt.Println(resp.StatusCode)
        fmt.Println(resp.Header)
        fmt.Println(body)
    }
}

保存语音信息

URL

/media/create

请求方式

POST

请求参数

{
    "projectId" : 255 ,
    "mediaContent" : "你好,我是***...",
    "mediaUrl" : "https://domain/..."
}

说明:

参数类型说明必选约束
projectIdint项目Id是非负整数
mediaContentint语音文本内容是长度1~100
mediaUrlstring语音播放地址是长度10~1024

返回结果

{
    "code" : 200 ,
    "msg" : "操作成功" ,
    "data" : {
        "mediaId" : 1020
    }
}

说明:

返回字段字段类型说明
mediaIdint语音ID

更新语音信息

URL

/media/update

请求方式

PUT

请求参数

{
    "projectId" : 255 ,
    "mediaId" : 1020 , 
    "mediaContent" : "你好,我是***直卖网...",
    "mediaUrl" : "https://domain/..."
}

说明:

参数类型说明必选约束
projectIdint项目Id是非负整数
mediaIdint语音Id是非负整数
mediaContentstring语音文本内容是长度1~100
mediaUrlstring语音播放地址是长度10~1024

返回结果

{
    "code" : 200 ,
    "msg" : "操作成功" ,
    "data" : null
}

删除语音信息

URL

/media/del/{mediaId}

请求方式

DELETE

请求参数 说明:

参数类型说明必选约束
mediaIdint语音Id是非负整数

返回结果

{
    "code" : 200 ,
    "msg" : "操作成功" ,
    "data" : null
}

系统错误码

值说明
401鉴权失败
401鉴权失败[header不完整]
401鉴权失败[sign超时]
401鉴权失败[sign错误]
401鉴权失败[appId不存在]
5000服务运行错误,请联系管理员
5001请求体没有包含正确的version值
5002参数校验未通过
5003服务内部异常,请重试

业务错误码

值说明
70101项目不存在
70102项目名称重复
70201语音不存在
70202语音内容重复
70203语音文件为空
Last updated on 3/12/2019 by Qianlu
← 外呼机器人对外接口文档_v2.0外呼机器人NLP接口参考手册_v1.0 →
  • 发行/变更日志
    • 验证方式
    • API参数和输出
    • 数据类型或格式
    • 文档编辑
    • 公共返回值
    • 服务地址
  • 项目管理接口
    • 获取项目列表
    • 新增项目
    • 修改项目
    • 删除项目
  • 语音管理接口
    • 获取媒体语音列表
    • 语音上传
    • 保存语音信息
    • 更新语音信息
    • 删除语音信息
    • 系统错误码
    • 业务错误码
中通天鸿开发者平台
产品中心
呼叫中心在线客服工单系统IM机器人CTI-PLUS语音机器人通信云资源云
帮助中心
常见问题更新日志
关于我们
公司简介联系我们友情链接
Copyright © 2021 中通天鸿(北京)通信科技股份有限公司