智能路由 JSON 接口对接指南

版本:v1.0
更新日期:2026-06-18
适用对象:第三方后端开发者
服务提供方:TelCRM HibernateService(OSGi Bundle)


1. 概述

本服务提供对智能路由规则(Intelligent Routing Rule)的增删改查 HTTP 接口。智能路由规则用于根据号码、时间、操作类型等条件,对呼入/呼出电话进行自动路由(如转分机、转语音邮箱、IVR 导航、放音后挂机等)。

  • 协议:HTTP/1.1
  • 默认端口:12121
  • 入口路径:/bridge/jsoncfg
  • 认证:无认证。部署于内网,请确保在网络层(防火墙/安全组)做好隔离。
  • 数据格式:请求与响应均为 JSON,UTF-8 编码。

服务共暴露 4 个接口:

接口opt 取值HTTP 方法用途
查询全部规则INTELLIGENT_ROUTING_GET_ALLGET列出所有规则
新增规则INTELLIGENT_ROUTING_ADDPOST新增一条规则
修改规则INTELLIGENT_ROUTING_UPDATEPOST按 id 修改已有规则
删除规则INTELLIGENT_ROUTING_DELETEGET按 id 删除规则

2. 通用约定

2.1 URL 结构

所有接口共用同一个入口 URL,通过 query 参数 opt 区分操作类型:

http://<host>:<port>/bridge/jsoncfg?opt=<操作类型>[&json=<参数>]
  • opt:必填,取值见上表。
  • json:可选,用于 DELETE 操作传 id 数字串;ADD/UPDATE 不使用此参数,参数走请求体。

2.2 HTTP 方法选择

opt方法数据位置
INTELLIGENT_ROUTING_ADDPOST请求体(raw body)
INTELLIGENT_ROUTING_UPDATEPOST请求体(raw body)
INTELLIGENT_ROUTING_DELETEGETquery 参数 json=<id>
INTELLIGENT_ROUTING_GET_ALLGET无

重要:ADD/UPDATE 必须用 POST 把 JSON 放在请求体里。不要把 JSON 拼到 query 参数 json= 上——URL 长度受限、+ 号编码有歧义、特殊字符容易出错。

2.3 请求编码

  • 请求体编码:UTF-8。
  • POST 请求推荐带 Header:Content-Type: application/json; charset=UTF-8(不带也能工作,但建议带上以便代理/网关正确处理)。

2.4 响应结构

所有接口统一返回 JSON 对象,结构如下:

{
  "state": 200,
  "total": 1,
  "data": [ ... ]
}
字段类型说明
stateInteger业务状态码。200=成功,400=失败。
totalIntegerdata 数组的元素数量。
dataArray数据数组,元素类型视接口而定(智能路由场景为 IntelligentRoutingRule 对象数组)。

关于 null 字段:服务端用 Gson 默认配置序列化,值为 null 的字段会被省略。例如 DELETE 成功响应实际是 {"state":200,"total":0},不会包含 data 字段。客户端解析时不要假设 data 一定存在。

2.5 HTTP 状态码

服务端 始终返回 HTTP 200,无论业务成功或失败。业务成败请通过响应 JSON 的 state 字段判断。

2.6 错误响应示例

业务失败时,响应形如:

{
  "state": 400,
  "total": 0
}

不包含错误详情字段。如需排查,请联系服务端运维查服务端日志(异常堆栈会写入 ERROR 日志)。


3. 数据模型

3.1 IntelligentRoutingRule 字段说明

所有接口的请求/响应数据都围绕 IntelligentRoutingRule 这个对象。字段如下:

