应对企微认证考试,写了node版的企微对接

This commit is contained in:
aixianling
2023-12-01 09:51:03 +08:00
parent 857825af4a
commit 76ed5c0028
5 changed files with 107 additions and 0 deletions

View File

@@ -22,11 +22,13 @@
},
"author": "kubbo",
"dependencies": {
"@wecom/crypto": "^1.0.1",
"axios": "^1.2.1",
"dayjs": "^1.11.0",
"express": "^4.17.3",
"express-async-errors": "^3.1.1",
"express-ws": "^5.0.2",
"form-data": "^4.0.0",
"fs-extra": "^10.0.1",
"helmet": "^5.0.2",
"mysql": "^2.18.1",

View 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"})
}
}
}

View 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)
}
}
}

View 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
})
})
}
}

View 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})
})
}
}