问题概述
近期有个需求,需要在企业微信中通过链接的方式唤起我们企业微信的内部自建应用小程序,本以为会很简单,因为微信小程序提供有类似能力通过urlscheme
生成类似的于weixin://dl/....
的短链,跳转这个短链就可以跳转到对应的小程序。但是在企业微信的开发文档中并没有类似的方法。。。
寻找解决办法
js
wx.invoke('launchMiniprogram', {
"appid" : "wx062aaa5507909631", // 需跳转的小程序appid
"path" : "pages/home/index.html", // 所需跳转的小程序内页面路径及参数。非必填
}, function(res) {
if(res.err_msg == "launchMiniprogram:ok") {
// 正常
} else {
// 错误处理
}
}
);
众所周知微信相当严格,要使用launchMiniprogram
之前要先成功调用agentConfig
相关注意事项
使用这些api时要引入相关的js-sdk。 这里我以一个简单的h5举个🌰
step1 注入js-sdk
html
<script src="https://res.wx.qq.com/open/js/jweixin-1.2.0.js"></script>
首先引入这个js-sdk 引入后并不能直接使用需要相关权限验证配置官方文档
先通过config接口注入权限验证配置
js
wx.config({
beta: true,// 必须这么写,否则wx.invoke调用形式的jsapi会有问题
debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: '', // 必填,企业微信的corpID,必须是本企业的corpID,不允许跨企业使用
timestamp: '', // 必填,生成签名的时间戳
nonceStr: '', // 必填,生成签名的随机串
signature: '',// 必填,签名,见 附录-JS-SDK使用权限签名算法
jsApiList: [] // 必填,需要使用的JS接口列表,凡是要调用的接口都需要传进来
});
appId
: 一定是你所在企业的corpId,未来你在A企业用这个跳转逻辑,你就填A企业的idtimestamp
: 随机的时间戳(一般采用当前时间戳,建议在链路跑通前写死)nonceStr
: 随机的字符串(建议在链路跑通前写死)signature
: 下面单独讲,jsApiList
: 需要使用到的接口都需要传进来
signature签名生成(官方文档)
要想生成这个签名首先需要 拼接一下这个字符串jsapi_ticket=JSAPITICKET&noncestr=NONCESTR×tamp=TIMESTAMP&url=URL
有两个注意点:
- 字段值采用原始值,不要进行URL转义;
- 必须严格按照如下格式拼接,不可变动字段顺序。
然后对这个字符串进行sha1加密就是我们所需要的签名了
其中 noncestr
和 timestamp
就是之前生成的随机值,url
就是当前h5的地址 这里的 jsapi_ticket
使用的是企业的jsapi_ticket
获取企业jsapi_ticket(官方文档)
请求URL: qyapi.weixin.qq.com/cgi-bin/get... 通过这个接口就能拿到 ticket ACCESS_TOKEN不同的应用方式也不同,具体参考官方文档
有了ticket就可以生成签名了 官方也提供了检验工具,来帮助我们查看生成的签名是否正确
有了签名config基本就注入成功了,如果失败的话也会有提示。
step2 agentConfig注入应用的权限
这里和config的注入方法一样,只有一个区别就是这里获取的jsapi_ticket
是应用的jsapi_ticket
注:获取企业的jsapi_ticket和应用的jsapi_ticket调用接口是不同的(这里提醒下因为之前踩过坑),企业的jsapi_ticket的比较长应用的比较短
官方也说过可以直接通过agentConfig注入应用的权限,而不需要注入config,但是保险起见以后也不知道会不会有其他的需求建议一起注入。
code
html
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>H5</title>
<script>//sha1加密的cdn</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.0.0/core.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.0.0/enc-base64.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.0.0/sha1.min.js"></script>
<script>//js-sdk</script>
<script src="https://res.wx.qq.com/open/js/jweixin-1.2.0.js"></script>
<script src="https://open.work.weixin.qq.com/wwopen/js/jwxwork-1.0.0.js"></script>
</head>
<body>
<button id="btn" style="width: 100vw; height: 100px; text-align: center">click</button>
</body>
<script src="./demo.js"></script>
</html>
js
//demo.js
//获取随机字符串
function generateRandomString(length) {
var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
var result = new Array(length).fill(0).map(() => chars.charAt(Math.floor(Math.random() * chars.length))).join('');
return result;
};
//获取签名
function getsignature({ time, str, isapp }) {
//提前获取的企业jsapi_ticket
const ticket = "HoagFKDcsGMVCIY2vOjf9l_kslAeMzZBEEdLJZ8kfUR7Ci6q5SNCZwDm0MCvUqljsw15y8MSRwlghNtNXlxXYA"
//提前获取的应用jsapi_ticket
const appticket = 'Jt9ZPs1ZB1bj0CorBIwBgA=='
const lastTicket = isapp ? appticket : ticket;
const data = `jsapi_ticket=${lastTicket}&noncestr=${str}×tamp=${time}&url=${location.href}`
return CryptoJS.SHA1(data).toString();
};
//给btn注册点击事件 点击后跳转小程序
document.querySelector('#btn').addEventListener('click', function () {
document.querySelector('.txt').innerHTML = location.href
const nowTime = Math.floor(new Date().getTime() / 1000);
const nonStr = generateRandomString(16)
const signature = getsignature({ time: nowTime, str: nonStr })
const appsignature = getsignature({ time: nowTime, str: nonStr, isapp: true })
wx.config({
beta: true,// 必须这么写,否则wx.invoke调用形式的jsapi会有问题
debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: 'wwxxxxxxxxxxx', // 必填,企业微信的corpID,必须是本企业的corpID,不允许跨企业使用
timestamp: nowTime, // 必填,生成签名的时间戳
nonceStr: nonStr, // 必填,生成签名的随机串
signature: signature,// 必填,签名,见 附录-JS-SDK使用权限签名算法
jsApiList: ['invoke'], // 必填,需要使用的JS接口列表,凡是要调用的接口都需要传进来
})
wx.agentConfig({
corpid: 'ww0xxxxxxx', // 必填,企业微信的corpid,必须与当前登录的企业一致
agentid: '100000000', // 必填,企业微信的应用id (e.g. 1000247)
timestamp: nowTime, // 必填,生成签名的时间戳
nonceStr: nonStr, // 必填,生成签名的随机串
signature: appsignature,// 必填,签名,见附录-JS-SDK使用权限签名算法
jsApiList: ['invoke', 'launchMiniprogram'], //必填,传入需要使用的接口名称
success: function (res) {
wx.invoke('launchMiniprogram', {
"appid": "wxaaaaaaaaa", // 需跳转的小程序appid
}, function (res) {
wx.closeWindow() //关闭当前h5
}
)
},
fail: function (res) {
setTxt(JSON.stringify('wx.agentConfig erroer' + JSON.stringify(res)))
if (res.errMsg.indexOf('function not exist') > -1) {
alert('版本过低请升级')
}
}
});
})
如果有什么问题欢迎在评论区留言