使用 NodeJs 响应微信请求

使用 NodeJs 响应微信请求

代码之外

前言

最近做项目, 需要用nodejs开发weixin的自动回复系统(包括菜单事件什么的, 在github上简单看了一些库, 发现都有一个类似的bug. 每当用户发送消息的时候, 微信服务器都会向我们的nodejs服务器发送一个POST请求, 包括 node-wechat, weixin_api, node-weixin, 在收到 POST 请求之后将请求的 response 设置在全局位置, 这样在多条消息同时到来的时候会有问题. 先来的消息很有可能会通过后面的 response 发送消息. 这个问题我和 node-wechat 的作者 nswbmw 提出了, 他好心的要修改一下, 但是,我现在很立刻就需要呀~ 所以就自己动手了. 写的时候也参考了文中提到的三个库的优缺点, 在此一并谢过~ 高级功能会在日后逐渐完善, 希望有好心人一起完整其他功能~

注意事项

  • 有的时候同一条消息会触发多次,是因为在 5s 内,你的服务器没有给weixin服务器相应,weixin服务器会在未来的有限时间内不断的向你的服务器发送同一条消息的请求。可以通过 MsgId 来判断是否为同一条消息

Nodejs Wechat

NPM version Build Status

Nodejs wrapper of wechat api

Usage

Work with native http server

var http = require('http');
var xmlBodyParser = require('express-xml-parser');
var Wechat = require('nodejs-wechat');

var opt = { token: ‘TOKEN’, url: ‘/’ }; var parse = xmlBodyParser({ type: ‘text/xml’ }); var wechat = new Wechat(opt); wechat.on(‘event.subscribe’, function(session) { session.replyTextMsg(‘欢迎您关注我们的订阅号’); }); var server = http.createServer(function(req, res) { if (req.method === ‘GET’) { wechat.verifyRequest(req, res); } else { parse(req, res, function(err) { if (err) { res.end(); return; } wechat.handleRequest(req, res); }); } }); server.listen(80);

Work with express

var express = require('express');
var app = express();
var middlewares = require('express-middlewares-js');
app.use('/weixin', middlewares.xmlBodyParser({
  type: 'text/xml'
}));

/*
  Alternative way

var xmlBodyParser = require('express-xml-parser');
app.use('/weixin', xmlBodyParser({
  type: 'text/xml',
  limit: '1mb'
}));

*/

var Wechat = require('nodejs-wechat');
var opt = {
  token: token,
  url: '/weixin'
};
var wechat = new Wechat(opt);

app.get('/weixin', wechat.verifyRequest.bind(wechat));
app.post('/weixin', wechat.handleRequest.bind(wechat));

// you can also work with other restful routes
app.use('/api', middlewares.bodyParser());

wechat.on('text', function(session) {
  session.replyTextMsg('Hello World');
});
wechat.on('image', function(session) {
  session.replyNewsMsg([{
    Title: '新鲜事',
    Description: '点击查看今天的新鲜事',
    PicUrl: 'http://..',
    Url: 'http://..'
  }]);
});
wechat.on('voice', function(session) {
  session.replyMsg({
    Title: 'This is Music',
    MsgType: 'music',
    Description: 'Listen to this music and guess ths singer',
    MusicUrl: 'http://..',
    HQMusicUrl: 'http://..',
    ThumbMediaId: '..'
  });
});

app.listen(80);

NOTE: We apply { type: 'text/xml' } to xmlBodyParser as weixin server send us a text/xml content type instead of application/xml.

API

Wechat

  • #verifyRequest(req, res)

    This is a express/connect middleware, which verify the signature of request from weixin server

  • #handleRequest(req, res)

    This is a express/connect middleware, which handle the request post from weixin server

  • #on(msgType, handler)

    Wechat is an inheritance from event.EventEmitter. Wechat will emit an event in incoming message’s MsgType, with a Session as parameter. Valid events:

    text, image, voice, video, location, link, event.subscribe, event.unsubscribe, event.SCAN, event.LOCATION, event.CLICK, event.VIEW, error

    References: 接收普通消息, 接收事件推送

Session

  • incomingMessage

    This is a direct parse of weixin server request

<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[FromUser]]></FromUserName>
<CreateTime>123456789</CreateTime>
<MsgType><![CDATA[event]]></MsgType>
<Event><![CDATA[subscribe]]></Event>
</xml>