字段类型必填说明
idIntegerUPDATE 必填 / ADD 忽略规则主键。ADD 时由服务端分配并返回;UPDATE 时用于定位要修改的记录。
telnumStringADD 必填适用号码。被叫侧智能路由填被叫号码;CALL_FORWARD 等主叫侧业务填主叫号码。含 + 号时(如国际号码 +86...)必须转义为 %2B,详见 §6 FAQ。
datetypeString视 operationtype 而定时间类型枚举,见 3.2。无时段业务(如 BUSY_AND_REJECT)可传空字符串 ""。
begintimeString视 datetype 而定时段开始时间。格式随 datetype 变化,见 3.2。
endtimeString视 datetype 而定时段结束时间。格式随 datetype 变化,见 3.2。
operationtypeString必填操作类型枚举,见 3.3。
parametersString视 operationtype 而定操作参数。含义随 operationtype 变化,见 3.3 对照表。
subbegintimeString仅 WEEK_TYPE 必填子时段开始,格式 HH:mm:ss,默认 "00:00:00"。仅 WEEK_TYPE 生效,其他 datetype 留空。
subendtimeString仅 WEEK_TYPE 必填子时段结束,格式 HH:mm:ss,默认 "23:59:59"。仅 WEEK_TYPE 生效。
offonBoolean可选(默认 true)规则是否启用。true=启用、false=停用。
groupnameString可选分组名,用于管理界面归类展示,不影响路由逻辑。

3.2 datetype 枚举与时间格式

值含义begintime / endtime 格式示例subbegintime / subendtime
DAY_TYPE每天重复HH:mm:ss"08:30:00" ~ "17:30:00"不使用
WEEK_TYPE每周重复整数 0–6:"0"=周日、"1"=周一、"2"=周二、"3"=周三、"4"=周四、"5"=周五、"6"=周六"1" ~ "5"(工作日)HH:mm:ss,默认 "00:00:00" / "23:59:59"
MONTH_TYPE每月重复整数 1–31"1" ~ "15"不使用
SPECIFIED_DAY指定日期yyyy-MM-dd HH:mm:ss"2026-07-01 09:00:00" ~ "2026-07-01 18:00:00"不使用

WEEK_TYPE 注意:取值是 0–6(不是 1–7)。"0" 代表周日,这点和其他系统常用的 ISO 8601(1=周一)不同。

3.3 operationtype 枚举与 parameters 语义

每种操作类型对 parameters 字段的含义要求不同:

operationtype含义parameters 含义是否需要 datetype 时段
BUSY_AND_REJECT置忙拒接(直接拒绝来电)不使用,传空字符串 ""可选
PLAY_AND_HANGUP放音后挂机提示音 id可选
TRANSFER_CALL无条件前转目标号码(分机号或外线号码)可选
CALL_FORWARD主叫侧来电直呼转分机(主叫侧业务,telnum 填主叫号码)目标分机号可选
VOICE_MAIL转语音邮箱提示音 id / 邮箱 id可选
ONANSWER_TO_VM无应答转语音邮箱提示音 id不需要(强制无时段,datetype 应为空)
ONANSWER_TRANSFER无应答前传目标号码可选
IVR_SELECT分时语音导航IVR 菜单 id可选
DIAL_HTTP_DOCKING拨打触发 HTTP 调用HTTP 对接配置(具体格式与服务端约定)可选
CALLER_AREA_TRANSFER基于主叫归属地前传目标号码可选
CALLER_AREA_IVR基于主叫归属地的 IVRIVR 菜单 id可选
INCOMING_CALL_DELAY延迟呼叫分机(保证企业彩铃播完)延迟毫秒数(整数字符串)可选
INCOMING_CALL_FLOOD_CTRL呼入流控JSON 模板:{"telnums":["",""],"toneId":0,"threshold":0}可选
DISTRIBUTED_EXT_CALL分布式分机呼叫(已废弃)——
NOT_SUPPORTED不支持的(占位)——

常用推荐:第三方对接一般用 TRANSFER_CALL(转号码)、VOICE_MAIL(转语音邮箱)、IVR_SELECT(IVR 导航)、BUSY_AND_REJECT(黑名单式拒接)。其它类型主要为系统内部使用。


4. 接口清单

4.1 查询全部规则

项值
optINTELLIGENT_ROUTING_GET_ALL
HTTP 方法GET
URL/bridge/jsoncfg?opt=INTELLIGENT_ROUTING_GET_ALL
请求体无

响应:

