关于 setup-sip-trunk
为 Bolna Agent 配置自带 SIP 中继(BYOT)的技能,涵盖中继、号码和入站路由的设置,以及入站和出站呼叫的 API 流程。
主要功能
- 01创建和管理 SIP 中继
- 02注册及管理 DID 号码
- 03将入站 DID 映射到 Agent
- 04配置出站呼叫路由
- 05设置传输与媒体加密
适用场景
- 01沿用现有运营商号码处理呼叫
- 02通过 SIP 中继发起出站呼叫
- 03将入站号码连接到 Bolna Agent
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ bolna-ai/ skills --skill setup-sip-trunk安装后在 Claude Code 中输入/setup-sip-trunk确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/plivo-zentrunk.mdtwilio-elastic.mdscripts/add_trunk_number.pycreate_sip_trunk.pydiagnose_trunk.py详细介绍
Bolna SIP 中继(BYOT)
使用任何符合标准的 SIP 中继——Twilio Elastic SIP、Plivo Zentrunk、Telnyx、Vonage、Zadarma、DIDWW 或你自己的运营商——处理由 Bolna Agent 接听和拨出的电话。
Beta。 SIP 中继需要企业版访问权限。如果 API 调用返回访问错误,请先联系
[email protected],再更改代码。
为什么使用 BYOT
| 原因 | 详情 |
|---|---|
| 保留现有运营商关系 | 无需携号转网,也不会产生并行账单。 |
| 协商费率 | Bolna 不会加价收取你的通话时长费用。 |
| 号码可携带性 | 使用你已有的号码。 |
| 合规性/区域运营商 | 当地法规要求使用特定运营商时必需。 |
高层级流程
1. Provider portal: Whitelist 13.200.45.61, set origination URI to sip.bolna.ai
2. POST /sip-trunks/trunks → create trunk in Bolna
3. POST /sip-trunks/trunks/{id}/numbers → register your DIDs on the trunk
4. PATCH /v2/agent/{id} telephony_provider=sip-trunk (for outbound)
5. POST /inbound/setup → link DID ↔ agent (for inbound)
6. POST /call with from_phone_number = your DID → outbound dial
步骤 0 — 在 SIP 提供商的门户中
将 Bolna 的 IP 加入白名单
13.200.45.61
将此项添加到提供商的允许 IP/ACL/可信 IP 列表中。否则,Bolna 的出站 INVITE 和 RTP 数据包会被丢弃。
对于 ip-based 身份验证,这也是中继用于识别 Bolna 的 IP。
设置始发 URI(用于入站)
| 中继传输方式 | 始发 URI |
|---|---|
| UDP 或 TCP | sip:sip.bolna.ai:5060 |
| TLS | sip:sip.bolna.ai:5061;transport=tls |
如果提供商只接受 IP,请在 UDP/TCP 中使用 sip:13.200.45.61:5060。TLS 入站必须使用主机名,以便运营商验证 Bolna 的 TLS 证书。
可按每个 DID 分别设置,也可在整个中继上设置——具体取决于提供商。
编解码器
默认使用 G.711 ulaw。至少允许 ulaw(最好也允许 alaw)。避免使用 G.729 和其他压缩编解码器。
端点
| 方法 | 路径 | 用途 |
|---|---|---|
POST | /sip-trunks/trunks | 创建中继 |
GET | /sip-trunks/trunks | 列出中继 |
GET | /sip-trunks/trunks/{trunk_id} | 获取一个中继 |
PATCH | /sip-trunks/trunks/{trunk_id} | 更新中继 |
DELETE | /sip-trunks/trunks/{trunk_id} | 删除中继 |
POST | /sip-trunks/trunks/{trunk_id}/numbers | 添加 DID |
GET | /sip-trunks/trunks/{trunk_id}/numbers | 列出 DID |
DELETE | /sip-trunks/trunks/{trunk_id}/numbers/{phone_number_id} | 移除 DID |
POST | /inbound/setup | 将 DID 的 phone_number_id 映射到 Agent |
POST | /inbound/unlink | 取消映射 |
所有路径都位于 https://api.bolna.ai 下。身份验证:Authorization: Bearer $BOLNA_API_KEY。
示例:Twilio Elastic SIP(userpass)
curl -X POST https://api.bolna.ai/sip-trunks/trunks \
-H "Authorization: Bearer $BOLNA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Twilio Production",
"provider": "twilio",
"description": "Main Twilio Elastic SIP trunk",
"auth_type": "userpass",
"auth_username": "<your-sip-username>",
"auth_password": "<your-sip-password>",
"gateways": [
{ "gateway_address": "your-trunk.pstn.twilio.com", "port": 5060, "priority": 1 }
],
"transport": "transport-udp",
"allow": "ulaw,alaw",
"disallow": "all",
"inbound_enabled": true,
"outbound_leading_plus_enabled": true
}'
响应中包含中继 id。请保存。
示例:Plivo Zentrunk(ip-based)
curl -X POST https://api.bolna.ai/sip-trunks/trunks \
-H "Authorization: Bearer $BOLNA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Plivo Zentrunk",
"provider": "plivo",
"auth_type": "ip-based",
"gateways": [
{ "gateway_address": "21467306465797919.zt.plivo.com", "port": 5060, "priority": 1 }
],
"ip_identifiers": [
{ "ip_address": "15.207.90.192/31" },
{ "ip_address": "204.89.151.128/27" },
{ "ip_address": "13.52.9.0/25" }
],
"transport": "transport-udp",
"inbound_enabled": true
}'
ip_identifiers 是运营商的出口 IP。Plivo、Telnyx 等会公布这些 IP。
示例:TLS + SDES(加密媒体)
适用于支持信令和媒体加密的运营商:
curl -X POST https://api.bolna.ai/sip-trunks/trunks \
-H "Authorization: Bearer $BOLNA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Twilio Production (encrypted)",
"provider": "twilio",
"auth_type": "userpass",
"auth_username": "<u>",
"auth_password": "<p>",
"gateways": [
{ "gateway_address": "your-trunk.pstn.twilio.com", "port": 5061, "priority": 1 }
],
"transport": "transport-tls",
"media_encryption": "sdes",
"media_encryption_optimistic": false,
"inbound_enabled": true
}'
| 参数 | 作用 |
|---|---|
transport: "transport-tls" | 加密 SIP 信令。端口为 5061。 |
media_encryption: "sdes" | 使用 SDP 交换密钥的 SRTP。需要 TLS 传输。 |
media_encryption_optimistic: true | 如果运营商不提供加密,则回退到普通 RTP。适用于测试。 |
你的运营商也必须在其一端启用 SDES/SRTP——否则,SIP 呼叫虽能建立,但媒体无法建立(通话无声)。
向中继添加 DID 号码
curl -X POST "https://api.bolna.ai/sip-trunks/trunks/$TRUNK_ID/numbers" \
-H "Authorization: Bearer $BOLNA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"phone_number": "919876543210",
"name": "Mumbai Support Line"
}'
响应中包含 phone_number_id——这是进行入站映射时要使用的 ID。请保存。 Bolna 会原样存储号码字符串;入站匹配时查找可有可无 +,但请保持一致。
从中继拨打出站电话
更新 Agent,使 Bolna 通过你的中继路由:
curl -X PATCH "https://api.bolna.ai/v2/agent/$AGENT_ID" \
-H "Authorization: Bearer $BOLNA_API_KEY" \
-H "Content-Type: application/json" \
-d '{"agent_config":{"telephony_provider":"sip-trunk"}}'
然后照常拨打电话——from_phone_number 必须是已在中继上注册的 DID:
curl -X POST https://api.bolna.ai/call \
-H "Authorization: Bearer $BOLNA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"agent_id": "'$AGENT_ID'",
"recipient_phone_number": "+918800001234",
"from_phone_number": "+919876543210"
}'
呼入中继的电话
注册 DID 后,将其映射到 Agent:
curl -X POST https://api.bolna.ai/inbound/setup \
-H "Authorization: Bearer $BOLNA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"agent_id": "'$AGENT_ID'",
"phone_number_id": "'$PHONE_NUMBER_ID'"
}'
Bolna 会自动将 Agent 的音频格式设为 ulaw,以符合通过 SIP 路由的呼叫对 Asterisk 的要求。
一个号码对应一个 Agent。 将 DID 重新映射到新的 Agent 时,会自动取消其与之前 Agent 的映射。若要在不重新映射的情况下解除关联,请使用相同的请求体调用 POST /inbound/unlink。
创建中继字段参考
| 字段 | 类型 | 必填 | 默认值 | 备注 |
|---|---|---|---|---|
name | string | 是 | — | 账户内唯一。 |
provider | string | 是 | — | twilio、plivo、telnyx、vonage、custom 等。 |
description | string | 否 | null | 内部使用。 |
auth_type | string | 是 | — | userpass 或 ip-based。 |
auth_username / auth_password | string | 有条件必填 | — | 当 auth_type == "userpass" 时必填。 |
gateways[] | array | 是 | — | 一个或多个 {gateway_address, port, priority}。 |
ip_identifiers[] | array | 有条件必填 | [] | 当 auth_type == "ip-based" 时必填。包含 {ip_address} 列表。 |
allow | string | 否 | "ulaw,alaw" | 以逗号分隔的编解码器。始终包含 ulaw。 |
disallow | string | 否 | "all" | 以逗号分隔的编解码器。 |
transport | enum | 否 | "transport-udp" | transport-udp、transport-tcp、transport-tls。 |
media_encryption | enum | 否 | "no" | no 或 sdes。sdes 需要 transport-tls。 |
media_encryption_optimistic | bool | 否 | false | 如果运营商不提供加密,则回退到未加密的 RTP。 |
inbound_enabled | bool | 否 | false | 开启后可接收来电。 |
outbound_leading_plus_enabled | bool | 否 | true | 拨出时在号码前添加 +。部分运营商会拒绝 +。 |
direct_media | bool | 否 | false | 保持为 false。 |
rtp_symmetric | bool | 否 | true | NAT 所必需。 |
force_rport | bool | 否 | true | NAT 所必需。 |
qualify_frequency | int | 否 | 60 | SIP OPTIONS ping 的间隔秒数;0 表示禁用。 |
phone_numbers[] | array | 否 | [] | 创建时可选添加的初始 DID。 |
故障排除
呼入通话已接通,但只有单向音频或没有音频
最常见的原因:Bolna 与运营商之间 SRTP 不匹配。
- 运营商已禁用 SRTP,但 Bolna 上的
media_encryption: "sdes"→ 设置media_encryption: "no",或调整运营商设置使其一致。 - 快速测试:
media_encryption_optimistic: true会回退到未加密的 RTP。 - 在通话建立正常前完全跳过加密:
transport-udp+media_encryption: "no"。
422 media_encryption='sdes' requires transport='transport-tls'
SDES 密钥通过 SDP 传输,因此需要加密信令。可以:
- 将
transport切换为transport-tls(并将网关上的port: 5061),或 - 设置
media_encryption: "no"。
呼出 INVITE 一直响铃 / 在某个运营商上无提示地失败
UDP 分片。运营商在 INVITE 中添加了较大的标头(较长的 Diversion、多个 Route、P-Asserted-Identity),导致 UDP 数据包超过 MTU。
解决方法:transport: "transport-tcp"。无需使用 TLS — 单独使用 TCP 即可避免分片。
完全没有呼入通话
按以下顺序逐项检查:
- 运营商上的 Origination URI 是否设置为
sip:sip.bolna.ai:5060(或:5061;transport=tls)? - 是否通过
POST /sip-trunks/trunks/{id}/numbers将 DID 添加到了中继? - 中继上的
inbound_enabled: true是否已设置? - 是否通过
POST /inbound/setup将 DID 映射到 Agent? - 运营商是否已将 Bolna IP
13.200.45.61加入允许名单? - INVITE 的
Request-URI或To标头是否与存储的号码格式匹配(带+或不带+)?
呼出时 from_phone_number 被拒绝
from_phone_number必须是已注册到中继的 DID(/sip-trunks/trunks/{id}/numbers)。- Agent 的
telephony_provider必须更新为sip-trunk。 - 中继上的
is_active: true。 - 部分运营商会拒绝拨出号码前导的
+— 请切换outbound_leading_plus_enabled以匹配运营商要求。
userpass 身份验证失败
重新检查运营商门户中的 SIP 凭据 — 它们与账户凭据分开。Twilio Elastic SIP 使用专门用于 SIP REGISTER 身份验证的 “Credential List”。
安全
删除中继会级联删除其网关、IP 标识符和号码映射。活跃的呼入和呼出将立即停止。执行 DELETE /sip-trunks/trunks/{id} 前,务必先征得用户确认。
深入了解
| 文件 | 内容 |
|---|---|
references/twilio-elastic.md | Twilio Elastic SIP 端到端设置,包含运营商侧的准确界面截图。 |
references/plivo-zentrunk.md | Plivo Zentrunk 设置,包括 ip_identifiers。 |
scripts/create_sip_trunk.py | 封装 POST /sip-trunks/trunks。 |
scripts/add_trunk_number.py | 封装 POST /sip-trunks/trunks/{id}/numbers。 |
scripts/diagnose_trunk.py | 读取中继、号码和活动映射,用于排查问题。 |
另请参阅
setup-inbound— DID 到 Agent 的映射(对 Bolna 托管的 DID 和 SIP 中继 DID 采用相同方式)。make-call— 出站 API;telephony_provider为sip-trunk时,工作方式相同。manage-phone-numbers— Bolna 托管的 DID(BYOT 的替代方案)。https://raw.githubusercontent.com/bolna-ai/skills/main/references/india-compliance.md— 即使使用自己的中继,您的号码仍须满足 DLT 要求。