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包括下面几种不同的调用方法.
wechat(token, function (req, res, next) {});
我们上面用的就是这一种,把req,res 传入,next 指向下一个中间件队列需要处理的中间件
wechat(token, wechat.text(function (message, req, res, next) {
// 这里处理文本类消息
}).location(function (message, req, res, next) {
// 这里处理地理位置消息 (就是分享一个地理位置)
})//后面还可以链式处理其他类型的消息
);
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个中间件就不会在所有路由上过滤.