@siaikin/juphoon-web-sdk v1.0.5
Juphoon Web SDK WeChat集成文档
根据本文指导快速在 微信小程序 集成视频客服SDK并在你自己的APP里实现坐席访客通话。
示例项目
Juphoon 提供了一个实时音视频示例项目,请联系客服获取。在实现相关功能前,你可以下载并查看源代码。
同时在微信上也提供了一个视频客服通话示例,你可以使用 Android 或 iOS 手机上打开微信 App,扫描识别下面的二维码或搜索 菊风访客 ,快速体验 Juphoon 视频客服的小程序解决方案。
开发环境要求
开发前提条件: 了解必要的前端知识, 以及微信小程序的开发
支持情况
- 支持微信版本6.5.22及以上
准备开发环境
注册小程序并开通相关接口
目前只针对国内主体如下类目的小程序开放 <live-player>
和 <live-player>
组件 ,需要先通过类目审核,再在小程序管理后台,「开发」-「接口设置」中自助开通该组件权限。
一级类目/主体类型 | 二级类目 | 小程序内容场景 |
---|---|---|
社交 | 直播 | 涉及娱乐性质,如明星直播、生活趣事直播、宠物直播等。选择该类目后首次提交代码审核,需经当地互联网主管机关审核确认,预计审核时长7天左右 |
教育 | 在线视频课程 | 网课、在线培训、讲座等教育类直播 |
医疗 | 互联网医院,公立医院 | 问诊、大型健康讲座等直播 |
金融 | 银行、信托、基金、证券/期货、证券、期货投资咨询、保险、征信业务、新三板信息服务平台、股票信息服务平台(港股/美股)、消费金融 | 金融产品视频客服理赔、金融产品推广直播等 |
汽车 | 汽车预售服务 | 汽车预售、推广直播 |
政府主体帐号 | / | 政府相关工作推广直播、领导讲话直播等 |
工具 | 视频客服 | 不涉及以上几类内容的一对一视频客服服务,如企业售后一对一视频服务等 |
注意:如果以上设置都正确,但小程序依然不能正常工作,可能是微信内部的缓存没更新,请删除小程序并重启微信后,再进行尝试。
创建微信小程序项目
根据官方文档说明创建微信小程序项目
集成微信小程序 SDK
将SDK文件夹中的 juphoon-web-sdk.we-chat.min.js
和 component
文件夹中的 local-stream
, remote-stream
两个微信小程序组件放到小程序任意能访问到的目录下
可使用Juphoon_WeChat对象下的方法进行快速集成。该对象的方法简化了集成的步骤。
local-stream
, remote-stream
组件说明
由于微信小程序仅支持使用rtmp协议进行实时媒体流传输,且需使用 live-pusher
,live-player
进行推流和拉流操作。所以我们用 local-stream
, remote-stream
对 live-pusher
,live-player
进行了封装,以便于开发者操作。
实现视频通话
事件监听
目前 WeChatClient,WeChatSocket 可以通过 BaseEventTarget.addEventListener
,BaseEventTarget.removeEventListener
来添加/移除事件监听器。
相关接口及详细信息见BaseEventTarget。
类-事件类型对应关系表如下:
Class | EventType |
---|---|
WeChatClient | WeChatClientEventType, WeChatClientErrorType |
WeChatSocket | BaseSocketEventType, BaseSocketErrorType |
注:删除线标记的为弃用事件
SDK引入方式
SDK中的所有类都可以通过下面方式引入,类定义请查看接口文档。
import { Juphoon_WeChat, BaseSocketEventType, BaseSocketErrorType, WeChatClientEventType, WeChatLogger, LoggerLevel } from '../../lib/juphoon-web-sdk.we-chat.min.js';
创建连接
创建连接前需要设置两个服务地址。
- serverAddress:获取登录令牌地址
- socketAddress: WebSocket连接地址
连接步骤
- 调用
Juphoon_WeChat.getToken
获取令牌 - 获取了令牌之后,调用
Juphoon_WeChat.createSocket
连接WebSocket。连接时,需要传递一个headers
参数用来进行校验。const headers = { // 获取token时传递的用户名 username: 'xxx', // 为获取到的令牌 token: 'xx' }
- serverAddress地址格式: http(s)://IP:PORT socketAddress地址格式: ws(s)://IP:PORT/wx_webrtc
import { Juphoon_WeChat } from '../../lib/juphoon-web-sdk.we-chat.min.js';
// 设置服务器地址和WebSocket连接地址
// serverAddress: http(s)://IP:PORT
// socketAddress: ws(s)://IP:PORT/wx_webrtc
Juphoon_WeChat.config.serverAddress = env.serverAddress;
Juphoon_WeChat.config.socketAddress = env.socketAddress;
// 设置用户名,需要以 `wx_user_` 为前缀
Juphoon_WeChat.config.username = `wx_user_${this.data.username}`;
// 获取token
Juphoon_WeChat.getToken(Juphoon_WeChat.config.username)
.then(res => {
wx.hideLoading();
if (res.ret !== 0) {
wx.showModal({
title: '获取Token失败',
content: JSON.stringify(res),
});
console.error(res);
return;
}
Juphoon_WeChat.config.headers = {
username: Juphoon_WeChat.config.username,
token: res.data
};
wx.showLoading({
title: '建立连接...',
mask: true
});
const socket = Juphoon_WeChat.createSocket({
headers: Juphoon_WeChat.config.headers,
connectUrl: Juphoon_WeChat.config.socketAddress,
receiveUrl: `/user/${Juphoon_WeChat.config.username}/msg`,
heartbeatUrl: '/acd/heartbeat',
sendUrl: '/acd/set/data',
});
socket.addEventListener(BaseSocketEventType.OPENED, () => {
wx.hideLoading();
wx.navigateTo({
url: '../business/business',
});
}, {once: true});
socket.addEventListener(BaseSocketEventType.ERROR, (ev) => {
wx.hideLoading();
wx.showModal({
title: '建立连接失败',
content: JSON.stringify(ev),
});
console.log(ev);
});
socket.addEventListener(BaseSocketErrorType.RECONNECT_TIMES_EXCEED_ERROR, (ev) => {
wx.hideLoading();
wx.showModal({
title: '重连失败',
content: JSON.stringify(ev),
});
console.log(ev);
});
})
.catch(err => {
wx.hideLoading();
console.error(err)
});
获取业务列表
WeChatClient.getBusinessList 会发送获取业务列表的消息,可以通过监听 WeChatClientEventType.BUSINESS_LIST 事件获取返回的业务列表, 该接口无需登录即可使用。
业务列表项说明如下:
Name | Type | Description |
---|---|---|
telNumber | string | 业务号 |
group | string | 组号 |
memo | string | 业务名称 |
logoUrl | string | 业务logo地址 |
const client = Juphoon_WeChat.createClient({
socket: this.socket,
confProps: {
accountName: Juphoon_WeChat.config.username,
nickName: Juphoon_WeChat.config.nickName
}
});
// 发送获取业务列表的消息
client.getBusinessList();
// 监听`WeChatClientEventType.BUSINESS_LIST` 事件获取到业务列表
client.addEventListener(WeChatClientEventType.BUSINESS_LIST, (ev) => {
this.data.businessList = ev.message;
}, { once: true });
呼叫
呼叫之前需要先调用WeChatClient.login()登录,登录成功后会回调 WeChatClientEventType.LOGIN
事件,
在该事件中可以调用WeChatClient.join()进行呼叫,呼叫需指定用户名和业务号, 业务号可从上一步骤中获得。
呼叫成功将会触发 WeChatClientEventType.CONFERENCE_JOINED 事件,呼叫成功表示该呼叫已进入排队队列,
注:一个 WeChatClient
对象对应一次呼叫,即再次呼叫时需要销毁上一次的呼叫对象然后重新创建一个 WeChatClient
。
this.client.login();
this.client.addEventListener(WeChatClientEventType.LOGIN, (ev) => {
// 使用用户名和业务号呼叫
this.client.join({
username: Juphoon_WeChat.config.username,
organize: telNUmber
});
}, { once: true });
// 监听 `WeChatClientEventType.CONFERENCE_JOINED` 事件,创建并进入房间成功
this.client.addEventListener(WeChatClientEventType.CONFERENCE_JOINED, (event) => {
}, { once: true });
等待坐席接听
坐席接通后会触发 WeChatClientEventType.AGENT_ANSWERED 事件,可以监听该事件跳转到通话界面。
// 添加 `WeChatClientEventType.WAIT_COUNT` 事件,显示排队人数
this.client.addEventListener(WeChatClientEventType.WAIT_COUNT, (ev) => {
this.queueCount = ev.message.count;
});
// 添加 `WeChatClientEventType.AGENT_ANSWERED` 事件
this.client.addEventListener(WeChatClientEventType.AGENT_ANSWERED, (ev) => {
});
渲染双方画面
由于微信小程序的特殊性, 无法通过DOM操作设置 <live-player>
和 <live-pusher>
的属性, 因此需要使用经过封装的组件 <remote-stream>
(对应 <live-player>
) 和 <local-stream>
(对应 <live-pusher>
) 组件来代替。
在小程序中可使用 this.selectComponent(selector)
获取组件实例。
也可以用 Juphoon_WeChat.createLocalStream/createRemoteStream 获取, 使用该方法获取时实例可通过 Juphoon_WeChat.config.remoteStream/localStream
访问。
注:通过 Juphoon_WeChat
创建的 remoteStream/localStream
已自动设置拉流以及推流地址。
SDK中提供了 Juphoon_WeChat.attachLocalStreamComponent 和 Juphoon_WeChat.attachAllRemoteStreamComponents 将小程序自定义组件与SDK进行关联。
注:如果通话人数发生改变需要调用 Juphoon_WeChat.attachAllRemoteStreamComponents
重新绑定组件(可能会有多个远端客服,但访客只会有一个所以无需重复调用 Juphoon_WeChat.attachLocalStreamComponent
)。
本地画面设置
获取到 <local-stream>
组件实例后,通过 WeChatLocalStream.init
设置rtmp推流地址以及其他属性,如果设置了 autopush
(默认为 true
)为 false
则需手动调用 start
开启推流。
坐席接通后,通过调用 WeChatClient.getLocalStream() 获取本地媒体流对象,然后将其传入 <local-stream>
。
<local-stream id="local-stream" class="local-video" config="{{ localStream }}">
</local-stream>
远端画面设置
获取到 <remote-stream>
组件实例后,通过 WeChatRemoteStream.init
设置rtmp拉流地址以及其他属性, 然后调用 start
( 默认为 false
)开始拉流。
坐席接通后,调用 WeChatClient.getRemoteStreamList() 获取远端媒体流对象数组,在界面上遍历数组,然后将数组项传入 <remote-stream>
。
<remote-stream wx:for="{{remoteStreamList}}" class="remote-video" config="{{ item }}">
</remote-stream>
绑定组件到SDK
使用 this.setData
将两端的媒体流信息传输到视图层,后调用 Juphoon_WeChat.attachLocalStreamComponent
和 Juphoon_WeChat.attachAllRemoteStreamComponents
方法将组件绑定到SDK。
this.setData({
localStream: this.client.getLocalStream(),
remoteStreamList: this.client.getRemoteStreamList()
}, () => {
Juphoon_WeChat.attachLocalStreamComponent('#local-stream', this);
Juphoon_WeChat.attachAllRemoteStreamComponents('.remote-video', this);
this.data.remoteStreamList.forEach(stream => stream.reset({objectFit: 'fillCrop'}));
});
通话挂断
在排队或者通话过程中可以通过调用WeChatClient.leave方法退出。
退出后会有WeChatClientEventType.CONFERENCE_LEAVED事件回调(可不必关心此回调,调用 WeChatClient.leave
后即可跳转页面)。
this.client.leave();
this.client.addEventListener(WeChatClientEventType.CONFERENCE_LEAVED, (event) => {
}, { once: true });
业务流程图
4 years ago