# 接入说明
- 服务地址
API 支持就近地域接入,接入地址:https://wxvoip.juphoon.com:8777/call-bff/meeting/call
- 通信协议
服务端 API 的所有接口均通过 HTTPS 进行通信,提供高安全性的通信通道。
- 字符编码
均使用 UTF-8 编码。
# HTTPS 鉴权
客户调呼叫接口时需要鉴权,具体鉴权方式如下:
鉴权方式采用 HMAC-SHA256 加密
鉴权头示例:
X-RTC-Timestamp: 1641370291
X-RTC-Service: rtc-api
Authorization: J-HMAC-SHA256 app-key="yourAppKey",signed-headers="x-rtc-timestamp;x-rtc-service",signature="yourSignature"
说明:
Authorization Token 必须以 “J-HMAC-SHA256”开头;
签名字符包含两个部分:
对应 header "X-RTC-Timestamp"的值
service 名称,对应 header "X-RTC-Service"
默认使用sha256算法。
签名包括:
app-key: 从控制台获取appKey;
signed-headers: 固定值"x-rtc-timestamp;x-rtc-service",用于签名构造的 header,其值会参与签名构造;
signature: 通过算法加密而成的 HMAC 签名。
获取加密的 key 为 secret,流程如下
登录开发者控制台,通过【产品】选择选择 RTC1.0 实时音视频服务
进入【应用管理】选择应用,点击【查看详情】
开通微信 VoIP 通话服务,查看 secret


