Express搭建微信公众号后台

初衷

最近在弄个人公众号,也会发表一些自己的技术实现,同时为了要加粉,所以加了一个回复关键字获取demo的功能,可是每次设置关键字都要在微信公众平台设置,比较繁琐,于是想到直接使用后端控制,然而,受限于自身后端实力,要搭建一个完整的系统实在有些为难,所以才去了折中的办法。

面向对象

  1. 后端不熟悉,但有基本的编程思维;
  2. 稍微了解运营基础(可以参考我的另外一篇文章CentOS下从零开始部署自己的博客);
  3. 功能简单,没有复杂场景,比较适合个人。

开发过程

工具

必须

  • 一台服务器
  • 一个域名

软件推荐

  1. ssh工具:Mobaxterm(windows)、nuoshell(mac) ——都是免费的,linux 就直接用命令行好了
  2. nginx:其它工具也行,不用代理apache也可以
  3. pm2: 便于管理express应用

安装工具

  1. 安装node和nginx

往期文章已详细叙述,不在赘述CentOS下从零开始部署自己的博客

  • npm命令,本人皆使用的是淘宝镜像,用cnpm命令速度将快速很多
  1. 安装express脚手架和pm2
npm install express-generator -g
npm install pm2 -g
  • 推荐直接安装express脚手架,这样路由什么的都已经配好了,方便拿来即用,当然想自定义的,可以只安装express。
  1. 创建微信工程,并安装依赖
express -e wechat
cd wechat
npm install

申请微信参数

我们可以先在测试环境使用,在微信公众平台接口测试帐号申请页面,创建基本参数,并记住token参数。

代码编写

功能开发
  1. 该步骤需要安装crypto
npm install crypto

按照文档描述,将字段排序并加密后与签名比对,代码

const crypto = require('crypto');
router.get('/', function (req, res, next) {

	const signature = req.query.signature;
	const timestamp = req.query.timestamp;
	const nonce = req.query.nonce;
	const echostr = req.query.echostr;

	// 1. 将token、timestamp、nonce三个参数进行字典序排序
	let array = new Array('微信后台设置的token', timestamp, nonce);
	array.sort();
	let str = array.toString().replace(/,/g, "");

	// 2. 将排序后的字符串进行sha1加密
	let sha1Code = crypto.createHash("sha1");
	let code = sha1Code.update(str, 'utf-8').digest("hex");

	// 3. 与signature对比,如果匹配表示数据来自微信
	if (code === signature) {
		res.send(echostr)
	} else {
		res.send("error");
	}
});
  1. 回复功能

因为与微信的交互都是xml格式,所以我们还要安装一个xml解析库

npm install xml2js -s

解析接受的消息

const parseString = require('xml2js').parseString;
router.post("/", (req, res) => {
	var buffer = [];
	req.on('data', function (data) {
		buffer.push(data);
	});
	req.on('end', function () {
		var msgXml = Buffer.concat(buffer).toString('utf-8');
		parseString(msgXml, { explicitArray: false }, (err, result) => {
			if (err) {
				throw err;
			}
			result = result.xml;
			var toUser = result.ToUserName;
			var fromUser = result.FromUserName;
			if (result.MsgType === "text") {
                // 文本消息
			} else if (result.MsgType === "image") {
                // 图片消息
			} else if ('event' === result.MsgType) {
				if ('subscribe' === result.Event) {
                    // 被关注
				}
			}
		})
	})
});

回复文本消息

let str = `<xml><ToUserName><![CDATA[${fromUser}]]>
    </ToUserName><FromUserName><![CDATA[${toUser}]]></FromUserName>
    <CreateTime>${new Date().getTime()}</CreateTime>
    <MsgType><![CDATA[text]]></MsgType>
    <Content><![CDATA[你回复的文本内容]]></Content></xml>`;
res.send(str);
  1. 菜单功能
  • 菜单功能仅对认证的公众号开放,因本人公众号并未认证,所以在正式号上,没发实现,但测试是可以的。
        axios.post(`https://api.weixin.qq.com/cgi-bin/menu/create?access_token=获取到的access_token`, '菜单内容').then((response) => {
            if (response.data.errcode == 0) {
                // 成功
            }
        }).catch((error) => {
            // 失败
        });
不用数据库实现各功能的动态更新

画重点,这是最主要的地方

不用数据库,我们直接使用json配置文件,模拟数据库,该怎么做呢?

fs库给我们提供了一个api

/**
     * Watch for changes on `filename`. The callback `listener` will be called each time the file is accessed.
     * @param filename A path to a file or directory. If a URL is provided, it must use the `file:` protocol.
     * URL support is _experimental_.
     */
    export function watchFile(filename: PathLike, listener: (curr: Stats, prev: Stats) => void): void;

所以,我们在node启动时,注册一个监听,就可以实时更新数据了,都不需要重启服务器,是不是很简单。

代理

因为微信仅支持80/443端口,所以我们需要使用nginx代理一下,当然端口没有占用,你直接将node运行在这个端口上也没问题。
比如本人是开启的443端口,则代理配置如下

    server {
        listen 443 ssl;
        server_name 代理域名;
        ssl_certificate 签名文件;
        ssl_certificate_key 签名文件;

        ssl_session_cache    shared:SSL:1m;
        ssl_session_timeout  5m;

        ssl_ciphers  HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers  on;

        location / {
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header Host  $http_host;
            proxy_set_header X-Nginx-Proxy true;
            proxy_set_header Connection "";
            // 这里填写实际的地址和端口
            proxy_pass http://127.0.0.1:3000;
            proxy_redirect default;
            #root   html;
            #index  index.html index.htm;
        }
    }

运行

至此,所有的开发完成了,我们如果想测试效果,可以

npm start

如果我们发布,自然不会一直挂在终端上,所以我们用pm2命令

pm2 start bin/www

更多命令,可以自行搜索。

最后

所有代码,我都整理成了一个demo,并且将需要配置的地方已经提取出来了,只需要简单配置,即可运行。

如需获取完整demo,可以关注公众号[奶爸程序猿]回复"wxexpress"获取。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值