Official account of WeChat official account official server using NodeJs as node backlog server, node verify official account tonken node WeChat official account development
Y-X Nanchuan 2021-06-04 10:08:06

Use NodeJs As WeChat official account server

The following demo code source address https://gitee.com/szxio/weChatServer

Official account for application test

Log in first WeChat public platform , Choose your own official account to log in. . After successful login, click developer tools , Select public platform test account

Click in and we can apply for a public official account. , Experience all advanced interfaces , Here we need to configure an online interface address , In the verification of Tonken, When sending and receiving messages, wechat will request our configured address , Here is an easy to use intranet penetration tool , We can map our local project address to the Internet , So that we can debug

Millet ball inner net penetration tool

The online address I generated here is http://songzx.ngrok2.xiaomiqiu.cn/, We will use this address as the interface configuration address of our official account.

image-20210518191538886

Realization Tonken verification

First, create a new blank node project

npm init -y

Then install some common dependencies

npm install express

Next, create a new project under the root path of the project index.js, The initial code is as follows

const express = require("express")
const app = express()
app.get("/",(req,res)=>{
res.send('Hello World')
})
app.listen(8088,()=>{
console.log("running 127.0.0.1:8088");
})

Then start the project and access it with a browser 127.0.0.1:8088 You can see the following results , Indicates that the service is started successfully

Now let's implement verification tonken The logic of

First install the following dependencies , Used for encryption processing

npm install crypto

Then build util and router Two folders , Place our unified method and ordinary request method separately

Then build util -> validateToken.js file , The code is as follows , This method is specially used to verify the data transmitted by wechat Tonken

var crypto = require("crypto");
// Encryption method
function sha1(str) {
var md5sum = crypto.createHash("sha1");
md5sum.update(str);
str = md5sum.digest("hex");
return str;
}
// verification tonken
function validateToken(req) {
return new Promise((resolve, reject) => {
let query = req.query;
let signature = query.signature;
let echostr = query["echostr"];
let timestamp = query["timestamp"];
let nonce = query["nonce"];
let oriArray = new Array();
oriArray[0] = nonce;
oriArray[1] = timestamp;
oriArray[2] = "admin123"; // This is in the official account interface configuration information. Token
oriArray.sort();
let original = oriArray.join("");
let scyptoString = sha1(original);
if (signature == scyptoString) {
// Verification passed , return echostr
resolve(echostr);
} else {
reject(false);
}
});
}
// Export validation Tonken The distribution of
module.exports = validateToken;

Then build router -> weChat.js file , This file is specially used to handle requests sent by wechat , Write the following code in this file

const express = require("express");
const router = express.Router(); // Configure routing module
const validateToken = require("../util/validateToken");
// get Request validation tonken effectiveness
router.get("/", (req, res) => {
validateToken(req).then((t) => {
res.send(t);
});
});
// export router
module.exports = router;

Finally, revise index.js file , Introduce our new router.js file

const express = require("express");
const app = express();
const path = require("path");
const weChat = require(path.resolve(__dirname, "./router/weChat"));
app.use(weChat);
app.listen(8088, () => {
console.log("running 127.0.0.1:8088");
});

Now let's test the configuration of WeChat official account.

image-20210519162630934

Pop up in page Configuration is successful It means we verify Tonken Our business has been completed

obtain Tonken And refresh it regularly

Wechat Tonken To send a get Request to get , And this Tonken There is an expiration date , We need to keep this on our own Tonken And refresh it regularly , In order to make sure Tonken effectiveness

Wechat official for access Tonken Description of

Interface call description

  • Request mode : GET
  • Request address :https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET

Since we need to use the request , Let's install a axios Used to send requests

npm install axios

Then create a new public -> tonken.json , It's used to store what we get tonken, It's also true tonken A way of persistent storage based on XML ,json The content of the document is empty

Then new util -> tonkenConfig.js file , The code is as follows

