XSwitch Cloud
小樱桃 XSwitch 声网 SIP-PSTN 网关
RTC 与 SIP 互转,PSTN 对接落地。支持声网转 SIP、SIP 转声网、SIP 加入声网会议等,提供 PSTN 号码资源、用户也可以对接自己的 PSTN 中继。
功能
XSwitch Cloud 目前支持如下功能和场景:
- 声网转 SIP(PSTN):声网 App 客户端可以呼叫 SIP 终端或 PSTN 电话号码,实现一对一通话。
- SIP(PSTN)转声网:SIP 设备或 PSTN 电话可以呼入声网频道,跟 App 一对一通话。
- SIP 呼入声网会议:SIP 设备或 PSTN 电话可以呼入声网频道,实现多对多会议。
- 邀请 SIP(PSTN)用户加入声网会议:通过 API,可以
- 多租户
XSwitch Cloud 使用云计算技术和分布式技术构建,支持多租户、支持弹性伸缩。
XSwitch Cloud 提供简单易用的 API,可以快速开通和对接应用。
XSwitch Cloud 提供优质 PSTN 号码资源和落地对接,可以快速打通电话。
优势
- 两个 REST API 实现 SIP 呼入、呼出
- 支持自动选择呼出号码(线路)
- 支持指定呼出号码(线路)
使用指南
理解 XSwitch 云平台
XSwitch 云平台是一个多租户的通信平台,每个租户对应一个“域”(域名),如小樱桃对应:cherry.xswitch.cn。
页面访问及 API 接口调用地址统一为https://cloud.xswitch.cn/api/cloud,访问时或调用相应的 API 时通过传入的用户名、密码、域名进行分离。
租户可以直接使用主域名进行测试和使用。如果一个租户内有多个项目需要隔离(不同的号码段、号码池及话单),则可以在租户内建立下级租户。由于安全及审核的需要,目前下级租户的开通需要联系客服手工创建。后期将可以开通 Web 控制台自助管理。
前期准备
重要:
- 在声网网站上开通声网账号 https://www.shengwang.cn/ 。
- 在声网控制台上添加一个项目,如“XSwitch Cloud Test”:
- 简单起见,创建项目时,“鉴权机制”可以填调试模式,等调试通过后再关闭。
- 如果使用安全模式,则可以在项目控制台上生成一个临时的 Token。
- 下面,需要使用声网 Token 的地方都兼容临时 Token 和项目 App ID。
准备好后可以先到 https://xswitch.cn/agora/basicVoiceCall/index.html 测试,打开两个网页,输入相同的 App ID、Token(可选)及 Channel Name 后,分别点击【Join】可以互相通话,点击【Leave】离开。
使用流程
- 准备相关信息
- 是否需要 XSwitch 提供 PSTN 号码,还是自带 SIP 中继
- 如果需要 XSwitch 提供 PSTN 号码,需要提供以下信息
- 落地城市
- 呼入、呼出,还是双向
- 号码数量
- 每线并发数
- 普通号码还是需要 AXB 号码
- 业务类型、使用场景
- 业务类型、相应的话术等
- 公司名称,用于开通租户
- 相应的域名,用于开通租户,域名以
xswitch.cn结尾,如cherry.xswitch.cn是小樱桃的域名。 - 呼叫服务器回调地址,如
https://cherry.xswitch.cn/api/callback/agora-callback。
- 从声网云市场购买 XSwitch SIP-PSTN 网关
- XSwitch 开发者账号(线下获取)
由于 PSTN 号码安全管控需要,PSTN 号码开通流程需要通过线下进行,视情况可能需要 1 ~ 7 个工作日。
系统架构
系统总体架构如下图所示:
系统集成逻辑如下图所示:
其中,业务侧的 App 集成声网 SDK,App 连接自己的后台服务器(上图中的“业务侧服务器”)。后台服务器与 XSwitch 交互控制相关呼叫逻辑。详细呼叫流程如下节所述。
呼叫流程
有 SIP 参与的基本呼叫流程如下。
声网呼 SIP
声网 App 客户端呼叫 SIP。
- App 从业务侧服务器后台获取声网 token、channel、uid 等信息,(在调试模式下,token 的值也可以填 App ID 的值)。
- App 加入 channel。
- App 通知服务器呼叫手机。
- 服务器调用外呼 API,呼叫手机。
- XSwitch 收到外呼请求,将声网模块加入与 App 相同的 channel。
- XSwitch 通过 SIP 模块呼叫运营商。
- 手机振铃接听。
- App 与手机通话。
注:声网 App 侧可能是任何的声网 SDK 客户端,如果没有现成的客户端,可以使用如下在线网页测试:
SIP 呼叫声网 App
- 手机呼叫一个 PSTN 号码进入 XSwitch。
- XSwitch 根据号码找到相关的租户信息,回调租户提供的 API 接口(业务侧服务器)。
- 业务侧服务器返回声网 token、channel、uid 等信息。
- XSwitch 将声网模块加入对应的 channel。
- 业务服务器通知 App 加入相关的 channel。
注:以上最后三步的顺序可根据自己的业务逻辑调整。
呼叫进展消息
CREATEorSTART:开始RINGING:振铃MEDIA:媒体建立ANSWERED:应答BRIDGE:桥接UNBRIDGE: 断开桥接DESTROY:挂机
呼入
呼出,其中,M 代表有媒体,N 代表ignore_early_media=true的情况。
通话记录推送
获取通话记录,目前支持话单事件推送方式也支持【XCC】订阅方式。
- 话单事件推送
原始话单事件推送目前支持 JSON 以及 XML 格式推送
- XCC 订阅方式
XCC 订阅方式,启用 NATS 服务。此时业务方可使用熟悉的后端语言(提供go、java、python、js等语言示例),启动订阅程序。当有通话结束时,该服务即可订阅到对应话单。
挂机流程
在一对一通话中,当通话建立后,会生成一个唯一的通话UUID,可以通过 REST API 的DELETE接口,挂断指定UUID对应的通话。
系统也支持“自动”挂机:
当 XSwitch 侧的声网 Linux SDK 加入一个channel后,如果检测到另一个uid加入相同的channel并离开,当前channel中只剩下 Linux SDK 时,XSwitch 侧的 Linux SDK 会自动退出channel,SIP 侧挂机。
在实际使用时,App 侧也可以使用相同的逻辑,检测到channel中的uid数从2变成1时自动挂机。
API 接口
下面是涉及到的 API 接口,示例主要以cURL形式描述,文末有相关的示例代码。
鉴权
业务侧调用 XSwitch 鉴权
XSwitch Cloud 支持通过 API 方式访问。使用 Session/Token 的鉴权方式,业务侧通过认证 API 拿到 Token 后,即可携带 Token 访问有权限认证的接口。
业务侧通过“用户名”、“密码”、“域名”及“jwt”发起请求,系统返回一个 JWT 格式的 Token。
请求参数说明
| 参数 | 必选 | 类型 | 备注 |
|---|---|---|---|
| login | 是 | string | 用户名 |
| password | 是 | string | 密码 |
| domain | 是 | string | 用户域 |
| jwt | 是 | string | true,返回 JWT Token |
POST /api/cloud/token
示例
curl -X POST https://cloud.xswitch.cn/api/cloud/token \ -H 'Content-Type: application/json' \ -d '{ "login": "cloud_xxx", "password": "xxx", "domain": "cherry.xswitch.cn", }'
正常返回一个 JSON Object。
code:结果代码token:string,可用作 Token (X-XTRA-AUTH-ID)expires:int,UNIX 时间戳,过期时间refresh_token: refresh token 用于更新 token
如果出错,返回 HTTP 状态码如403(用户名/密码错)500(内部错误)等。
产生 JWT Token 示例:
{ "code": 200, "expires": 1692576984, "refresh_token": "ey...", "token": "ey..." }
当 token 过期后,可以使用上面的refresh_token来属性新的 token 使用refresh_token来产生新的 JWT Token 示例:
curl -X POST https://cloud.xswitch.cn/api/cloud/token \ -H 'Content-Type: application/json' \ -d '{ "refresh_token": "ey..." }'
返回结果可以参考上面的示例。
XSwitch 回调业务侧接口鉴权
XSwitch 回调业务侧接口时,可以使用 IP 地址白名单鉴权。目前,XSwitch 回调的 IP 地址如下,请加入防火墙白名单:
212.129.138.139 43.140.224.96 211.159.171.210 211.159.155.29 211.159.155.30 49.232.232.170
此外,XSwitch 在回调时可以在 JSON 中携带一个事先约定的cookie字符串,服务侧也可以根据该cookie字符串鉴权。
外呼接口
通过接口呼叫 PSTN,采用 JSON 格式。当发起外呼时,需客户侧提供 domain、token、channel、uid、destNumber 必选参数。
发起外呼后,查询trunks表,根据domain确定remote_add(外呼时选的线路地址),从而实现呼叫指定被叫号码并加入到指定的 agora 通道
外呼参数如下:
domain:域,必选,必须与认证信息中的域相同。appid:字符串,声网 AppId。token:必选,加密的 Agora Token,生成方式为0+频道名。channel:必选,字符串。uid:字符串,必选 声网 uid。destNumber:必选,被叫号码,如186xxxxxxxx。其中10000200是小樱桃提供的虚拟测试号码,自动接听,参见测试号码。cidName:可选,字符串,如不选系统自动分配。cidNumber:可选,字符串,如不选系统自动分配。uuid:可选,UUIDv4 格式,呼出的 SIP Channel 的 UUID,可用于跟业务侧的呼叫 ID 关联。areaCode:可选,字符串,区域码对应的 INT 值。encryptMode:可选,字符串,加密模式对应的 INT 值。encryptKey:字符串,如果指定了加密模式,则必须指定加密 Key。encryptSalt:可选,字符串,加密 Salt,部分加密模式不需要 Salt。
POST /api/cloud/callPSTN
curl -X POST https://cloud.xswitch.cn/api/cloud/callPSTN \ -H 'Authorization: Bearer eyJxxx.yyy.zzz' \ -H 'Content-Type: application/json' \ -d '{ "destNumber": "10000200", "token": "9fd575ca8600xxxxxxxxxxxx", "channel": "xswitch-cloud", "domain": "cherry.xswitch.cn" }'
返回 JSON:
code:代码,成功返回200。message:信息描述,成功为success。data:SIP 通话 UUID@hash_str,可用于挂机接口的uuid参数。
{ "code": 200, "message": "success", "data": "0bee39f2-...@JaJoJk..." }
呼入接口
呼入接口由业务侧提供 URL。即业务方根据如下接口约定提供所需 Agora 信息接口用于呼入。
SIP 呼入后,XSwitch Cloud会根据主叫号码、域名等查找DID从而查找到该租户对应的 URL, 并发送 POST 请求,数据使用 JSON 格式。所有字符串均使用 UTF-8 编码(如下所示例子)。
请求参数:
ver:协议版本号,目前固定为1.0uuid:当前通话唯一 IDcidName:字符串,主叫名称cidNumber:字符串,主叫号码destNumber:字符串,被叫号码domain:当前租户对应的域remoteAddr:远端 IP 地址cookie:可选字符串,由业务方提供,可用于鉴权
返回 JSON:
token:必选,加密的 Agora Token 或不加密的 App IDchannel:必选,字符串uid:字符串,可选,如不存在或为空则自动选择(缺省设置为cidName主叫名称)cidName:可选,字符串,覆盖主叫用户名称cidNumber:可选,字符串,覆盖主叫用户号码
agora客户接口模拟测试(其中agora-call-in为客户侧自主提供的接口 URL):
curl -XPOST -H "Content-Type: application/json" -d '{"ver":"1.0","uuid":"fbb53115-f52d-625xxxxx","cidName":"test","cidNumber":"10010","destNumber":"777","domain":"cherry.xswitch.cn","remoteAddr": "192.168.1.7"}' http://localhost:8088/api/agora-call-in
DTMF按键发送接口
根据通道 UUID 对当前通道发送DTMF按键信息,Body 里 channel_uuid 取自 callPSTN 接口的返回值,即,channel_uuid@hash_str。
- 请求 URL:
/api/cloud/dtmf/:channel_uuid@hash_str - 请求方式:
POST - 消息头:
Content-Type: application/json - Body 信息:
| 字段 | 必选 | 类型 | 备注 |
|---|---|---|---|
| channel_uuid | 是 | string | channel_uuid@hash_str来自 callPSTN 接口的返回值 |
| data | 是 | string | 按键数值 |
请求示例:
curl -X POST https://cloud.xswitch.cn/api/cloud/dtmf/01959245-455d-7169-bf20-83478cdf7ecf@aJoJk... \ -H 'Authorization: Bearer eyJxxx.yyy.zzz' \ -H 'Content-Type: application/json' \ -d '{ "channel_uuid": "01959245-455d-7169-bf20-83478cdf7ecf@aJoJk...", "data": "1" }'
成功返回:
{ "data":"01959245-455d-7169-bf20-83478cdf7ecf@aJoJk...", "message":"success", "code": 200 }
若返回500错误,为发送失败,可能是 channel_uuid 不存在等原因。
挂断接口
根据通道 UUID 挂断当前通话,url 中的:channel_uuid@hash_str来在 callPSTN 接口的返回值。
挂断接口参数如下:
hangup_cause:可选,默认为NORMAL_CLEARING
hangup_cause可用的值可参考:https://docs.xswitch.cn/xpedia/hangup-cause/ 。
DELETE /api/cloud/calls/:channel_uuid@hash_str
示例
curl -XDELETE https://cloud.xswitch.cn/api/cloud/calls/0bee39f2-...@JaJoJk... \ -H 'Content-Type: application/json' \ -H 'Authorization: Bearer ey...' \ -d '{ "hangup_cause": "NORMAL_CLEARING" }'
隐私和安全
- 根据国家有关法律法规,XSwitch Cloud 平台需要留存通话记录 6 个月。
- 根据国家有关法律法规,所有登录系统和使用 API 的用户都必须实名。
- XSwitch 不会向第三方泄漏您的通话记录,也永远不会使用您的通话记录做大数据挖掘、分析等。
- XSwitch 平台不存储您的用户数据,所有用户数据都存储在您自己的服务器上。
- 为了能接通服务,XSwitch 需要声网侧产生的临时 token、channel、uid 等数据,由于计费、故障追踪等需要,可能会存储 2-3 个月。这些数据都是由您的服务端生成的,最好不要包含敏感信息。平台不会对这些数据进行任何大数据挖掘和分析等。
测试号码
小樱桃提供了一批10000开头的测试号码用于开发测试,如:
10000183:回彩铃,不接听10000200:自动接听,放广告语10000201:自动接听,放广告语,约 1 分钟10000202:自动接听,放广告语,约 2 分钟10000486:不接听,放被叫忙
这些号码仅供 SIP 测试,不保证一直可用。详见更多测试号码。