应对企微认证考试,写了node版的企微对接
This commit is contained in:
@@ -22,11 +22,13 @@
|
|||||||
},
|
},
|
||||||
"author": "kubbo",
|
"author": "kubbo",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@wecom/crypto": "^1.0.1",
|
||||||
"axios": "^1.2.1",
|
"axios": "^1.2.1",
|
||||||
"dayjs": "^1.11.0",
|
"dayjs": "^1.11.0",
|
||||||
"express": "^4.17.3",
|
"express": "^4.17.3",
|
||||||
"express-async-errors": "^3.1.1",
|
"express-async-errors": "^3.1.1",
|
||||||
"express-ws": "^5.0.2",
|
"express-ws": "^5.0.2",
|
||||||
|
"form-data": "^4.0.0",
|
||||||
"fs-extra": "^10.0.1",
|
"fs-extra": "^10.0.1",
|
||||||
"helmet": "^5.0.2",
|
"helmet": "^5.0.2",
|
||||||
"mysql": "^2.18.1",
|
"mysql": "^2.18.1",
|
||||||
|
|||||||
20
src/rest/addressBook/action.js
Normal file
20
src/rest/addressBook/action.js
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
const {getSignature, decrypt} = require("@wecom/crypto");
|
||||||
|
const {addOrUpdate} = require("../../utils/dbUitls");
|
||||||
|
const token = "OTUlglGGoGm7EKKpKeg6tc"
|
||||||
|
const encodingAESKey = "LHLwd2nhbia4iCEfyDJkUPBb9TT7G8GMlWpgqzNHODi"
|
||||||
|
module.exports = {
|
||||||
|
action: "/wxwork/addressBook/action",
|
||||||
|
method: "post",
|
||||||
|
execute: (request, response) => {
|
||||||
|
const {msg_signature, timestamp, nonce, echostr} = request.query
|
||||||
|
const signature = getSignature(token, timestamp, nonce, echostr);
|
||||||
|
if (msg_signature == signature) {
|
||||||
|
const context = decrypt(encodingAESKey, echostr)
|
||||||
|
const {name, mobile: phone, email, userId} = context
|
||||||
|
addOrUpdate({
|
||||||
|
table: "sys_user", form: {name, email, phone, userId}
|
||||||
|
})
|
||||||
|
response.send({code: 0, message: "success"})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
15
src/rest/addressBook/actionGet.js
Normal file
15
src/rest/addressBook/actionGet.js
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
const {getSignature, decrypt} = require("@wecom/crypto");
|
||||||
|
const token = "OTUlglGGoGm7EKKpKeg6tc"
|
||||||
|
const encodingAESKey = "LHLwd2nhbia4iCEfyDJkUPBb9TT7G8GMlWpgqzNHODi"
|
||||||
|
module.exports = {
|
||||||
|
action: "/wxwork/addressBook/action",
|
||||||
|
method: "get",
|
||||||
|
execute: (request, response) => {
|
||||||
|
const {msg_signature, timestamp, nonce, Encrypt} = request.query
|
||||||
|
const signature = getSignature(token, timestamp, nonce, Encrypt);
|
||||||
|
if (msg_signature == signature) {
|
||||||
|
const context = decrypt(encodingAESKey, Encrypt)
|
||||||
|
response.send(context)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
48
src/rest/addressBook/add.js
Normal file
48
src/rest/addressBook/add.js
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
const dbUtils = require("../../utils/dbUitls");
|
||||||
|
const fs = require('fs');
|
||||||
|
const FormData = require('form-data');
|
||||||
|
const fastcsv = require('fast-csv');
|
||||||
|
const axios = require("axios");
|
||||||
|
|
||||||
|
//生成csv并上传至企微后台获取 media_id
|
||||||
|
const uploadCsv = (data = [], access_token) => {
|
||||||
|
// data数据格式
|
||||||
|
// {"name": "张三", "email": "john.doe@example.com",phone:"13388888888"},
|
||||||
|
const csv = data.map(e => {
|
||||||
|
return {
|
||||||
|
"姓名": e.name,
|
||||||
|
"账号": e.phone,
|
||||||
|
"手机号": e.phone,
|
||||||
|
"邮箱": e.email,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
const form = new FormData()
|
||||||
|
const csvStream = fastcsv.format({headers: true})
|
||||||
|
csvStream.pipe(fs.createWriteStream('tmp.csv'))
|
||||||
|
data.forEach(item => csvStream.write(item))
|
||||||
|
csvStream.end()
|
||||||
|
form.append('media', fs.createReadStream('tmp.csv'))
|
||||||
|
return axios.post(`https://qyapi.weixin.qq.com/cgi-bin/media/upload?access_token=${access_token}&type=file`, {
|
||||||
|
headers: form.getHeaders()
|
||||||
|
}).then(res => {
|
||||||
|
const {media_id} = res.data
|
||||||
|
return media_id
|
||||||
|
})
|
||||||
|
}
|
||||||
|
module.exports = {
|
||||||
|
action: "/wxwork/addressBook/syncUser",
|
||||||
|
method: "post",
|
||||||
|
execute: (request, response) => {
|
||||||
|
const {access_token} = request.body
|
||||||
|
// 获取原CA账号数据
|
||||||
|
dbUtils.list({
|
||||||
|
table: "sys_user",
|
||||||
|
}).then(data => uploadCsv(data, access_token))
|
||||||
|
.then(media_id => {
|
||||||
|
// 上传csv至企微后台
|
||||||
|
return axios.post(`https://qyapi.weixin.qq.com/cgi-bin/batch/replaceuser?access_token=${access_token}`, {
|
||||||
|
media_id
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
22
src/rest/addressBook/token.js
Normal file
22
src/rest/addressBook/token.js
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
const axios = require("axios");
|
||||||
|
const CORPID = "ww596787bb70f08288"
|
||||||
|
const SECRET = "Bh3GT11_bzxSm03xZBY8otjw_WLWeLsduzDQweUohAY"
|
||||||
|
const getAccessToken = (corpid = CORPID, secret = SECRET) => {
|
||||||
|
const url = `https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=${corpid}&corpsecret=${secret}`
|
||||||
|
return axios.get(url).then(res => {
|
||||||
|
return res.data?.access_token
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
action: "/wxwork/addressBook/token",
|
||||||
|
method: "post",
|
||||||
|
execute: (request, response) => {
|
||||||
|
getAccessToken().then(token => {
|
||||||
|
response.send({code: 0, token})
|
||||||
|
}).catch(err => {
|
||||||
|
console.log(err)
|
||||||
|
response.send({code: 1, err})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user