{
  "state": 200,
  "total": 2,
  "data": [
    {
      "id": 1,
      "telnum": "801",
      "datetype": "DAY_TYPE",
      "begintime": "08:30:00",
      "endtime": "17:30:00",
      "operationtype": "TRANSFER_CALL",
      "parameters": "800",
      "subbegintime": "00:00:00",
      "subendtime": "23:59:59",
      "offon": true,
      "groupname": "售后组"
    },
    {
      "id": 2,
      "telnum": "802",
      "datetype": "",
      "begintime": "",
      "endtime": "",
      "operationtype": "BUSY_AND_REJECT",
      "parameters": "",
      "offon": true,
      "groupname": ""
    }
  ]
}

说明:返回全部规则,无分页。空字符串字段会出现在 JSON 中,null 字段会被省略(参考 §2.4)。

curl 示例:

curl 'http://127.0.0.1:12121/bridge/jsoncfg?opt=INTELLIGENT_ROUTING_GET_ALL'

4.2 新增规则

项值
optINTELLIGENT_ROUTING_ADD
HTTP 方法POST
URL/bridge/jsoncfg?opt=INTELLIGENT_ROUTING_ADD
请求体IntelligentRoutingRule JSON,id 字段会被忽略(由服务端分配)

请求示例(每天工作时段转分机 800):

{
  "telnum": "801",
  "datetype": "DAY_TYPE",
  "begintime": "08:30:00",
  "endtime": "17:30:00",
  "operationtype": "TRANSFER_CALL",
  "parameters": "800",
  "offon": true,
  "groupname": "售后组"
}

成功响应:

{
  "state": 200,
  "total": 1,
  "data": [
    {
      "id": 123,
      "telnum": "801",
      "datetype": "DAY_TYPE",
      "begintime": "08:30:00",
      "endtime": "17:30:00",
      "operationtype": "TRANSFER_CALL",
      "parameters": "800",
      "subbegintime": "00:00:00",
      "subendtime": "23:59:59",
      "offon": true,
      "groupname": "售后组"
    }
  ]
}

data[0].id 是服务端分配的新 id,后续 UPDATE/DELETE 需要用到。

失败响应:{"state":400,"total":0}。常见原因:请求体不是合法 JSON、必填字段缺失、服务端内部处理异常。

curl 示例:

curl -X POST 'http://127.0.0.1:12121/bridge/jsoncfg?opt=INTELLIGENT_ROUTING_ADD' \
     -H 'Content-Type: application/json; charset=UTF-8' \
     --data-raw '{"telnum":"801","datetype":"DAY_TYPE","begintime":"08:30:00","endtime":"17:30:00","operationtype":"TRANSFER_CALL","parameters":"800","offon":true,"groupname":"售后组"}'

4.3 修改规则

项值
optINTELLIGENT_ROUTING_UPDATE
HTTP 方法POST
URL/bridge/jsoncfg?opt=INTELLIGENT_ROUTING_UPDATE
请求体IntelligentRoutingRule JSON,必须包含 id

请求示例(把上一步 id=123 的规则改成转语音邮箱 v100):

{
  "id": 123,
  "telnum": "801",
  "datetype": "DAY_TYPE",
  "begintime": "09:00:00",
  "endtime": "18:00:00",
  "operationtype": "VOICE_MAIL",
  "parameters": "v100",
  "offon": true,
  "groupname": "售后组"
}

成功响应:

{
  "state": 200,
  "total": 1,
  "data": [
    {
      "id": 123,
      "telnum": "801",
      "datetype": "DAY_TYPE",
      "begintime": "09:00:00",
      "endtime": "18:00:00",
      "operationtype": "VOICE_MAIL",
      "parameters": "v100",
      "subbegintime": "00:00:00",
      "subendtime": "23:59:59",
      "offon": true,
      "groupname": "售后组"
    }
  ]
}

说明:UPDATE 是全字段覆盖,请求体里没传的字段会被置为默认值(或 null)。建议先 GET_ALL 取出原记录,修改字段后再整体提交。

