1.0.5 • Published 4 years ago

@siaikin/juphoon-web-sdk v1.0.5

Weekly downloads
-
License
GPL-3.0
Repository
-
Last release
4 years ago

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.jscomponent 文件夹中的 local-streamremote-stream两个微信小程序组件放到小程序任意能访问到的目录下

可使用Juphoon_WeChat对象下的方法进行快速集成。该对象的方法简化了集成的步骤。

local-stream, remote-stream 组件说明

由于微信小程序仅支持使用rtmp协议进行实时媒体流传输,且需使用 live-pusherlive-player 进行推流和拉流操作。所以我们用 local-streamremote-streamlive-pusherlive-player 进行了封装,以便于开发者操作。

实现视频通话

事件监听

目前 WeChatClientWeChatSocket 可以通过 BaseEventTarget.addEventListenerBaseEventTarget.removeEventListener 来添加/移除事件监听器。 相关接口及详细信息见BaseEventTarget

类-事件类型对应关系表如下:

ClassEventType
WeChatClientWeChatClientEventType, WeChatClientErrorType
WeChatSocketBaseSocketEventType, BaseSocketErrorType

注:删除线标记的为弃用事件

SDK引入方式

SDK中的所有类都可以通过下面方式引入,类定义请查看接口文档。

import { Juphoon_WeChat, BaseSocketEventType, BaseSocketErrorType, WeChatClientEventType, WeChatLogger, LoggerLevel } from '../../lib/juphoon-web-sdk.we-chat.min.js';

创建连接

创建连接前需要设置两个服务地址。

  1. serverAddress:获取登录令牌地址
  2. socketAddress: WebSocket连接地址

连接步骤

  1. 调用 Juphoon_WeChat.getToken 获取令牌
  2. 获取了令牌之后,调用 Juphoon_WeChat.createSocket 连接WebSocket。连接时,需要传递一个 headers 参数用来进行校验。
    const headers = {
      //  获取token时传递的用户名
      username: 'xxx',
      //  为获取到的令牌
      token: 'xx'
    }
  3. 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 事件获取返回的业务列表, 该接口无需登录即可使用。

业务列表项说明如下:

NameTypeDescription
telNumberstring业务号
groupstring组号
memostring业务名称
logoUrlstring业务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.attachLocalStreamComponentJuphoon_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.attachLocalStreamComponentJuphoon_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 });

业务流程图

npm.io