diff --git a/index.js b/index.js index c9c5dae..820b608 100644 --- a/index.js +++ b/index.js @@ -1,4 +1,5 @@ const express = require('express') +const xmlparser = require('express-xml-bodyparser'); require("express-async-errors") const db = require('./src/utils/dbUitls') const rest = require('./src/rest') @@ -13,7 +14,9 @@ chalk.level = 1 app.listen(port, () => { db.init() app.use(express.json()) // for parsing application/json + app.use(xmlparser()); app.use(express.urlencoded({extended: true, limit: '50mb'})) // for parsing application/x-www-form-urlencoded + Promise.all([rest.init(app)]).then(() => { log(`${chalk.bgGreen.black(" DONE ")} serve is listening on ${port}`) ws.init(app) diff --git a/package.json b/package.json index 0bba0a9..e655c4e 100644 --- a/package.json +++ b/package.json @@ -28,12 +28,15 @@ "express": "^4.17.3", "express-async-errors": "^3.1.1", "express-ws": "^5.0.2", + "express-xml-bodyparser": "^0.3.0", "fast-csv": "^4.3.6", "form-data": "^4.0.0", "fs-extra": "^10.0.1", "helmet": "^5.0.2", + "jsonwebtoken": "^9.0.2", "mysql": "^2.18.1", - "uuid": "^8.3.2" + "uuid": "^8.3.2", + "xml2js": "^0.6.2" }, "devDependencies": { "chalk": "^4.1.2" diff --git a/src/config/auth.js b/src/config/auth.js new file mode 100644 index 0000000..2c69082 --- /dev/null +++ b/src/config/auth.js @@ -0,0 +1,23 @@ +const auth = require("jsonwebtoken"); +module.exports = { + //key wxtest token + secret: "ddb64c99f29d310c", + verifyToken(req, res, next) { + const token = req.headers['authorization']; + + if (!token) { + return res.status(401).json({message: 'No token provided'}); + } + + auth.verify(token, this.secret, (err, decoded) => { + if (err) { + return res.status(403).json({message: 'Failed to authenticate token'}); + } + req.userId = decoded.userId; + next(); + }); + }, + generateToken(userId) { + return auth.sign({userId}, this.secret, {expiresIn: '24h'}); + } +} diff --git a/src/rest/wxtest/action.js b/src/rest/wxtest/action.js index 452880d..93c34f9 100644 --- a/src/rest/wxtest/action.js +++ b/src/rest/wxtest/action.js @@ -1,20 +1,71 @@ const {getSignature, decrypt} = require("@wecom/crypto"); -const {addOrUpdate} = require("../../utils/dbUitls"); +const {Parser} = require("xml2js"); +const {query} = require("../../utils/dbUitls"); +const dayjs = require("dayjs"); +const axios = require("axios"); +const {getAccessToken} = require("./getUserInfo"); const token = "pnYAdXEHYzYhIyzE6Qbs2L" const encodingAESKey = "fHkOHrUGSVUmPjFmshLEFN2XbaqF3OxsuYgnJu6DB1G" + +let accessToken + +const reply = (agentid, to, content) => { + axios.post("https://qyapi.weixin.qq.com/cgi-bin/message/send", { + touser: to, agentid, msgtype: "markdown", markdown: { + content + } + }, {params: {access_token: accessToken}}) +} +/** + * 获取当前值班人并将信息发送给询问人,同时通知值班人员 + * @param params + */ +const handleReplyDutyInfo = (params) => { + const {FromUserName: touser, AgentID: agentid} = params, + now = dayjs().format("YYYY-MM-DD HH:mm:ss"), + sql = `select * from node_wx_test_duty where dutyStartTime<='${now}' and dutyEndTime>='${now}'` + query(sql).then(res => { + const info = res?.[0] || {} + if (info.dutyUserId) { + getAccessToken().then(access_token => { + accessToken = access_token + /** + * 回复查询值班信息给查询人 + */ + reply(agentid, touser, `当前值班信息如下\n>值班时间:${info.dutyStartTime} - ${info.dutyEndTime}\n值班人员:${info.dutyUserName}\n`) + /** + * 通知提醒值班人员 + */ + reply(agentid, info.dutyUserId, `今天轮到你值班了,请知悉~`) + }) + } else { + /** + * 无值班人员 + */ + reply(agentid, touser, `今天没有值班人员哦~`) + } + }) +} + + module.exports = { action: "/node/wxtest/action", method: "post", execute: (request, response) => { - const {msg_signature, timestamp, nonce, echostr} = request.query - const signature = getSignature(token, timestamp, nonce, echostr); + const {msg_signature, timestamp, nonce} = request.query, + {xml: {encrypt}} = request.body + const signature = getSignature(token, timestamp, nonce, encrypt[0]); 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} + const context = decrypt(encodingAESKey, encrypt[0]) + const parser = new Parser({explicitArray: false}) + parser.parseString(context.message, (err, result) => { + if (!err) { + if (result.xml.Content == '值班') { + handleReplyDutyInfo(result.xml) + } + response.send({code: 0, message: "success"}) + } else response.send({code: 1, err}) }) - response.send({code: 0, message: "success"}) - }else response.send({code: 1, message: "error"}) + } else response.send({code: 1, message: "error"}) } } diff --git a/src/rest/wxtest/actionGet.js b/src/rest/wxtest/actionGet.js index 58a3097..4a1694f 100644 --- a/src/rest/wxtest/actionGet.js +++ b/src/rest/wxtest/actionGet.js @@ -5,12 +5,11 @@ module.exports = { action: "/node/wxtest/action", method: "get", execute: (request, response) => { - const {msg_signature, timestamp, nonce, Encrypt} = request.query - const signature = getSignature(token, timestamp, nonce, Encrypt); - console.log(msg_signature, signature) + const {msg_signature, timestamp, nonce, echostr} = request.query + const signature = getSignature(token, timestamp, nonce, echostr); if (msg_signature == signature) { - const context = decrypt(encodingAESKey, Encrypt) - response.send(context) + const context = decrypt(encodingAESKey, echostr) + response.send(context.message) } else { response.send({code: 1, message: "验证不通过"}) } diff --git a/src/rest/wxtest/getUserInfo.js b/src/rest/wxtest/getUserInfo.js index 1fb0c93..c1c7344 100644 --- a/src/rest/wxtest/getUserInfo.js +++ b/src/rest/wxtest/getUserInfo.js @@ -1,6 +1,8 @@ const axios = require("axios"); +const auth = require("../../config/auth.js") const CORPID = "ww596787bb70f08288" -const SECRET = "Bh3GT11_bzxSm03xZBY8otjw_WLWeLsduzDQweUohAY" +const SECRET = "ZEpS51fCRPznHG16k0z1lfxaH0VciEnBljeP9aR47VU" + /** * 获取access_token */ @@ -14,7 +16,7 @@ const getAccessToken = (corpid = CORPID, secret = SECRET) => { * 获取 userId及其他信息 */ const getUserInfo = (accessToken, code) => { - return axios.get(`https://qyapi.weixin.qq.com/cgi-bin/user/getuserinfo`, { + return axios.get(`https://qyapi.weixin.qq.com/cgi-bin/auth/getuserinfo`, { params: {access_token: accessToken, code} }) } @@ -24,15 +26,18 @@ module.exports = { execute: (request, response) => { const {code} = request.query getAccessToken().then(token => getUserInfo(token, code)).then(res => { - if (res?.data?.data) { - response.send({code: 0, data: res.data.data}) + const userid = res?.data?.userid + //userid换取我方系统token + if (userid) { + const token = auth.generateToken(userid) + response.send({code: 0, token}) } else { - console.log(res.data) response.send({code: 1, err: res.data}) } }).catch(err => { console.log(err) response.send({code: 1, err}) }) - } + }, + getAccessToken } diff --git a/src/rest/wxtest/token.js b/src/rest/wxtest/token.js index 00e78e8..1e08e29 100644 --- a/src/rest/wxtest/token.js +++ b/src/rest/wxtest/token.js @@ -9,7 +9,7 @@ const getAccessToken = (corpid = CORPID, secret = SECRET) => { } module.exports = { - action: "/node/wxtest/token", + action: "/node/wxtest/access", method: "post", execute: (request, response) => { getAccessToken().then(token => {