背景
为某化妆品企业的柜台推销员提供与客户交流的企业微信小应用,可以分享自己的名片,与自己的客户发起会话并发送素材库中的文章和新闻。同样可以在文章详情页将当前文章分享给微信好友。
引入jssdk并预设一些全局变量
第一步:换取code,使用code换取accessToken和userId
注意要点:
- 注意token验证 防止一直跳转
- axios请求地址使用https
- 测试时的地址不可以为本地地址,可使用uat
微信开发文档API:https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_webpage_authorization.html
/**
* 微信网页授权
* getAccessToken() 见名知意,用于获取accessToken
* tools.unparam() 用户将url的参数解析为json格式
*/
async function weixinAuth(fn) {
if (getAccessToken() || !window.isWexin || !window.isWxWork) return;
const params = tools.unparam(location.href);
if (params.code && params.state === 'weixinAuthorize') {
const res = await axios.get(`/app/index/auth`, {
params: {
code: params.code,
},
});
if (res.fail) return;
if (res.accessToken) {
setWxInfo(res);
fn && fn();
}
return;
}
delete params.code;
delete params.state;
let redirect_uri = location.href.split('?')[0];
redirect_uri += tools.param(params);
let authParams = {
redirect_uri,
appid: config.appId,
scope: 'snsapi_userinfo',
response_type: 'code',
state: 'weixinAuthorize',
};
authParams = tools.param(authParams);
location.replace(
`https://open.weixin.qq.com/connect/oauth2/authorize${authParams}#wechat_redirect`,
);
}
第二步:初始化微信SDK
思路:
- 将当前url传给后端拿到配置参数
- 将拿到的参数使用wx.config初始化
- 后续的操作需要在wx.ready中调用
注意:
- 当前网页的URL, 不包含#及其后面部分
- debug为true,在微信中调试时,会alert结果
import axios from 'axios';
const JSAPILIST = [
'getCurExternalContact',
'getContext',
'sendChatMessage',
'selectExternalContact',
'openEnterpriseChat',
'onMenuShareTimeline',
'onMenuShareAppMessage',
'previewImage',
'chooseImage',
'uploadImage',
'downloadImage',
'getNetworkType',
'openLocation',
'getLocation',
'hideOptionMenu',
'showOptionMenu',
'hideMenuItems',
'showMenuItems',
'hideAllNonBaseMenuItem',
'showAllNonBaseMenuItem',
'closeWindow',
'scanQRCode',
'previewFile',
];
/**
* 初始化微信SDK
*/
function init(success, fail) {
if (!window.isWexin || !window.isWxWork) {
fail && fail();
return;
}
axios
.get('/app/index/config/corp', {
params: {
url: location.href.split('#')[0], // 当前网页的URL, 不包含#及其后面部分
},
})
.then(res => {
console.log(res);
if (!res.signature) {
fail && fail();
return;
}
wx.config({
beta: true,
debug: false,
appId: res.corpID,
timestamp: +res.timestamp,
nonceStr: res.nonceStr,
signature: res.signature,
jsApiList: JSAPILIST,
});
wx.ready(function() {
success && success();
});
wx.error(function(res) {
console.log(res, 'error - config');
});
});
}
第三步:注入应用的身份与权限
并不是所有的接口都需要注入应用身份,例如:getLocation,chooseImage等
但是在企业微信中拉取联系人或者打开会话时需要先注入应用,例如wx.invoke('sendChatMessage', ...)
注意:
1.【初始化微信SDK】和【注入应用的身份与权限】签名算法完全一样,但是jsapi_ticket的获取方法不一样
- 调用wx.agentConfig之前,必须确保先成功调用wx.config. 注意:从企业微信3.0.24及以后版本(可通过企业微信UA判断版本号),无须先调用wx.config,可直接wx.agentConfig.
**** 在微信开发者工具中提示wx.agentConfig is not a function 意味着不支持企业微信接口,需要真机测试 ****
/**
* 注入应用的身份与权限
*/
async function initAgent(success, fail) {
if (!window.isWexin) {
fail && fail();
return;
}
init(
() => {
axios
.get('/app/index/config/app', {
params: {
url: location.href.split('#')[0], // 当前网页的URL, 不包含#及其后面部分
},
})
.then(res => {
if (res.fail || !res.signature) {
fail && fail();
return;
}
let configData = {
corpid: res.corpID,
agentid: res.agentId,
timestamp: +res.timestamp,
nonceStr: res.nonceStr,
signature: res.signature,
jsApiList: JSAPILIST,
success: () => {
success && success();
},
fail: function(res) {
console.log(res, 'fail - agentConfig');
if (res.errMsg.indexOf('function not exist') > -1) {
console.log('版本过低请升级', 'error');
}
},
};
wx.agentConfig(configData);
});
},
() => {
fail && fail();
},
);
}
怎么使用
注意:
使用的接口都要在jsApiList中先声明
/**
* 隐藏右上角菜单
*/
function hideOptionMenu() {
return new Promise(resolve => {
init(() => {
wx.hideOptionMenu();
});
});
}
/**
* 获取经纬度
*/
function getLocation() {
const defOptions = {
city: '上海市',
};
return new Promise(resolve => {
init(
() => {
wx.getLocation({
type: 'gcj02',
success: res => {
let { longitude, latitude } = res;
console.log('getLocation:', res);
resolve(res);
},
fail: () => {
Message({
message:
'获取位置失败,请开启并授权微信定位,此次将使用默认的位置',
type: 'error',
onClose() {
resolve(defOptions);
},
});
},
cancel: () => {
resolve(defOptions);
},
});
},
() => {
resolve(defOptions);
},
);
});
}
使用企业微信中的特定接口
/**
* 打开外部联系人
*/
function selectExternalContact() {
return new Promise(resolve => {
initAgent(
() => {
wx.invoke(
'selectExternalContact',
{
filterType: 0, //0表示展示全部外部联系人列表,1表示仅展示未曾选择过的外部联系人。
},
function(res) {
console.log(res, 'selectExternalContact');
if (res.err_msg == 'selectExternalContact:ok') {
resolve(res.userIds);
} else {
resolve([]);
}
},
);
},
() => {
console.log('err');
resolve([]);
},
);
});
}
/**
* 打开会话
* @param {*} userIds
*/
function openChat(userIds) {
let groupName = userIds.length > 1 ? '讨论组' : '';
let externalUserIds = userIds.join(';');
return new Promise(resolve => {
initAgent(
() => {
wx.openEnterpriseChat({
// 注意:参与会话的外部联系人列表,格式为userId1;userId2;…,用分号隔开。
externalUserIds,
// 必填,会话名称。单聊时该参数传入空字符串""即可。
groupName,
success: function(res) {
// 回调
resolve(res);
},
fail: function(res) {
if (res.errMsg.indexOf('function not exist') > -1) {
alert('版本过低请升级');
}
},
});
},
() => {},
);
});
}