AI 呼入
两种呼入接入方式:客户直接拨打平台号码(通过 API 开启呼入、设置号码、配置来电预查),或贵方呼叫中心经 SIP 转接并传参。
AI 呼入支持两种接入方式:
| 方式 | 来电路径 | 客户信息来源 | 章节 |
|---|---|---|---|
| 方式一:直拨平台号码 | 客户 → 项目线路号码 → 数字员工 | 来电预查:平台按来电号码调用贵方接口 | 3.1~3.6 |
| 方式二:SIP 转接 | 客户 → 贵方呼叫中心 → SIP 转接 → 数字员工 | 贵方在 X-Call-Params 中传入 | 3.7 |
两种方式均按 话单回调 推送话单。
3.1 方式一:前提与接口一览
前提:
- 企业已开通「协作呼入」,且 API Key 由企业主创建(平台 / 渠道管理员创建的 Key 不受限),否则修改类接口返回
403 - 数字员工已关联项目,项目已配置线路;呼入号码须为项目线路号码
| 接口 | 说明 | 所需权限 |
|---|---|---|
GET /api/v1/external/bots/:botId/inbound | 读取呼入配置 | READ |
PUT /api/v1/external/bots/:botId/inbound | 开关呼入、设置呼入号码 | CONTROL |
PUT /api/v1/external/bots/:botId/inbound/crm-query | 配置来电预查 | SCRIPT |
POST /api/v1/external/bots/:botId/inbound/crm-query/test | 测试来电预查 | SCRIPT |
:botId 取自 1.2 获取项目下数字员工列表。
完整开通示例:
# 1. 查看可用号码
curl "https://api.halfcall.cn/api/v1/external/bots/bot_xxx/inbound" -H "Authorization: Bearer sk_xxx"
# 2. 开启呼入,接听 02812345678
curl -X PUT "https://api.halfcall.cn/api/v1/external/bots/bot_xxx/inbound" \
-H "Authorization: Bearer sk_xxx" -H "Content-Type: application/json" \
-d '{ "enabled": true, "numbers": ["02812345678"] }'
# 3. 配置来电预查
curl -X PUT "https://api.halfcall.cn/api/v1/external/bots/bot_xxx/inbound/crm-query" \
-H "Authorization: Bearer sk_xxx" -H "Content-Type: application/json" \
-d '{ "enabled": true, "mode": "url", "url": "https://crm.example.com/api/customer", "auth": "bearer", "secret": "your_token" }'
# 4. 测试预查
curl -X POST "https://api.halfcall.cn/api/v1/external/bots/bot_xxx/inbound/crm-query/test" \
-H "Authorization: Bearer sk_xxx" -H "Content-Type: application/json" \
-d '{ "phone": "13800000000" }'
# 5. 开场白引用预查字段(见 4.2 更新话术)
curl -X PUT "https://api.halfcall.cn/api/v1/external/bots/bot_xxx/script" \
-H "Authorization: Bearer sk_xxx" -H "Content-Type: application/json" \
-d '{ "greeting": "您好{name},这里是某某客服中心,请问有什么可以帮您?" }'
3.2 读取呼入配置
GET /api/v1/external/bots/:botId/inbound(所需权限:READ)
{
"code": 0,
"msg": "success",
"data": {
"botId": "bot_xxx",
"programId": "cmk...",
"canManage": true,
"enabled": true,
"numbers": ["02812345678"],
"availableNumbers": ["02812345678", "02887654321"],
"crmQuery": {
"enabled": true,
"mode": "url",
"url": "https://crm.example.com/api/customer",
"method": "GET",
"auth": "bearer",
"hasSecret": true,
"headerNames": ["appid"],
"timeout": 3,
"toolId": null
},
"crmQueryTools": [
{ "toolId": "tool_xxx", "name": "query_meeting", "displayName": "会议查询" }
],
"crmQueryFields": ["name", "orgName"]
}
}
| 字段 | 说明 |
|---|---|
| programId | 关联的项目 ID,未关联时为 null |
| canManage | 当前 Key 是否有权修改呼入配置 |
| enabled | 是否已开启呼入 |
| numbers | 接听号码;空数组表示接听项目全部线路号码 |
| availableNumbers | 可设为呼入号码的项目线路号码 |
| crmQuery | 来电预查配置(字段见 3.4);密钥仅返回 hasSecret,请求头仅返回名称 headerNames |
| crmQueryTools | 可用于工具方式的已绑定 MCP 工具 |
| crmQueryFields | 近 30 天带入通话的预查字段名 |
3.3 开关呼入、设置呼入号码
PUT /api/v1/external/bots/:botId/inbound(所需权限:CONTROL)
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| enabled | boolean | ✓ | 开启 / 关闭呼入 |
| numbers | string[] | 接听号码,须在 availableNumbers 中;不传或空数组表示全部线路号码 |
// 请求
{ "enabled": true, "numbers": ["02812345678"] }
// 响应
{ "code": 0, "msg": "已保存,立即生效", "data": { "botId": "bot_xxx", "enabled": true, "numbers": ["02812345678"] } }
// 号码不属于项目线路
{ "code": -1, "msg": "13900000000 不属于当前项目任何一条线路的号码,请检查后重填" }
立即生效,无需重新发布。同一号码只能由一个数字员工接听,被占用时返回
400。
3.4 配置来电预查
来电接通时,平台以来电号码查询贵方系统,查询结果作为变量带入通话(开场白、提示词可引用)。
PUT /api/v1/external/bots/:botId/inbound/crm-query(所需权限:SCRIPT)
字段均可选,仅更新传入字段:
| 字段 | 类型 | 说明 |
|---|---|---|
| enabled | boolean | 开启 / 关闭;开启前须已配置 url 或 toolId |
| mode | string | url 接口地址 / tool 绑定工具(须同时传 toolId) |
| url | string | 查询接口地址,仅限公网 http / https |
| method | string | GET(默认)/ POST |
| auth | string | none(默认)/ basic / bearer / apikey |
| secret | string | 认证密钥 |
| headers | object | 自定义请求头,整体替换,如 {"appid": "xxx"} |
| timeout | number | 超时秒数 1~10;默认接口地址 5 秒、工具 3 秒,建议 ≤ 3 |
| toolId | string | 取自 crmQueryTools[].toolId |
// 接口地址方式
{ "enabled": true, "mode": "url", "url": "https://crm.example.com/api/customer", "method": "POST", "auth": "apikey", "secret": "your_key", "headers": { "appid": "10001" }, "timeout": 3 }
// 工具方式
{ "enabled": true, "mode": "tool", "toolId": "tool_xxx" }
// 关闭
{ "enabled": false }
{ "code": 0, "msg": "success", "data": { "botId": "bot_xxx", "crmQuery": { "enabled": true, "mode": "url", "...": "同 3.2" } } }
3.4.1 接口地址方式:贵方接口规范
请求(以 method=POST、auth=apikey 为例):
POST /api/customer HTTP/1.1
Host: crm.example.com
Content-Type: application/json
X-API-Key: your_key
appid: 10001
{ "phone": "13800000000" }
method=GET 时号码放在查询参数:GET /api/customer?phone=13800000000。
| auth | 请求头 |
|---|---|
| basic | Authorization: Basic <Base64(secret)> |
| bearer | Authorization: Bearer <secret> |
| apikey | X-API-Key: <secret> |
响应:JSON 对象,顶层 key 即变量名:
{ "name": "张三", "orgName": "某某市人民医院", "level": "VIP" }
→ 通话中可用 {name}、{orgName}、{level}。非 2xx、非 JSON 对象或超时视为未查到。
3.4.2 工具方式:返回值转换规则
来电号码传入工具的 phone 参数(无 phone 参数时传入第一个必填参数)。工具返回的 data 转换为变量:
data 中的值 | 变量 |
|---|---|
"orgName": "某某市卫健委" | {caller_orgName} = 某某市卫健委 |
"found": false | {caller_found} = false |
"remark": null | 不生成 |
"leads": [...] | {caller_leads} = 数组 JSON 字符串 |
leads[].variables 中各条取值相同的字段,如 "单位名称" | {caller_单位名称} |
工具方式统一加
caller_前缀,避免与 MCP 工具同名参数冲突(工具参数会被通话中的同名变量自动填充)。
来电人仅有一条 leads 且带 meetingId、通话中无办理操作时,话单 meetings 带一条 action=inquiry 记录,见 话单回调。
3.5 测试来电预查
POST /api/v1/external/bots/:botId/inbound/crm-query/test(所需权限:SCRIPT)
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| phone | string | ✓ | 测试号码 |
| 3.4 中的配置字段 | 临时覆盖已保存配置,仅本次生效,不保存 |
// 请求:用临时地址试查
{ "phone": "13800000000", "url": "https://crm-test.example.com/api/customer" }
// 响应
{
"code": 0,
"msg": "success",
"data": {
"fields": { "name": "张三", "orgName": "某某市人民医院" },
"raw": { "name": "张三", "orgName": "某某市人民医院" },
"error": null,
"elapsedMs": 236
}
}
// 未查到
{ "code": 0, "msg": "success", "data": { "fields": {}, "raw": null, "error": "超时(3 秒)", "elapsedMs": 3002 } }
| 字段 | 说明 |
|---|---|
| fields | 带入通话的变量 |
| raw | 接口 / 工具原始返回 |
| error | 未查到的原因,查到时为 null |
| elapsedMs | 耗时(毫秒);超过 3000 时通话中可能取不到结果 |
3.6 引用预查变量
| 位置 | 写法 | 说明 |
|---|---|---|
| 开场白 | {name} / {caller_xxx} | 开场白在对话前播放,只能通过变量取值 |
| 提示词 | 同上 | 未引用的预查结果也会附在提示词末尾供 AI 参考 |
- 预查变量无需加入线索字段
- 通话接通后最多等待约 3 秒,未查到时变量替换为空、不影响接听;
{user_phone}、{phone4}、{current_time}始终可用 - 开场白应保证变量为空时语句仍通顺
示例:会议通知呼入(工具方式)
// 工具返回 data
{
"found": true,
"name": "李四",
"orgName": "某某市卫健委",
"leads": [
{ "meetingId": "M20261023001", "variables": { "单位名称": "某某市人民医院", "会议时间": "10月25日上午9点" } }
]
}
开场白模板:您好,我是{caller_orgName}会议通知助理,{caller_单位名称}的{caller_name}您好,关于{caller_会议时间}的会议……
实际播报: 您好,我是某某市卫健委会议通知助理,某某市人民医院的李四您好,关于10月25日上午9点的会议……
3.7 方式二:SIP 转接
贵方转接时在 SIP Header 中带上数字员工 ID 和客户参数。无需开启 3.3 的呼入开关;可与来电预查同时使用。
3.7.1 参数说明
贵方转接时可通过 SIP Header 传入自定义参数,系统接收后在提示词中替换对应变量,实现个性化呼入体验。参数需提前在平台配置好字段定义,以下为示例(实际字段以平台配置为准):
| 参数 KEY | 参数名称 | 说明 | 是否必须 |
|---|---|---|---|
| user_phone | 用户手机号 | 用户手机号 | ✓ |
| variable3 | 用户的姓名 | 用户的姓名 | ✓ |
| variable10 | 用户欠费的金额 | 用户欠费的金额 | ✓ |
| variable2 | 余额50需充值金额 | 余额50需充值金额 | ✓ |
| variable4 | 余额一百需充值金额 | 余额一百需充值金额 | ✓ |
| variable9 | 用户欠费的手机号 | 用户欠费的手机号 | ✓ |
3.7.2 SIP Header 说明
| Header | 必填 | 说明 |
|---|---|---|
sip_h_X-BotId | ✓ | AI 数字员工唯一标识(即 1.2 获取项目下数字员工列表 中获取的 botId) |
sip_h_X-Call-Params | ✓ | 呼入参数,JSON 对象经 Base64 编码后的字符串 |
sip_h_X-Call-ID | ✓ | 本次呼入的唯一标识,全局唯一;通话结束后可凭此 ID 通过回调或查询接口获取结果 |
origination_uuid | ✓ | 发起方 UUID,由贵方外呼系统生成 |
3.7.3 参数编码
将所有参数组成 JSON 对象,整体做 Base64 编码后放入 sip_h_X-Call-Params:
function encodeCallParams(params) {
return Buffer.from(JSON.stringify(params)).toString('base64')
}
const encoded = encodeCallParams({
user_phone: "18888888888",
variable3: "张三",
variable10: "150.00",
variable2: "200.00",
variable4: "250.00",
variable9: "18811111111",
})
// eyJ1c2VyX3Bob25lIjoiMTg4ODg4ODg4ODgiLCJ2YXJpYWJsZTMiOiLlvKDkuIkiLCJ2YXJpYWJsZTEwIjoiMTUwLjAwIiwidmFyaWFibGUyIjoiMjAwLjAwIiwidmFyaWFibGU0IjoiMjUwLjAwIiwidmFyaWFibGU5IjoiMTg4MTExMTExMTEifQ==
3.7.4 FreeSWITCH 转发示例
originate {
ignore_early_media=true,
origination_uuid=001
} user/1001 &bridge({
sip_h_X-BotId=85488662,
sip_h_X-Call-Params=eyJ1c2VyX3Bob25lIjoiMTg4ODg4ODg4ODgiLCJ2YXJpYWJsZTMiOiLlvKDkuIkiLCJ2YXJpYWJsZTEwIjoiMTUwLjAwIiwidmFyaWFibGUyIjoiMjAwLjAwIiwidmFyaWFibGU0IjoiMjUwLjAwIiwidmFyaWFibGU5IjoiMTg4MTExMTExMTEifQ==,
sip_h_X-Call-ID=callid_20250720_083123,
ignore_early_media=false,
origination_uuid=001
} sofia/external/sip:85488662@<SIP_HOST>:<SIP_PORT>)
<SIP_HOST>:<SIP_PORT>为平台 SIP 接入地址,提交贵方服务器出口 IP 加入白名单后,由平台单独提供。
sip_h_X-Call-ID建议格式:callid_{yyyyMMdd}_{HHmmss}_{随机串},通话结束后可凭此 ID 通过回调接收或主动查询结果。
话单回调:通话结束后系统会主动向业务服务器推送话单(含通话记录、意向结果、对话日志),推送地址/签名规则/请求体等说明见 Webhook 参考。