const fs = require("fs");
const path = require("path");
const http = require("axios");
const fileUrl = path.resolve(__dirname, "../public/tonken.json");
const APPID = "wx2188729b190d357d"; // Test number APPID
const APPSECRET = "d976b0e6262b829ba003e9a24032447c"; // Test number APPSECRET
let INTERTIME = (7200 - 60) * 1000; // Set a default periodic access tonken Time for
// preservation Tonken
function setTonken() {
return new Promise((resolve, reject) => {
http
.get(
`https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=${APPID}&secret=${APPSECRET}`
)
.then((res) => {
// to update tonken The expiration time of , Get it again every other time tonken
INTERTIME = (res.data.expires_in - 60) * 1000;
// Get Tonken Save to json In file
fs.writeFile(
fileUrl,
JSON.stringify({
tonken: res.data.access_token,
}),
() => {
// Inform the outside world Tonken To be successful
resolve();
}
);
});
});
}
// Time acquisition Tonken
function timingSetTonken() {
// Refresh regularly tonken
setInterval(() => {
setTonken();
}, INTERTIME);
}
// obtain Tonken
function getTonken() {
return new Promise((resolve, reject) => {
// from json Read the saved Tonken
fs.readFile(fileUrl, (err, data) => {
// Return the obtained tonken
resolve(JSON.parse(data).tonken);
});
});
}
// Export the encapsulated method
module.exports = {
setTonken, // to update tonken
getTonken, // Return the obtained tonken
timingSetTonken, // Regularly update tonken
};

And then in router -> weChat.js Introduction in tonkenConfig.js

const express = require("express");
const router = express.Router(); // Configure routing module
const validateToken = require("../util/validateToken");
const { setTonken, timingSetTonken } = require("../util/tonkenConfig");
// Get automatically after the project starts tonken Methods
setTonken().then(() => {
// tonken After obtaining success, start to refresh regularly tonken operation
timingSetTonken();
});
// get Request validation tonken effectiveness
router.get("/", (req, res) => {
validateToken(req).then((t) => {
res.send(t);
});
});
// export router
module.exports = router;

At this point, we will automatically call get after starting the project tonken The interface of , Then get an expiration time from the interface , The expiration time of wechat return is in seconds , subtract 60 Seconds is for the next time tonken Time and this time tonken Smooth transition between , Then it will be retrieved every other time tonken

This will make us tonken Written to a json In file , We can get it in any file through the following methods tonken

const { getTonken } = require("./util/tonkenConfig");
// Call encapsulated get token Method
getTonken().then((tonken) => {
console.log(tonken); // 45_7k55HHRaYxM4MkD4aREraHZpgdjmT......
});

Receive wechat message and reply

Official description of the message received

In short, it is : We sent messages to WeChat official account. , Wechat will send a post Please give us the address configured above , Parameter time period xml Text , We need to parse this xml, And reply in the format specified by wechat xml Format string , Note the reply xml Format string

Install dependencies first , Used to resolve post In the request xml Parameters

npm install express-xml-bodyparser

And then in index.js The middleware is referenced and configured in the file

const express = require("express");
const app = express();
const path = require("path");
const weChat = require(path.resolve(__dirname, "./router/weChat"));
const xmlparser = require('express-xml-bodyparser'); // analysis xml
app.use(express.json());
app.use(express.urlencoded());
app.use(xmlparser());
app.use(weChat);
app.listen(8088, () => {
console.log("running 127.0.0.1:8088");
});

And then in weChat.js Add a post request , Print it and see what wechat sent us

// post Request to process messages sent by wechat
router.post("/", (req, res) => {
console.log(req.body);
res.send("");
});

Restart project , We sent a message to WeChat official account.

The parameters are as follows

{
xml: {
tousername: [ 'gh_a0f004c20d2b' ],
fromusername: [ 'olttN6WJOYe-lTysV8_tsnZ7-HMQ' ],
createtime: [ '1621416487' ],
msgtype: [ 'text' ],
content: [ 'hello' ],
msgid: [ '23213103466653274' ]
}
}