Java 示例代码
package com.juphoon.rcs.util;
import com.juphoon.rcs.cons.Const;
import lombok.extern.slf4j.Slf4j;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.net.URLEncoder;
import java.security.MessageDigest;
public class EncryptUtilsDemo {
public static final BASE64Encoder encoder = new BASE64Encoder();
public static final String SYMBOL = "/";
public static String hmacsha256(String key, String value) {
Mac sha256_HMAC = null;
try {
sha256_HMAC = Mac.getInstance("HmacSHA256");
SecretKeySpec secret_key = new SecretKeySpec(key.getBytes("UTF-8"), "HmacSHA256");
sha256_HMAC.init(secret_key);
byte[] array = sha256_HMAC.doFinal(value.getBytes("UTF-8"));
String encode = encoder.encode(array);
return URLEncoder.encode(encode, "UTF-8");
} catch (Exception e) {
e.printStackTrace();
}
return "";
}
// timestamp 替换成X-RTC-Timestamp头域的值
// juphoonAppSecret 替换为juphoon提供的appSecret
public static void main(String[] args)throws Exception {
String signatureString = "timestamp" + "/" + "rtc-api";
String secret = "juphoonAppSecret";
String hmacsha256 = hmacsha256(secret, signatureString);
System.out.println(hmacsha256);
}
}
# 设备呼叫接口
该接口使用场景为设备向小程序发起呼叫时,客户后台调用该接口请求呼叫
请求说明
| 请求方法 | POST |
|---|---|
| 访问 URL | https://wxvoip.juphoon.com:8777/call-bff/meeting/call |
| 通信协议 | HTTPS |
请求 Body 参数说明
| 参数名 | 类型 | 是否必填 | 说明 |
|---|---|---|---|
| modelId | String | 是 | 小程序 model_id |
| appId | String | 是 | 小程序 appId |
| deviceId | String | 是 | sn :设备唯一序列号。由厂商分配,长度不能超过 128 字节。字符只接受数字,大小写字母,下划线(_)和连字符(-)。 |
| flavor | String | 是 | 小程序的版本类型 0:小程序正式版 1:小程序开发版 2:小程序体验版 |
| openId | String | 是 | 微信小程序用户 id |
| callId | String | 是 | 自定义唯一会话标识,最大 64 位,要求每次通话都不同,不能包含空格,只允许包含字母、数字、下划线或横线 |
| channelId | String | 是 | 自定义菊风频道 id,最大 64 位,要求同一 appkey 下保持唯一。支持如下字符集范围:
|
| robotUid | String | 是 | 机器人加入频道后的 UID,最大 64 位,要求同一频道内保持唯一,支持如下字符集范围:
|
| video | Boolean | 是 | 表示微信 VoIP 通话的媒体类型,true 表示视频 ,false 表示音频 |
| query | String | 否 | 小程序页面自定义参数, 可以传 NULL,参考微信文档中 query 传参,建议与下列 subscribe 的参数值一致 |
| landscape | Boolean | 否 | 设备 SDK 接收小程序推流是否为 4:3 的流 true: SDK 收到流的宽高比 4:3 --- 320x240 480x352 640x480 1280x720 1920x1080 false: SDK 收到流的宽高比 3:4 --- 240x320 352x480 480x640 720x1080 1080x1920 |
| subscribeVideoLength | Int | 否 | 设备 SDK 期望收到的流分辨率固定长边值 开发者可以用此配置来订阅一个分辨率的长边值。此功能主要是针对那些不希望收到可变分辨率视频流的设备,如果不使用此功能,SDK 收到的视频流在不同的网络环境下会有不同的分辨率。此功能需要同时向微信提交 appid,待开通订阅机制后才生效。 目前这个配置仅支持如下两个值: 320: video_landscape = true 时收到的是 320x240,video_landscape = false 时收到的是 240x320 640: 不支持 video_landscape = true 模式,video_landscape = false 时收到的是 480x640 |
| subscribeVideoRotation | Int | 否 | 设备 SDK 期望收到的流方向 开发者可以用此配置来订阅自己收到的流的方向 SDK 默认收到的是逆时针旋转了 90 度的视频流,如果开发者的硬件没有旋转渲染能力,可以使用这个订阅。订阅 0 度流后,对端的微信客户端会对流进行前处理再发出。 此功能 Beta 中,需要微信客户端与插件均支持方可生效. 目前这个配置仅支持如下两个值: 1: 0 度流,需要配合小程序端的 0 度流参数,两者一致后才能收到 0 度流。 其它:旋转流,默认也是旋转流。 |
| subscribeVideoRatio | Int | 否 | 设备 SDK 期望收到的流比例 开发者可以用此配置来订阅自己收到的视频流的比例 此功能 Beta 中,需要微信客户端与插件均支持方可生效. 定义如下: 75: 宽/高 * 100 = 75, 例如 240x320 133: 宽/高 * 100 = 133, 例如 320x240 50: 宽/高 * 100 = 50, 例如 160x320 200: 宽/高 * 100 = 200, 例如 320x160 ... |
body 示例
{
"modelId":"6c06**************144097",
"appId":"a13******22",
"deviceId":"24a***152",
"callId":"dq******32",
"flavor":"6c06**************144097",
"openId":"a13****4122",
"query":"24a***152",
"video":true,
"subscribeVideoLength":320,
"landscape":true,
"subscribeVideoRotation":1,
"subscribeVideoRatio":75,
"channelId":"room001",
"robotUid":"bot001"
}
响应参数说明
| 名称 | 类型 | 必选 | 示例值 | 描述 |
|---|---|---|---|---|
| ret | String | 是 | 0 | 响应状态码。返回 0 代表请求成功。 |
| msg | String | 否 | ok | 返回状态描述信息。返回 ok 代表请求成功。 |
| data | String | 否 | 1 | 返回内容。 |
响应示例
{
"ret": 0,
"msg": "ok",
"data": "as*****23" //服务端返回的callId
}
# 设备拒接接口
该接口使用场景为小程序呼叫设备时,客户后台调用该接口拒接来电,小程序端可收到设备拒接通知
请求说明
| 请求方法 | POST |
|---|---|
| 访问 URL | https://wxvoip.juphoon.com:8777/call-bff/meeting/reject |
| 通信协议 | HTTPS |
请求 Body 参数说明
| 参数名 | 类型 | 是否必填 | 说明 |
|---|---|---|---|
| callId | String | 是 | 通话 id |
body 示例
{
"callId":"dq******32"
}
响应参数说明
| 名称 | 类型 | 必选 | 示例值 | 描述 |
|---|---|---|---|---|
| ret | String | 是 | 0 | 响应状态码。返回 0 代表请求成功。 |
| msg | String | 否 | ok | 返回状态描述信息。返回 ok 代表请求成功。 |
| data | String | 否 | 1 | 返回内容。 |
响应示例
{
"ret": 0,
"msg": "ok"
}
# 设备接听接口
该接口使用场景为小程序呼叫设备时,客户后台调用该接口接听小程序的呼叫
请求说明
| 请求方法 | POST |
|---|---|
| 访问 URL | https://wxvoip.juphoon.com:8777/call-bff/meeting/accept |
| 通信协议 | HTTPS |
请求 Body 参数说明
| 参数名 | 类型 | 是否必填 | 说明 |
|---|---|---|---|
| callId | String | 是 | 通话 id |
body 示例
{
"callId":"dq******32"
}
响应参数说明
| 名称 | 类型 | 必选 | 示例值 | 描述 |
|---|---|---|---|---|
| ret | String | 是 | 0 | 响应状态码。返回 0 代表请求成功。 |
| msg | String | 否 | ok | 返回状态描述信息。返回 ok 代表请求成功。 |
| data | String | 否 | 1 | 返回内容。 |
响应示例
{
"ret": 0,
"msg": "ok"
}
# 错误码
| 枚举值 | 说明 | msg |
|---|---|---|
| 1001 | 请求参数 video 不能为空 channelId 不能为空 robotUid 不能为空 | video 不能为空 channelId 不能为空 robotUid 不能为空 |
| 1002 | 请求参数 flavor 错误 | flavor 错误 |
| 1004 | callId 不能为空 | callId 不能为空 |
| 1007 | 加密结果鉴权失败 | auth result error |
| 1008 | 请求头不正确 | request header error |
| 1009 | 鉴权参数不正确 | auth params error |
| 1041 | 服务器内部错误 | client spawn |
| 1042 | 服务器内部错误 | forward rpc |
| 1043 | 参数异常 | invalid param |
| 1044 | 获取 snticket 异常 | get snticket error |
| 1045 | 获取通话信息异常 | get call info error |
| 1046 | room 参数异常 | valid room config error |
| 1047 | 微信通话参数异常 | wechat call params error |
| 1048 | 微信通话不存在 | wechat call not exist error |
| 1049 | 加入会议错误 | join room error |
| 1060 | 服务异常 | server error |
| 1062 | 查询呼叫信息异常 | query call info error |
| 1063 | 通话信息解析失败 | payload parse error |
| 1064 | wxvoip 初始化失败 | start wxvoip init error |
| 1065 | wxvoipcall 失败 | start wxvoipcall error |
| 7777 | 微信返回异常 | wechat error |
| 9999 | 未知错误 | unknown error |
# 微信返回异常错误码
| 枚举值 | 说明 |
|---|---|
| 1 | roomid 错误 |
| 2 | 设备 deviceId 错误 |
| 3 | voip_id 错误 |
| 5 | 生成 voip 房间错误 |
| 7 | openId 错误 |
| 8 | openId 未授权 |
| 9 | openId 未绑定设备 |
| 12 | 小程序音视频能力审核未完成,正式版中暂时无法使用 |
| 13 | 硬件设备拨打手机微信模式,voipToken 错误 |
| 14 | 手机微信拨打硬件设备模式,voipToken 错误 |
| 17 | voipToken 对应 modelId 错误 |
| 19 | openId 与小程序 appId 不匹配。请注意同一个用户在不同小程序的 openId 是不同的 |
| 20 | openId 无效 |
| 10008 | snticket 过期 |