Becomes

{
  "ToUserName": "toUser",
  "FromUserName": "FromUser",
  "CreateTime": "123456789",
  "MsgType": "event",
  "Event": "subscribe"
}
  • req

    This is the request from weixin server

  • res

    This is the response to weixin server

  • #replyMsg(msgObject)

    Reply a message via this.res

  • #replyTextMessage(content)

    Reply a text message

  • #replyNewsMessage(articles)

    Reply a news messages.

TODO

  • Advanced interfaces

    Will finish advanced interfaces before July/2014, welcome send pull requests :)


8 回复

使用 NodeJs 响应微信请求

前言

最近在项目中需要使用 Node.js 开发一个微信自动回复系统,包括处理菜单事件等。在 GitHub 上简单查看了一些库,发现它们都存在一个类似的问题:每当用户发送消息时,微信服务器会向我们的 Node.js 服务器发送一个 POST 请求。这些库在收到 POST 请求后,将响应设置在全局位置,这在多条消息同时到达时可能会导致问题。先来的消息可能会通过后来的响应发送消息。

我与 node-wechat 的作者 nswbmw 提出了这个问题,他也表示愿意修改,但我现在急需解决这个问题,因此决定自己动手。在编写代码的过程中,我也参考了其他几个库的优点和缺点,在此感谢这些库的贡献者们。高级功能会在日后逐步完善,希望有好心人能够一起完善其他功能。

注意事项

  • 有时候同一条消息会触发多次,这是因为你在 5 秒内没有给微信服务器相应的响应,微信服务器会在未来的有限时间内不断向你的服务器发送同一条消息的请求。可以通过 MsgId 来判断是否为同一条消息。

Nodejs Wechat

以下是使用 Node.js 开发微信自动回复系统的步骤和示例代码:

// 安装依赖包
npm install express xmlbodyparser nodejs-wechat
示例代码:使用原生 HTTP 服务器
const http = require('http');
const xmlBodyParser = require('xmlbodyparser');
const Wechat = require('nodejs-wechat');

const opt = {
  token: 'YOUR_TOKEN',
  url: '/'
};

const parse = xmlBodyParser({ type: 'text/xml' });

const wechat = new Wechat(opt);

wechat.on('event.subscribe', function(session) {
  session.replyTextMsg('欢迎您关注我们的订阅号');
});

const server = http.createServer(function(req, res) {
  if (req.method === 'GET') {
    wechat.verifyRequest(req, res);
  } else {
    parse(req, res, function(err) {
      if (err) {
        res.end();
        return;
      }
      wechat.handleRequest(req, res);
    });
  }
});

server.listen(80, () => {
  console.log('Server listening on port 80');
});
示例代码:使用 Express 框架
const express = require('express');
const app = express();
const middlewares = require('xmlbodyparser');
const Wechat = require('nodejs-wechat');

const opt = {
  token: 'YOUR_TOKEN',
  url: '/weixin'
};

const wechat = new Wechat(opt);

app.use('/weixin', middlewares.xmlBodyParser({ type: 'text/xml' }));

app.get('/weixin', wechat.verifyRequest.bind(wechat));
app.post('/weixin', wechat.handleRequest.bind(wechat));

wechat.on('text', function(session) {
  session.replyTextMsg('Hello World');
});

wechat.on('image', function(session) {
  session.replyNewsMsg([{
    Title: '新鲜事',
    Description: '点击查看今天的新鲜事',
    PicUrl: 'http://..',
    Url: 'http://..'
  }]);
});