失败响应:{"state":400,"total":0}。常见原因:id 缺失或非法、请求体不是合法 JSON。

curl 示例:

curl -X POST 'http://127.0.0.1:12121/bridge/jsoncfg?opt=INTELLIGENT_ROUTING_UPDATE' \
     -H 'Content-Type: application/json; charset=UTF-8' \
     --data-raw '{"id":123,"telnum":"801","datetype":"DAY_TYPE","begintime":"09:00:00","endtime":"18:00:00","operationtype":"VOICE_MAIL","parameters":"v100","offon":true,"groupname":"售后组"}'

4.4 删除规则

项值
optINTELLIGENT_ROUTING_DELETE
HTTP 方法GET
URL/bridge/jsoncfg?opt=INTELLIGENT_ROUTING_DELETE&json=<id>
参数json 为要删除的规则 id(数字字符串)

成功响应:

{
  "state": 200,
  "total": 0
}

注意:响应里没有 data 字段(值为 null,被 Gson 省略,见 §2.4)。

失败响应:{"state":400,"total":0}。常见原因:json 参数为空、非数字、id 不存在。

curl 示例:

curl 'http://127.0.0.1:12121/bridge/jsoncfg?opt=INTELLIGENT_ROUTING_DELETE&json=123'

5. 完整调用示例

5.1 curl 闭环(增 → 改 → 查 → 删 → 查)

把以下命令中的 <id> 替换为第 2 步 ADD 返回的真实 id。

第 1 步:新增规则

curl -X POST 'http://127.0.0.1:12121/bridge/jsoncfg?opt=INTELLIGENT_ROUTING_ADD' \
     -H 'Content-Type: application/json; charset=UTF-8' \
     --data-raw '{"telnum":"801","datetype":"DAY_TYPE","begintime":"08:30:00","endtime":"17:30:00","operationtype":"TRANSFER_CALL","parameters":"800","offon":true,"groupname":"售后组"}'

预期响应(注意 data[0].id,假设为 123):

{"state":200,"total":1,"data":[{"id":123,"telnum":"801","datetype":"DAY_TYPE","begintime":"08:30:00","endtime":"17:30:00","operationtype":"TRANSFER_CALL","parameters":"800","subbegintime":"00:00:00","subendtime":"23:59:59","offon":true,"groupname":"售后组"}]}

第 2 步:修改规则(把 id=123 改成语音邮箱)

curl -X POST 'http://127.0.0.1:12121/bridge/jsoncfg?opt=INTELLIGENT_ROUTING_UPDATE' \
     -H 'Content-Type: application/json; charset=UTF-8' \
     --data-raw '{"id":123,"telnum":"801","datetype":"DAY_TYPE","begintime":"09:00:00","endtime":"18:00:00","operationtype":"VOICE_MAIL","parameters":"v100","offon":true,"groupname":"售后组"}'

预期响应:

{"state":200,"total":1,"data":[{"id":123,"telnum":"801","datetype":"DAY_TYPE","begintime":"09:00:00","endtime":"18:00:00","operationtype":"VOICE_MAIL","parameters":"v100","subbegintime":"00:00:00","subendtime":"23:59:59","offon":true,"groupname":"售后组"}]}

第 3 步:查询全部,确认规则已生效

curl 'http://127.0.0.1:12121/bridge/jsoncfg?opt=INTELLIGENT_ROUTING_GET_ALL'

预期响应:

{"state":200,"total":1,"data":[{"id":123,"telnum":"801","datetype":"DAY_TYPE","begintime":"09:00:00","endtime":"18:00:00","operationtype":"VOICE_MAIL","parameters":"v100","subbegintime":"00:00:00","subendtime":"23:59:59","offon":true,"groupname":"售后组"}]}

第 4 步:删除规则

curl 'http://127.0.0.1:12121/bridge/jsoncfg?opt=INTELLIGENT_ROUTING_DELETE&json=123'

预期响应:

{"state":200,"total":0}

第 5 步:再次查询,确认已删除

curl 'http://127.0.0.1:12121/bridge/jsoncfg?opt=INTELLIGENT_ROUTING_GET_ALL'

