Node.js开发微信公众号:微信事件交互实战

作者:接口漫谈

时间:2026-10-29

浏览:167

本文详解Node.js环境下微信公众号开发者模式的事件交互流程。通过监听微信服务器推送的XML数据,验证签名后解析用户OpenID,并利用微信API获取用户头像、昵称等基础信息。文章结合策略模式代码示例,展示如何将关注事件数据存入数据库以建立用户会话,实现无需二次认证的网页访问体验。

文章目录

Node.js微信公众号交互入口

在微信公众号平台中,若启用了开发者模式,所有常规功能均需通过接口调用实现,例如自定义菜单必须通过POST请求生成。本节以用户从关注到取消关注的完整流程为例,阐述Node.js如何与微信服务器进行交互。交互的入口即你在测试公众号配置中填写的URL(下文以/login/wechat指代)。

微信事件交互流程

事件交互机制

当用户扫码关注公众号后,微信服务器会向你的接口/login/wechat发起请求,并附带一段XML格式的数据。首先,你需要提取签名参数,通过加密算法排序并与预设的TOKEN进行比对,验证一致后方可解析XML内容。在Node.js环境中解析XML需先引入相应模块,因此第一步是加载xml解析库。


//xml解析模块
var XMLJS = require('xml2js');
//解析,将xml解析为json
var parser = new XMLJS.Parser();
//重组,将json重组为xml
var builder = new XMLJS.Builder(); 

XML数据解析与字段说明

通过监听req对象的data事件,可以接收微信发送的XML数据包。以下展示了一个新用户关注公众号后,微信向后台接口(即前文提到的/yourapi)发送的XML数据示例。经解析后,其数据结构如下所示:

Node.js微信公众号交互入口

tousername字段表示接收方,此处为公众微信号。

fromusername字段表示发送方,此处对应用户的OpenID。

createTime字段记录消息发送的时间戳。

msgtype字段标识消息类型,包括event(事件响应)、text(文本消息)、image(图文消息)等。

event字段指明具体事件名称,此处特指“关注”事件。

eventkey字段为自定义Key,可在设置网页时定义,后文将对此进行说明。

上述内容即为微信在用户关注后向接口发送的数据包结构。其中,fromusername字段(即用户的OpenID)最为关键。获取该OpenID后,可通过微信提供的特定接口(https://api.weixin.qq.com/cgi-bin/user/info?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN)获取用户的头像、性别、昵称等详细信息,从而为你的应用程序构建可靠的用户资料库。

基于策略模式的代码实现

代码实现方案


//微信事件推送的入口
app.post('/yourapi', function(req, res, next) {
//获取参数
var query = req.query; 
//签名
var signature = query.signature; 
//输出的字符,你填写的TOKEN 
var echostr = query.echostr; 
//时间戳
var timestamp = query['timestamp']; 
//随机字符串
var nonce = query.nonce; 
var oriArray = new Array(); 
oriArray[] = nonce; 
oriArray[] = timestamp; 
oriArray[] = appConfig.token;
//排序参数
oriArray.sort(); 
var original = oriArray[]+oriArray[]+oriArray[]; 
//加密
var scyptoString = sha(original); 
//判断是否与你填写TOKEN相等
if (signature == scyptoString) {
//获取xml数据
req.on("data", function(data) {
//将xml解析
parser.parseString(data.toString(), function(err, result) {
var body = result.xml;
var messageType = body.MsgType[];
//用户点击菜单响应事件
if(messageType === 'event') {
var eventName = body.Event[];
(EventFunction[eventName]||function(){})(body, req, res);
//自动回复消息
}else if(messageType === 'text') {
EventFunction.responseNews(body, res);
//第一次填写URL时确认接口是否有效
}else {
res.send(echostr);
}
});
});
} else { 
//认证失败,非法操作
res.send("Bad Token!"); 
}
});
//微信客户端各类回调用接口
var EventFunction = {
//关注
subscribe: function(result, req, res) {
//存入openid 通过微信的接口获取用户的信息同时存入数据库。
},
//注销
unsubscribe: function(openid, req, res) {
//删除对应id
},
//打开某个网页
VIEW: function() {
//根据需求,处理不同的业务
},
//自动回复
responseNews: function(body, res) {
//组装微信需要的json
var xml = {xml: {
ToUserName: body.FromUserName,
FromUserName: body.ToUserName,
CreateTime: + new Date(),
MsgType: 'text',
Content: '编辑@+您想说的话,我们可以收到'
}};
var reciviMessage = body.Content[]
if(/^\@.*/.test(reciviMessage)) {
xml.xml.Content = '已经收到您的建议,会及时处理!'
}<br>//将json转为xml
xml = builder.buildObject(xml);<br>//发送给微信
res.send(xml);
}
}

在此场景下,建议采用JavaScript设计模式中的策略模式。在subscribe方法中编写具体业务逻辑,通过发送携带openid参数的请求,可在用户关注时将基本资料存入数据库并建立会话。这样,当用户后续访问你的网页时,无需再次进行完整认证,只需比对OpenID并查询数据库即可完成身份确认。

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章