vue引入企业微信JS-SDK;企业微信开发步骤;vue开发企业微信;企业微信侧边栏应用开发
vue引入企业微信JS-SDK;企业微信开发步骤;vue开发企业微信;企业微信侧边栏应用开发
企业微信开发
本篇主要介绍,在vue中使用企业微信JS-SDK来开发企业微信的应用
详细案例:本次开发,是通过企业微信,创建外部群既客户群,然后再客户群中添加侧边栏页面。在侧边栏页面中引入vue的H5页面,在其中一个页面点击按钮获取到当前外部群的群id
在企业微信外部群内的效果:是正确的的,也只能在企业微信内进行测试。
在浏览器内调试只能进行一部分逻辑,因为有些api是必须在企业微信内运行
以下为实际开发遇到的问题和步骤:
文章目录
一、准备工作
1.新建一个vue项目,用于开发H5
2.需要在企业微信中创建应用,在应用中关联上本vue项目
二、注意要点和坑
1.必须注意以下问题:
1.在企业微信创建应用,需要管理员权限
2.所有的JS接口只能在企业微信应用的可信域名下调用(包括子域名),且可信域名必须有ICP备案且在管理端验证域名归属。 验证域名归属的方法在企业微信的管理后台“我的应用”里,进入应用,设置应用可信域名。
3.相关企业微信的api只能在企业微信中调用:
也就是说本地开发,调用企业微信api是会报错的,所以你只能把项目部署上线后,才能去企业微信进行验证。
不过我在工作台配置了本地应用地址(例如:http://192.168.12.123:9999/#/login): 本地IP+端口号+地址,这样本地开发时候,也可以在企业微信的工作台内实时看到效果。但还是存在有些api必须在聊天框内才能调用的问题。
建议: 用自己企业微信创建个自己的企业,当成测试环境,在上面调试。注意代码需要区分好本地和线上调用不同企业微信的应用。
4.官方提供的引入企业微信JS-SDK好像不行???????????????????????????????
我在index.html引入后,不是找不到wx,就是找不到wx.config,又或者找不到wx.agentConfig报undefined
官方文档写的引入企业微信JS-SDK:
<!-- 企业微信开发 引入 jwxwork sdk -->
<script src="//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>
.
.
.
后来我在index.html里引入,在script标签上加了 referrerpolicy="origin"
,然后就正常了:
我自己引入方式:
<!-- 企业微信开发 引入 jwxwork sdk -->
<script src="https://res.wx.qq.com/open/js/jweixin-1.2.0.js" referrerpolicy="origin"></script>
<script src="https://open.work.weixin.qq.com/wwopen/js/jwxwork-1.0.0.js" referrerpolicy="origin"></script>
5.JS-SDK使用权限签名算法驼峰命名问题
:
注意里面的noncestr是有大小写的,既有noncestr,也有nonceStr。
还有签名用的noncestr和timestamp必须与wx.config中的nonceStr和timestamp相同。
6.wx.config和wx.agentConfig不同:
具体区别看文档
wx.agentConfig必须在wx.config成功后调用,也就是在wx.config的wx.ready内调用。但是你想要看到wx.config成功后进入到wx.ready,你就必须将wx.config参数debug设置为debug:true 才可以。
6企业微信的相关:
jsApiList 数组中传入需要调用的接口名称
6.wx.config和wx.agentConfig不同:
6.wx.config和wx.agentConfig不同:
三、帮助文档和工具
1.开发文档
2.管理后台
3.基本概念术语
4.开发者社区
5.错误码查询工具,帮助开发者根据接口报错,进行快速定位bug。
四、实例代码:
1.index.html:引入sdk
<!-- 在需要调用JS接口的页面引入如下JS文件 -->
<!-- 企业微信开发 引入 jwxwork sdk -->
<script src="https://res.wx.qq.com/open/js/jweixin-1.2.0.js" referrerpolicy="origin"></script>
<script src="https://open.work.weixin.qq.com/wwopen/js/jwxwork-1.0.0.js" referrerpolicy="origin"></script>
2.vue页面:通过环境变量获取企业微信id和应用id,同时引入初始化鉴权的js代码
<template>
<div>
<div style="text-align: center;">发票页</div>
<div>chatId:{{chatId}}</div>
<div>corpid:{{corpid}}</div>
<div>agentid:{{agentid}}</div>
<el-button @click="setToken">鉴权后获取群id</el-button>
</div>
</template>
<script>
import { getAuthTicket } from 'common/js/wx_auth_token' //初始化
import { MyPost, MyGet, PayPost } from "common/js/request"
import { G_CGI_PHP } from "api/api"
export default {
data () {
return {
chatId: '',//外部群id
corpid: '',
agentid: '',
}
},
mounted () {
},
methods: {
setToken () {
let _this = this
let flag = false
// 根据环境判断 调用后端接口 获取测试环境和线上环境的两个id
if (process.env.NODE_ENV === "development") {
alert("开发环境")
MyGet(G_CGI_PHP.superOrder.corpGet + '?name=zhbtest', {
}).then((res) => {
if (res.success) {
console.log(res)
// 上线时候需要替换成线上真正的id -- 开发使用自己的企业微信应用 -- 最会保test -- 测试企业
flag = getAuthTicket(res.data.corpid, res.data.agentid)//企业微信的id:corpid 企业微信的应用id:agentid
console.log('flag1', flag)
this.corpid = res.data.corpid
this.agentid = res.data.agentid
} else {
this.$message({
message: res.return_message,
type: "error",
})
}
})
} else {
alert("生产环境")
// MyGet(G_CGI_PHP.superOrder.corpGet + '?name=zhbnoncar', {
MyGet(G_CGI_PHP.superOrder.corpGet + '?name=zhbtest', {
}).then((res) => {
if (res.success) {
console.log(res)
// 上线时候需要替换成线上真正的id -- 上线使用公司的企业微信应用 -- 最会保经纪
flag = getAuthTicket(res.data.corpid, res.data.agentid)//企业微信的id:corpid 企业微信的应用id:agentid
console.log('flag2', flag)
this.corpid = res.data.corpid
this.agentid = res.data.agentid
} else {
this.$message({
message: res.return_message,
type: "error",
})
}
})
}
}
},
}
</script>
<style>
</style>
3.wx_auth_token.js:初始化鉴权的代码
1.access_token是后端通过接口计算好:因为access_token有2小时的有效期 同时调用次数有限制 而且前端获取需要传入秘钥不安全 故是后端计算出来的
2.通过后端接口获取到企业和应用的ticket(都需要先获取到access_token):注意拿到的ticket是未加密的,在调用wx.config和wx.agentConfig时候需要自己加密得到签名
3.总体逻辑:
①先获取access_token
②获取企业ticket
③加密得到签名
④调用wx.config 注意 jsApiList 需要配置agentConfig
⑤在wx.ready里再获取应用的ticket
⑥加密得到签名
⑦在定时器setTimeout里调用wx.agentConfig 注意 jsApiList 需要配置你要调用的接口方法 例如getCurExternalChat获取外部群id
⑧在success里调用wx.invoke对应的接口方法
// ---------------------------------做企业微信的和应用的授权与初始化---------------------------------
/*
1.access_token是后端通过接口计算好:因为access_token有2小时的有效期 同时调用次数有限制 而且前端获取需要传入秘钥不安全 故是后端计算出来的
2.通过后端接口获取到企业和应用的ticket(都需要先获取到access_token):注意拿到的ticket是未加密的,在调用wx.config和wx.agentConfig时候需要自己加密得到签名
3.总体逻辑:
①先获取access_token
②获取企业ticket
③加密得到签名
④调用wx.config 注意 jsApiList 需要配置agentConfig
⑤在wx.ready里再获取应用的ticket
⑥加密得到签名
⑦在定时器setTimeout里调用wx.agentConfig 注意 jsApiList 需要配置你要调用的接口方法 例如getCurExternalChat获取外部群id
⑧在success里调用wx.invoke对应的接口方法
*/
import {
MyPost,
MyGet
} from 'common/js/request'
// 引入加密依赖
let sha1 = require('js-sha1')
let obj = {
ticket1: '', //获取企业的ticket --- 对应config注入的是企业的身份与权限
ticket2: '', // 获取应用的ticket --- 对应agentConfig注入的是应用的身份与权限
access_token: '', // 登录凭证
}
let corpidVal = ''
let agentidVal = ''
let _this = this
// 先获取企业的ticket
export function getAuthTicket(corpid, agentid) {
corpidVal = corpid
agentidVal = agentid
MyGet('/chc-shop/api/v1/qywechat/jsapiticket/corp', {}).then(res => {
console.log('先获取企业的ticket', res);
alert('先获取企业的ticket')
if (res.success) {
obj.ticket1 = res.data;
const ticket1 = res.data // 很重要!!!!
let nonceStr = 'Y7a8KkqX041bsSwT' // 随机字符串
let timeStamp = new Date().getTime() // 时间戳
let newTimeStamp = String(timeStamp).substr(0, 10) // 10位数的时间戳
// 当前网页的 URL(可以为本地局域网网址),不包含 # 及其后面部分
let url = String(location.href.split('#')[0])
let verifyStr = `jsapi_ticket=${ticket1}&noncestr=${nonceStr}×tamp=${newTimeStamp}&url=${url}`
let signature = sha1(verifyStr)
console.log('签名1', signature)
wx.config({
beta: true, // 必须这么写,否则wx.invoke调用形式的jsapi会有问题
// 上线的时候记得将 debug 关掉哦!!!!!
debug: process.env.NODE_ENV === "development" ? true : false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: corpid, // 必填,企业微信的corpid
timestamp: newTimeStamp, // 必填,生成签名的时间戳
nonceStr: nonceStr, // 必填,生成签名的随机串
signature: signature, // 必填,签名,见 附录-JS-SDK使用权限签名算法
jsApiList: [
'agentConfig',
'checkJsApi',
'onMenuShareTimeline',
'onMenuShareAppMessage',
'onMenuShareQQ',
'onMenuShareWeibo',
'hideMenuItems',
'showMenuItems',
'hideAllNonBaseMenuItem',
'showAllNonBaseMenuItem',
'chooseImage',
'previewImage',
'uploadImage',
'downloadImage',
'getLocalImgData',
'getNetworkType',
'openLocation',
'getLocation',
'hideOptionMenu',
'showOptionMenu',
'closeWindow',
'scanQRCode',
'chooseWXPay',
'openProductSpecificView',
'addCard',
'chooseCard',
'openCard'
] // 必填,需要使用的JS接口列表,凡是要调用的接口都需要传进来
});
wx && wx.ready(function () {
// config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,
// 所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。
// 对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。
alert('ready')
getAuthTicket2(corpid, agentid)
});
wx && wx.error(function (res) {
// config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名。
console.log('wx.error', res)
alert(res.errMsg)
});
} else {
alert(res.return_message)
}
})
}
// 先获取应用的ticket
export function getAuthTicket2(corpid, agentid) {
MyGet('/chc-shop/api/v1/qywechat/jsapiticket/app', {}).then(res2 => {
console.log('先获取应用的ticket', res2);
alert('先获取应用的ticket')
alert(res2)
if (res2.success) {
alert('进入success')
obj.ticket2 = res2.data
const ticket2 = obj.ticket2 // 很重要!!!!
let nonceStr = 'Y7a8KkqX041bsSwT' // 随机字符串
let timeStamp = new Date().getTime() // 时间戳
let newTimeStamp = String(timeStamp).substr(0, 10) // 10位数的时间戳
// 当前网页的 URL(可以为本地局域网网址),不包含 # 及其后面部分
let url = String(location.href.split('#')[0])
let verifyStr = `jsapi_ticket=${ticket2}&noncestr=${nonceStr}×tamp=${newTimeStamp}&url=${url}`
let signature = sha1(verifyStr)
console.log('签名2', signature)
alert('签名2:' + signature)
alert(wx)
console.log('wx', wx);
alert(wx.agentConfig)
// 企业微信ios/mac 端如果出现 "wx.agentConfig undefined" 的报错,可将调用放在异步操作中进行,例如使用:setTimeout 包裹
setTimeout(() => {
alert('进入定时器')
wx.agentConfig({
corpid: corpid, // 必填,企业微信的corpid,必须与当前登录的企业一致 https://developer.work.weixin.qq.com/document/path/90665#agentid
agentid: agentid, // 必填,企业微信的应用id (e.g. 1000247) https://developer.work.weixin.qq.com/document/path/90665#agentid
// timestamp: +new Date(), // 必填,生成签名的时间戳
// nonceStr: +new Date(), // 必填,生成签名的随机串
timestamp: newTimeStamp, // 必填,生成签名的时间戳
nonceStr: nonceStr, // 必填,生成签名的随机串
signature: signature, // 必填,签名,见 附录-JS-SDK使用权限签名算法 https://developer.work.weixin.qq.com/document/path/90506
jsApiList: [
'getCurExternalChat',
'chooseCard',
], // 必填,需要使用的JS接口列表,凡是要调用的接口都需要传进来
success: function (res2) {
// 回调
console.log('success==', res2)
alert('success==' + res2)
wx.invoke('getCurExternalChat', {}, function (res) {
console.log('获取群id==', res)
if (res.err_msg == "getCurExternalChat:ok") {
// _this.chatId = res.chatId //返回当前外部群的群聊ID
alert('群ID:' + res.chatId)
} else {
//错误处理
alert('fail===' + res.err_msg)
}
})
return true
},
fail: function (res2) {
console.log('fail===', res2)
alert('fail===' + res2.errMsg)
if (res2.errMsg.indexOf('function not exist') > -1) {
alert('版本过低请升级')
return false
}
return false
}
})
}, 1000);
} else {
alert(res2.return_message)
return false
}
})
}
总结
提示:这里对文章进行总结:需要注意,只能本地先开发,然后将代码发布到线上,然后再去实际调试效果(可以先发布到自己测试的那个企业微信上看看效果,没问题再将代码的企业微信和应用id改真正的线上企业微信数据id)
更多推荐
所有评论(0)