预期响应:

{"state":200,"total":0,"data":[]}

5.2 Java OkHttp 客户端封装

以下是 OkHttp 4.x 的客户端示例。Maven 依赖:

<dependency>
  <groupId>com.squareup.okhttp3</groupId>
  <artifactId>okhttp</artifactId>
  <version>4.12.0</version>
</dependency>
<dependency>
  <groupId>com.google.code.gson</groupId>
  <artifactId>gson</artifactId>
  <version>2.10.1</version>
</dependency>

封装代码:

import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

import java.io.IOException;
import java.util.Arrays;
import java.util.List;

public class IntelligentRoutingClient {

    private static final MediaType JSON_TYPE = MediaType.get("application/json; charset=utf-8");

    private final OkHttpClient client = new OkHttpClient();
    private final Gson gson = new Gson();
    private final String baseUrl;

    public IntelligentRoutingClient(String host, int port) {
        this.baseUrl = "http://" + host + ":" + port + "/bridge/jsoncfg";
    }

    /** 新增规则,返回服务端分配的 id */
    public int addRule(IntelligentRoutingRule rule) throws IOException {
        String body = gson.toJson(rule);
        Request request = new Request.Builder()
                .url(baseUrl + "?opt=INTELLIGENT_ROUTING_ADD")
                .post(RequestBody.create(body, JSON_TYPE))
                .build();
        try (Response response = client.newCall(request).execute()) {
            JsonObject json = parseResponse(response);
            checkState(json);
            return json.getAsJsonArray("data").get(0).getAsJsonObject()
                    .get("id").getAsInt();
        }
    }

    /** 修改规则(rule.id 必填) */
    public void updateRule(IntelligentRoutingRule rule) throws IOException {
        String body = gson.toJson(rule);
        Request request = new Request.Builder()
                .url(baseUrl + "?opt=INTELLIGENT_ROUTING_UPDATE")
                .post(RequestBody.create(body, JSON_TYPE))
                .build();
        try (Response response = client.newCall(request).execute()) {
            checkState(parseResponse(response));
        }
    }

    /** 按 id 删除规则 */
    public void deleteRule(int id) throws IOException {
        Request request = new Request.Builder()
                .url(baseUrl + "?opt=INTELLIGENT_ROUTING_DELETE&json=" + id)
                .get()
                .build();
        try (Response response = client.newCall(request).execute()) {
            checkState(parseResponse(response));
        }
    }

    /** 查询全部规则 */
    public List<IntelligentRoutingRule> getAllRules() throws IOException {
        Request request = new Request.Builder()
                .url(baseUrl + "?opt=INTELLIGENT_ROUTING_GET_ALL")
                .get()
                .build();
        try (Response response = client.newCall(request).execute()) {
            JsonObject json = parseResponse(response);
            checkState(json);
            IntelligentRoutingRule[] rules = gson.fromJson(json.getAsJsonArray("data"),
                    IntelligentRoutingRule[].class);
            return Arrays.asList(rules);
        }
    }

    private JsonObject parseResponse(Response response) throws IOException {
        String body = response.body() != null ? response.body().string() : "{}";
        return JsonParser.parseString(body).getAsJsonObject();
    }

    private void checkState(JsonObject json) throws IOException {
        if (json.get("state").getAsInt() != 200) {
            throw new IOException("operation failed: state=" + json.get("state"));
        }
    }

    /** DTO 示例,字段与 IntelligentRoutingRule 对齐 */
    public static class IntelligentRoutingRule {
        public Integer id;
        public String telnum;
        public String datetype;
        public String begintime;
        public String endtime;
        public String operationtype;
        public String parameters;
        public String subbegintime;
        public String subendtime;
        public Boolean offon;
        public String groupname;
    }
}

调用示例:

