node.js 调用 wechat 开发微信公众号自定义接口及中间件简介
上一次给公众号做自定义接口已经是很久以前的事了.....以至于今天发现那个公众号的接口已经不能服务了.
访问公众号直接给出提示"该公众号暂时无法提供服务,请稍后再试"
我想难道是年久失修? 也不应该啊,这么牛x的公司绝对不会修改api,或者是更新api不兼容之类的.....看来问题还是出在我这边.
我甚至忘记了公众号登录密码.
进去后复制接口链接地址到浏览器地址栏,发现是可以访问的,那么问题出在哪里?
难道腾讯知道我好久没有维护此号了.所以暂时不提供服务了,想想以前网易邮箱经常被冻结,我竟然真的以为是这样的了.
所以:我尝试前后到编辑模式,然后再切换回来,依然不提供服务...
我试图改了token ,尝试还是不行....
最后,我终于发现了那个 www ,没错,之前我的站点主域是 www.yijiebuyi.com ,后来我折腾几次,改成了现在的样子 yijiebuyi.com
而且对于www开头的域名做了一个301跳转.去掉www就好了,接口不能跳转的.
使用:
npm install wechat
var wechat = require('wechat');
wechat 是一个中间件
exports.wechat_method=wechat('你定义的token', function (req,res) { var message=req.weixin; if (message && message.MsgType == 'text') { var text = ''; var description = ''; switch (message.Content) { case '关键词1': res.reply({ content: 'hello world!', type: 'text' }); break; case '关键词2': text = '关键词2'; description = message.ToUserName + '----' + message.FromUserName; res.reply([ { title: text, description: description, picurl: '图片绝对地址', url: '' } ]); break; default: //默认回复文本消息 res.reply({ content: '消息已收到', type: 'text' }); break; } } else if (message && message.Event) { switch (message.Event) { case 'subscribe': res.reply({ content: '关注事件', type: 'text' }); break; case 'unsubscribe': //取消关注 break; default: res.reply({ content: 'O(∩_∩)O~', type: 'text' }); break; } } });
看到上面的方法,你应该发现 req,res 非常奇怪.
因为他不再是你认为的req和res了.
req有了 weixin 的属性.
res 有了 reply 的方法.
因为上面调用 wechat 中间件,然后对req,res 做了包装.
wechat包括下面几种不同的调用方法.
1.
wechat(token, function (req, res, next) {});
我们上面用的就是这一种,把req,res 传入,next 指向下一个中间件队列需要处理的中间件
2.
wechat(token, wechat.text(function (message, req, res, next) { // 这里处理文本类消息 }).location(function (message, req, res, next) { // 这里处理地理位置消息 (就是分享一个地理位置) })//后面还可以链式处理其他类型的消息 );
3.
wechat(token) .text(function (message, req, res, next) { // 处理文本类消息 }).location(function (message, req, res, next) { // 处理地理位置消息 }).middleware();//后面依然可以链式调用
一共支持下面几种类型的消息处理:
* - `text`,处理文字推送的回调函数,接受参数为(text, req, res, next)。
* - `image`,处理图片推送的回调函数,接受参数为(image, req, res, next)。
* - `voice`,处理声音推送的回调函数,接受参数为(voice, req, res, next)。
* - `video`,处理视频推送的回调函数,接受参数为(video, req, res, next)。
* - `location`,处理位置推送的回调函数,接受参数为(location, req, res, next)。
* - `link`,处理链接推送的回调函数,接受参数为(link, req, res, next)。
* - `event`,处理事件推送的回调函数,接受参数为(event, req, res, next)。
顺便我们了解一下node.js 中的中间件:
最出名的中间件模块非 Connect 莫属了.其中 express 就是在此模块上构建起来的.
它内部维护了一个中间件队列,队列中的每一个中间件都有一个next指针,指向下一个中间件.每一个中间件就像U盘,可以插拔一样.
我们实现一个最简单的中间件:
function (req, res, next) { // 中间件 }
一个非常简单的中间件实现过程,处理完请求,执行 next() --> 指向中间件队列里的下一个请求
我们之前写的关于判断登录,图片防盗链,301跳转等,其实都是一个中间件的实现.
中间件处理流程大致分为3种:
1. pre-request 用来改写 request 的原始数据.
2. request /response 我们常常写的一些处理,过滤等操作,就是类似这样的中间件
3. post-response 全局处理,改写 response 数据等.
像上面介绍的微信处理中间件这3个过程都经历了,因为它不仅修改了request ,而且还修改了 response .
我们用express 创建web项目的时候,常见的 use() 就是一个典型的中间件使用环境.
var app = connect(); // Middleware app.use(connect.staticCache()); app.use(connect.cookieParser()); app.use(connect.session()); app.use(connect.bodyParser()); app.use(connect.csrf()); app.use(function (req, res, next) { // 自己实现一个中间件 }); app.listen(3001);
上面这类中间件是匹配所有路由,其实中间件接受2个参数,第一个就是指定一个路由,如果指定,就会针对此路由下的请求做出过滤.如下:
app.use('/public', connect.static(__dirname + '/public')); app.use("/upload", connect.multipart({ uploadDir: path }));
指定静态服务器走 /public 目录, 上传文件走 /upload 目录,那么这2个中间件就不会在所有路由上过滤.