After we get the parameters, we can use the msgtype Determine the type of message delivered , as well as content It's the message , Got the parameters , The next thing to do is to reply according to the message

Official passive reply to user message document

Here is the template code for a reply message , Can be very convenient to help us generate the specified xml Format string

// Reply text message
exports.textMessage = function (message) {
var createTime = new Date().getTime();
return `<xml>
<ToUserName><![CDATA[${message.FromUserName}]]></ToUserName>
<FromUserName><![CDATA[${message.ToUserName}]]></FromUserName>
<CreateTime>${createTime}</CreateTime>
<MsgType><![CDATA[text]]></MsgType>
<Content><![CDATA[${message.reply}]]></Content>
</xml>`;
};
// Reply to picture message
exports.imageMessage = function (message) {
var createTime = new Date().getTime();
return `<xml>
<ToUserName><![CDATA[${message.FromUserName}]]></ToUserName>
<FromUserName><![CDATA[${message.ToUserName}]]></FromUserName>
<CreateTime>${createTime}</CreateTime>
<MsgType><![CDATA[image]]></MsgType>
<Image>
<MediaId><![CDATA[${message.mediaId}]]></MediaId>
</Image>
</xml>`;
};
// Reply to voice message
exports.voiceMessage = function (message) {
var createTime = new Date().getTime();
return `<xml>
<ToUserName><![CDATA[${message.FromUserName}]]></ToUserName>
<FromUserName><![CDATA[${message.ToUserName}]]></FromUserName>
<CreateTime>${createTime}</CreateTime>
<MsgType><![CDATA[voice]]></MsgType>
<Voice>
<MediaId><![CDATA[${message.mediaId}]]></MediaId>
</Voice>
</xml>`;
};
// Reply to video message
exports.videoMessage = function (message) {
var createTime = new Date().getTime();
return `<xml>
<ToUserName><![CDATA[${message.FromUserName}]]></ToUserName>
<FromUserName><![CDATA[${message.ToUserName}]]></FromUserName>
<CreateTime>${createTime}</CreateTime>
<MsgType><![CDATA[video]]></MsgType>
<Video>
<MediaId><![CDATA[${message.mediaId}]]></MediaId>
<Title><![CDATA[${message.title}]]></Title>
<Description><![CDATA[${message.description}]]></Description>
</Video>
</xml>`;
};
// Reply to text message
exports.articleMessage = function (message) {
var createTime = new Date().getTime();
return `<xml>
<ToUserName><![CDATA[${message.FromUserName}]]></ToUserName>
<FromUserName><![CDATA[${message.ToUserName}]]></FromUserName>
<CreateTime>${createTime}</CreateTime>
<MsgType><![CDATA[news]]></MsgType>
<ArticleCount>${message.articles.length}</ArticleCount>
<Articles>
${message.articles
.map(
(article) =>
`<item><Title><![CDATA[${article.title}]]></Title>
<Description><![CDATA[${article.description}]]></Description>
<PicUrl><![CDATA[${article.img}]]></PicUrl>
<Url><![CDATA[${article.url}]]></Url></item>`
)
.join("")}
</Articles>
</xml>`;
};

stay weChat.js The template above is introduced in , I put the template code here util -> template.js in , Then modify the new one post Method

// Introduce message template
const template = require("../util/template");
// post Request to process messages sent by wechat
router.post("/", (req, res) => {
let xml = req.body.xml;
let msgtype = xml.msgtype[0];
switch (msgtype) {
case "text":
// Encapsulates the message parameters to reply to
let message = {
FromUserName: xml.fromusername[0],
ToUserName: xml.tousername[0],
reply: " How are you? , I replied to you through the code ",
};
res.send(template.textMessage(message));
break;
default:
res.send(""); // Not a text message, but a null response by default
break;
}
});

We're trying to send a message now

We see that the official account has been able to answer us. .

Please bring the original link to reprint ,thank
Similar articles

2021-08-09

2021-08-09