public class Demo {
    public static void main(String[] args) throws Exception {
        IntelligentRoutingClient client = new IntelligentRoutingClient("127.0.0.1", 12121);

        // 新增
        IntelligentRoutingClient.IntelligentRoutingRule rule = new IntelligentRoutingClient.IntelligentRoutingRule();
        rule.telnum = "801";
        rule.datetype = "DAY_TYPE";
        rule.begintime = "08:30:00";
        rule.endtime = "17:30:00";
        rule.operationtype = "TRANSFER_CALL";
        rule.parameters = "800";
        rule.offon = true;
        rule.groupname = "售后组";
        int id = client.addRule(rule);
        System.out.println("新增成功,id=" + id);

        // 修改
        rule.id = id;
        rule.operationtype = "VOICE_MAIL";
        rule.parameters = "v100";
        client.updateRule(rule);

        // 查询
        System.out.println("当前规则数: " + client.getAllRules().size());

        // 删除
        client.deleteRule(id);
    }
}

6. 常见问题(FAQ)

Q1:何时用 POST,何时用 GET?

  • ADD / UPDATE:必须用 POST,JSON 放请求体。
  • DELETE / GET_ALL:用 GET,参数走 query。

不要把 rule JSON 拼到 query 参数 json= 上——URL 长度受限、+ 号编码有歧义、特殊字符容易出错。

Q2:HTTP 状态码 vs 响应 state 字段,以哪个为准?

服务端始终返回 HTTP 200。业务成败看响应 JSON 的 state 字段:200=成功,400=失败。客户端代码请只判断 state。

Q3:begintime/endtime 格式怎么填?

格式随 datetype 变化:

  • DAY_TYPE → HH:mm:ss(如 "08:30:00")
  • WEEK_TYPE → 整数 0–6(0=周日、6=周六)
  • MONTH_TYPE → 整数 1–31
  • SPECIFIED_DAY → yyyy-MM-dd HH:mm:ss

格式不对的规则不会生效,但服务端通常不会报错(只在路由时被忽略)。

Q4:telnum 含 + 号怎么办?

服务端会对请求做 URL 解码,未转义的 + 会被解析为空格。

  • 国际号码 +8613800138000 在请求体里要写成 %2B8613800138000。
  • 同样适用于 parameters 中如果含 + 号的号码字段。

Q5:subbegintime/subendtime 什么时候要填?

只在 datetype=WEEK_TYPE 时生效,其它 datetype 留空即可。默认值 00:00:00 / 23:59:59 表示当天全天生效。

Q6:为什么 UPDATE 后某些字段不见了?

UPDATE 是全字段覆盖语义,不是 patch。请求体里没传的字段会被覆盖为默认值。建议先 GET_ALL 取出原记录、改完字段后再整体提交。

Q7:支持批量操作吗?

不支持。一次调用处理一条规则。如需批量,客户端循环调用即可。

Q8:并发修改同一规则会怎样?

服务端无锁。多个并发请求修改同一 id 时,最后写入的覆盖前面的。如需强一致,请在客户端做串行化或加分布式锁。

Q9:规则改完立即生效吗?

是。新增/修改/删除后,下一次呼入即按新规则路由,无需重启服务。

Q10:GET_ALL 数据量太大怎么办?

接口不分页,一次返回全部规则。规则数 >1000 时,建议客户端做应用层缓存(如启动时拉取一次,定时增量刷新)。

Q11:怎么排查 state=400 的失败原因?

响应里没有错误详情字段。请联系服务端运维查服务端日志(异常堆栈会写入 ERROR 日志,关键字 JsonIntelligentRoutingService / process failed)。


附录:opt 取值速查表

opt方法URL
INTELLIGENT_ROUTING_GET_ALLGET/bridge/jsoncfg?opt=INTELLIGENT_ROUTING_GET_ALL
INTELLIGENT_ROUTING_ADDPOST/bridge/jsoncfg?opt=INTELLIGENT_ROUTING_ADD
INTELLIGENT_ROUTING_UPDATEPOST/bridge/jsoncfg?opt=INTELLIGENT_ROUTING_UPDATE
INTELLIGENT_ROUTING_DELETEGET/bridge/jsoncfg?opt=INTELLIGENT_ROUTING_DELETE&json=<id>

文档结束