wechat.on('voice', function(session) {
  session.replyMsg({
    Title: 'This is Music',
    MsgType: 'music',
    Description: 'Listen to this music and guess the singer',
    MusicUrl: 'http://..',
    HQMusicUrl: 'http://..',
    ThumbMediaId: '..'
  });
});

app.listen(80, () => {
  console.log('Express server listening on port 80');
});

API 文档

Wechat 类
  • #verifyRequest(req, res):验证来自微信服务器的请求签名。
  • #handleRequest(req, res):处理来自微信服务器的 POST 请求。
  • #on(msgType, handler):监听特定类型的微信消息,如文本、图片、语音等。
Session 类
  • incomingMessage:直接解析微信服务器的请求。
  • req:微信服务器的请求对象。
  • res:响应微信服务器的对象。
  • #replyMsg(msgObject):通过 this.res 回复消息。
  • #replyTextMsg(content):回复文本消息。
  • #replyNewsMsg(articles):回复图文消息。

TODO

  • 实现更高级的接口,欢迎提交 Pull Requests。

通过以上代码和文档,你可以快速搭建一个基本的微信自动回复系统。


https://github.com/node-webot/weixin-robot 楼主试试这个? 更结构化地管理回复规则。

之前我按 node-weixin 的 pattern 把后面的代码写完了,后来发现他居然有bug。现在用自己写的这个也还可以,而且也没什么 bug 。你写的这个确实也不错呀~ 哈哈 但是我写的这个可以这样用

wechat.on('image', uploadImageToQiniu);
wechat.on('image', handleImageMessage);

集成过weixin-robot还不错…

node-webot 里的好像质量都挺好~

mark学习

感谢,对我很有帮助! xmlBodyParser中加一个这个 explicitArray: false ,不然解析出来的属性都是数组。

为了响应微信的请求,我们可以使用Node.js来处理微信服务器发来的消息或事件。以下是一个简单的示例,展示如何使用Node.js创建一个基本的微信自动回复系统。

示例代码

const express = require('express');
const bodyParser = require('body-parser');
const Wechat = require('nodejs-wechat'); // 假设有一个名为nodejs-wechat的库

const app = express();
const port = 80;

// 使用中间件解析XML格式的数据
app.use(bodyParser.raw({type: 'text/xml'}));

const token = 'your-token-here';
const wechat = new Wechat({token: token, url: '/wechat'});

// 处理微信验证请求
app.get('/wechat', (req, res) => {
  wechat.verifyRequest(req, res);
});

// 处理微信服务器发送的消息或事件
app.post('/wechat', (req, res) => {
  wechat.handleRequest(req, res);
});

// 监听文本消息
wechat.on('text', (session) => {
  const content = session.incomingMessage.Content || '';
  session.replyTextMsg(`您发送的消息是: ${content}`);
});

// 监听关注事件
wechat.on('event.subscribe', (session) => {
  session.replyTextMsg('欢迎关注我们的公众号!');
});

app.listen(port, () => {
  console.log(`Server running on port ${port}`);
});

解释

  1. 引入必要的模块:这里我们引入了express用于创建HTTP服务器,body-parser用于解析请求体中的XML数据,以及nodejs-wechat用于处理微信服务器的请求。

  2. 创建Express应用:我们创建了一个Express应用实例,并设置了监听端口为80。

  3. 配置中间件:我们使用bodyParser.raw()中间件来解析传入的XML数据。

  4. 初始化Wechat实例:创建了一个Wechat实例,指定了token和URL路径。

  5. 处理微信验证请求:对于GET请求,我们调用wechat.verifyRequest()方法来验证请求的有效性。

  6. 处理微信消息或事件:对于POST请求,我们调用wechat.handleRequest()方法来处理接收到的消息或事件。

  7. 监听事件和消息:我们通过wechat.on()方法来监听特定类型的消息或事件,并作出相应的回复。

这样,我们就完成了一个基本的微信自动回复系统的搭建。

回到顶部