赞
踩
- const log = require("./log");
- const util = require('./util');
- const crypt = require('./WXBizMsgCrypt');
- const wmpfVoip = requirePlugin('wmpf-voip').default
-
- // 判断当前是否为设备端拉起小程序
- const isWmpf = (typeof wmpf !== 'undefined');
-
- // 指定接听方使用的小程序版本。formal/正式版(默认);trial/体验版;developer/开发版
- const miniprogramState = (() => {
- const accountInfo = wx.getAccountInfoSync();
- if(accountInfo && accountInfo.miniProgram){
- const platform = { develop: 'developer', trial: 'trial', release: 'formal' }
- return platform[accountInfo.miniProgram.envVersion]
- }
- })()
- console.log('miniprogramState='+miniprogramState)
-
- // 「设备接入」从微信公众平台获取的 model_id
- const modelId = 'DSAF58AS5F3SA2FD2SA33DS55';
-
- // 设备名称,用于授权时显示给用户
- const deviceName = '好宝宝';
-
- // 通话监听
- const onVoipEvent = () => {
- wmpfVoip.onVoipEvent((event) => {
- const eventName = event.eventName;
- // 定义挂断事件
- const filterEvent = ['hangUpVoip', 'cancelVoip', 'timeout', 'rejectVoip'];
- // 挂断动作向设备端发送消息通知
- if(eventName == 'endVoip' || filterEvent.indexOf(eventName) > -1){
- // 每次通话只能推送一次挂断信息
- if(event.groupId && wx.getStorageSync('currcall') != event.groupId){
- sendMsgDevice('EndVoip');
- wx.setStorageSync('currcall', event.groupId)
- log.info('通知设备关闭小程序')
- }
- }
- // 通话记录参数
- const callData = {
- groupId: event.groupId,
- params: {
- eventName: eventName, data: event.data
- },
- }
- // 挂断上报通话记录
- filterEvent.indexOf(eventName) > -1 && updateCallRecord(callData)
- // 为避免上面几种情况执行异常,在结束通话时再次上报,延迟执行是为了避免并发
- if(eventName == 'endVoip'){
- setTimeout(() => {
- updateCallRecord(callData);
- }, 1500)
- }
- // 非通话中,打印调试
- (eventName != 'calling') && log.info(`onVoipEvent`, event);
- // 设备打微信,微信端插件通话页面 onShow
- if(eventName == 'callPageOnShow' && !isWmpf){
- setUIConfig(1)
- }
- })
- }
-
- // 设置通话结束跳转地址
- const setVoipEndPagePath = (recordId) => {
- if(!isWmpf){
- wmpfVoip.setVoipEndPagePath({
- url: '/pages/call/index',
- key: 'Call',
- })
- }
- }
-
- /**
- * 小程序传递消息给设备
- * @param {*} command
- */
- const sendMsgDevice = (command) => {
- if(isWmpf){
- wmpf.Channel.invoke({
- command: command,
- success: function(res) {
- wx.setStorageSync(command+'_invoke', 1)
- setTimeout(() => {
- wx.removeStorageSync(command+'_invoke');
- }, 1000)
- log.info('wmpf.Channel.invoke success:', res.data)
- },
- fail: function(res){
- log.error('wmpf.Channel.invoke fail:', res);
- }
- })
- }
- }
-
- /**
- * 微信打设备
- * @param {拨打方用户 openId} openid
- * @param {拨打对方用户信息 name:拨打方名字,仅显示用;roomType:voice音频房间,video音视频房间;voipToken:从设备获取的 pushToken} contact
- */
- const wechatCallDevice = (contact) => {
- wx.showLoading({title: '呼叫中',mask: true}), setTimeout(() => {wx.hideLoading()}, 3000)
- const initByCaller = async (config, data) => {
- log.info('====>通话请求参数', data, config)
- setUIConfig(2);
- const { groupId, isSuccess, errCode, errMsg } = await wmpfVoip.initByCaller(data)
- wx.hideLoading();
- if (isSuccess) {
- requestCallVoip(groupId, data.roomType, 0, config);
- const callPagePlugin = 'plugin-private://wxf830863afde621eb/pages/call-page-plugin/call-page-plugin'
- wx.redirectTo({
- url: `${callPagePlugin}?isCaller=1&roomType=${data.roomType}&groupId=${groupId}`,
- })
- } else {
- log.error('拨打请求失败:errCode='+errCode+';errMsg='+errMsg, config, data)
- if(errCode == 14){
- return wx.showToast({title: '手机微信拨打硬件设备模式,voipToken 错误',icon: 'error'})
- }
- wx.showToast({title: '拨打失败',icon: 'error'})
- }
- }
- const init = () => {
- checkDeviceAuth(contact.deviceId, ()=>{
- getCallConfigParams(contact.id, contact.relId, (config) => {
- initByCaller(config, {
- caller: {
- id: config.openid, name: config.name
- },
- listener: {
- id: config.deviceId
- },
- roomType: contact.roomtype,
- voipToken: config.pushToken,
- businessType: 2,
- miniprogramState: miniprogramState,
- })
- })
- })
- }
- // 通话结束延长1秒才能再次拉起通话,0.2秒检查一次
- const checkCallEnd = () => {
- if(wx.getStorageSync('EndVoip_invoke')){
- setTimeout(() => {
- checkCallEnd();
- }, 200)
- }else{
- init()
- }
- }
- checkCallEnd();
- }
-
- /**
- * 设备拨打微信
- */
- const deviceCallWechat = () => {
- const { query } = wmpfVoip.getPluginEnterOptions()
- log.info('====>设备拨打微信传参:', query)
- setUIConfig(query.isCaller === '1' ? 3 : 4);
- if(query.isPreLaunch == 'false' && query.isCaller === '1' && query.contactId){
- var contactId = query.contactId;
- var relId = query.deviceId;
- if(query.isRecord == '1'){
- contactId = -2;
- relId = query.contactId;
- }
- wx.setStorageSync('token', query.token);
- getCallConfigParams(contactId, relId, (config) => {
- wmpfVoip.initByCaller({
- caller: {
- id: query.deviceId
- },
- listener: {
- id: config.openid,name: config.name
- },
- roomType: query.roomType,
- voipToken: query.voipToken,
- businessType: 1,
- miniprogramState: miniprogramState,
- }).then((res)=>{
- log.info('===========>设备打微信initByCaller success', res);
- res.isSuccess && requestCallVoip(res.groupId, query.roomType, 1, config);
- if(!res.isSuccess){
- if(res.errCode == 9){
- wx.showToast({title: '未授权设备无法使用通话功能',icon: 'error'})
- }
- if(res.errCode == 13){
- // 传递参数给设备处理
- sendMsgDevice('VoipTokenErr13');
- }
- sendMsgDevice('errorEnd');
- }
- }).catch((e) => {
- sendMsgDevice('errorEnd');
- log.error('==========>设备打微信initByCaller fail', e);
- })
- }, () => {
- sendMsgDevice('errorEnd');
- })
- }
- }
-
- /**
- * 获取通话配置参数
- * @param {通讯录id} contactId
- */
- const getCallConfigParams = (contactId, relId, callback, errback) => {
- util.rqt({
- url: '/eeop/wechatcall/getCallConfig',
- data: {
- id: contactId,appid: crypt.appid,relId: relId
- },
- callBack(res){
- const encryptOpenid = res.data.encryptOpenid;
- if(!encryptOpenid){
- errback && errback();
- log.error('获取配置参数openid失败', res.data);
- return;
- }
- res.data.openid = crypt.decrypt(encryptOpenid.TimeStamp, encryptOpenid.Nonce, encryptOpenid.Encrypt, encryptOpenid.MsgSignature);
- callback && callback(res.data);
- },
- errCallBack(res){
- errback && errback();
- log.error('请求后台配置出现异常', res);
- }
- })
- }
-
- /**
- * 拨打电话
- */
- const requestCallVoip = (groupId, roomType, callWay, config) => {
- updateCallRecord({
- groupId: groupId,
- userId: config.userId,
- deviceId: config.deviceId,
- callType: (roomType == 'video' ? 1 : 0),
- callWay: callWay,
- params: {
- eventName: 'startVoip'
- }
- })
- }
-
- const updateCallRecord = (data) => {
- util.rqt({
- url: '/eeop/wechatcall/updateCallRecord',
- method: 'POST',
- data: data,
- callBack(res){
- log.info('上报通话返回结果', res, data);
- },
- errCallBack(res){
- log.error('上报通话数据返回异常', res, data)
- }
- })
- }
-
- /**
- * 添加联系人
- * @param {*} options
- * @param {*} callback
- */
- const addContact = (options, callback) => {
- if(!options.deviceId || !options.code){
- return wx.showToast({title: '扫描失败',icon: 'none'})
- }
- checkDeviceAuth(options.deviceId, () => {
- util.rqt({
- url: '/eeop/wechatcall/bind',
- data: options,
- callBack(res){
- open('添加成功', true);
- },
- errCallBack(res){
- if(res.code == 3010){
- return open('二维码已过期', false);
- }
- open(res.msg, false);
- }
- })
- const open = (content, status) => {
- wx.showToast({
- title: content, icon: 'none',
- success(res){
- setTimeout(() => {
- callback && callback(status);
- }, 1500)
- }
- })
- }
- })
- }
-
- /**
- * 更新token
- */
- const updatePushToken = () => {
- // 根据设备deviceId更新token信息到后台服务器
- const updatePushToken = (deviceId, pushToken) => {
- util.rqt({
- url: '/eeop/wechatcall/pushToken',
- data: {
- deviceId: deviceId,pushToken: pushToken
- },
- callBack(result){
- log.info('=====>设备端拉起小程序时向后台请求更新token返回结果callBack:deviceId='+deviceId+';pushToken='+pushToken, result);
- },
- errCallBack(result){
- log.info('=====>设备端拉起小程序时向后台请求更新token返回结果errCallBack:deviceId='+deviceId+';pushToken='+pushToken, result);
- }
- });
- }
- // 获取pushToken
- const getWmpfPushToken = (deviceId) => {
- log.info('=====>获取pushToken', deviceId);
- wmpf.getWmpfPushToken({
- success(res){
- log.info('=====>wmpf.getWmpfPushToken success', res);
- const pushToken = res.token;
- if(pushToken && pushToken != 'undefined'){
- updatePushToken(deviceId, pushToken);
- }
- },
- fail(res){
- log.error('=====>wmpf.getWmpfPushToken fail', res);
- }
- })
- }
- // 获取设备deviceId
- const { query } = wmpfVoip.getPluginEnterOptions()
- log.info('设备拉起小程序获取参数:', query);
- query.token && wx.setStorageSync('token', query.token);
- query.deviceId && getWmpfPushToken(query.deviceId);
- }
-
- /**
- * 检测是否授权
- * @param {用户信息} contact
- */
- const checkDeviceAuth = (deviceId, callback) => {
- const requestDeviceVoIP = (snTicket) => {
- wx.hideLoading();
- wx.requestDeviceVoIP({
- sn: deviceId, // 向用户发起通话的设备 sn(需要与设备注册时一致)
- snTicket: snTicket, // 获取的 snTicket
- modelId: modelId, // 「设备接入」从微信公众平台获取的 model_id
- deviceName: deviceName, // 设备名称,用于授权时显示给用户
- success(res) {
- callback && callback();
- log.info(`requestDeviceVoIP success:`, res)
- },
- fail(err) {
- if(err.errCode == 10021){
- wx.showModal({
- title: '是否要打开设置页面',
- content: '需要获取您的音视频通话授权信息,请到小程序的设置中打开授权',
- success(res) {
- res.confirm && wx.openSetting()
- }
- })
- }
- log.error(`requestDeviceVoIP fail:`, err)
- },
- })
- }
- const getSnTicket = () => {
- util.rqt({
- url: '/eeop/wechatcall/setting/getSnTicket',
- data: {
- deviceId: deviceId
- },
- callBack(res){
- requestDeviceVoIP(res.data.snTicket)
- },
- errCallBack(res){
- log.error(`getSnTicket fail:`, err)
- }
- })
- }
- util.checkWechatVersion('2.30.3') && wx.getDeviceVoIPList({
- success(res) {
- log.info('当前用户授权的设备:', res.list)
- const isAuth = res.list.some(element => {
- return element.sn == deviceId && element.status == 1;
- })
- if(isAuth){
- callback && callback()
- }else{
- getSnTicket();
- }
- }
- })
- }
-
- /**
- * 自定义UI相关配置
- * @param {拨打场景: 1设备打微信,微信端接听,微信端设置;2微信打设备,微信端设置;3设备打微信,设备端设置;4微信打设备,设备端接听,设备端设置} scene
- */
- const setUIConfig = (scene) => {
- return;
- // 显示设备端
- var UI_1 = {
- cameraRotation: 0, // caller的视频画面旋转角度,有效值为 0, 90, 180, 270。默认 0
- aspectRatio: 3/4, // 纵横比,caller的视频画面会进行适配比例,有效值 数字。默认 4/3
- horMirror: false, // 横向镜像,boolean 值,默认 false
- vertMirror: false, // 竖直镜像,同上
- enableToggleCamera: false, // 是否支持切换摄像头,false 则不显示「摄像头开关」按钮。默认false 【该配置项在wmpf无效,wmpf默认开摄像头,且不显示开关按钮】
- }
- // 显示微信端
- var UI_2 = {
- cameraRotation: 0,
- aspectRatio: 4/3,
- horMirror: false,
- vertMirror: false,
- enableToggleCamera: false,
- }
- if(scene == 1){
- wmpfVoip.setUIConfig({
- btnText: null,
- callerUI: UI_1,
- listenerUI: UI_2
- })
- }
- if(scene == 2){
- wmpfVoip.setUIConfig({
- btnText: null,
- callerUI: UI_1,
- listenerUI: UI_2
- })
- }
- if(scene == 3){
- wmpfVoip.setUIConfig({
- btnText: null,
- callerUI: UI_1,
- listenerUI: UI_2
- })
- }
- if(scene == 4){
- wmpfVoip.setUIConfig({
- btnText: null,
- callerUI: UI_2,
- listenerUI: UI_1
- })
- }
- }
-
- module.exports = {
- isWmpf, updatePushToken, wechatCallDevice, deviceCallWechat, checkDeviceAuth, onVoipEvent, setVoipEndPagePath, addContact
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。