nodejs实现公众号服务URL绑定验证,nodejs实现公众号关注并回发送一条消息,以及关注之后的聊天自动回复消息

首先关注公众号的时候,公众号会发送一条 post 请求到 nodejs 服务器,这条消息是 xml 数据类型,这里就用到 xml 解析,demo 里用的是 [email protected]
demo 用的 express 脚手架生成的【express 生成项目】
直接看 demo ,写的比较 low 大神请飘过~
创建的 demo 直接将代码复制粘贴到 routes/index.js 里边就行

var express = require('express');
var router = express.Router();

var url = require('url');
var qs = require('qs');
var cy = require('crypto');
var TOKEN = 'demo_reply';
var fxp = require('fast-xml-parser');

//这个是验证签名,公众号后台配置路由的时候用的,公众号配置服务器路由的时候会发送 get 请求到这个接口 接口进行 sha1 加密并验证就行了
router.get('/', function (req, res, next) {
    let query = url.parse(req.url).query;
    let params = qs.parse(query);

    if (!checkSignature(params, TOKEN)) {
        //如果签名不对,结束请求并返回
        res.end('signature fail');
    } else {
        res.end(params.echostr);
    }
});
function checkSignature(params, token) {
    let key = [token, params.timestamp, params.nonce].sort().join('');

    let sha1 = cy.createHash('sha1');

    sha1.update(key);
    
    //将加密后的字符串与signature进行对比,若成功,返回echostr
    return sha1.digest('hex') == params.signature;
}

//这是验证之后其他的事件都走的 post 同样的接口,只是接收方式和接收到的东西不同罢了,分开写没毛病 老铁们~
router.post('/', function (req, res, next) {
    let postdata = ''; //预定义一个变量用来接收 post 过来的 xml 字符串
    req.addListener("data", function (postchunk) {
        postdata += postchunk;
    });
    //获取到了 post 的 xml 数据
    req.addListener("end", function () {
        let str = checkMsg(postdata); //检查到底是什么类型的消息,分 event 和 其他类型 ,并根据消息类型返回不同的消息
        res.end(str);
    });
})

//将接收到的 xml 字符串传递过来并解析成 json 方便调用
function checkMsg(xmlStr) {
    let formatMsg = fxp.parse(xmlStr).xml;
    let resStr = ""; //预定义的返回值消息
    if (formatMsg.MsgType == "event") {
        resStr = eventMsg({ event: formatMsg.Event, formatMsg });
    } else {
        resStr = otherMsg({ MsgType: formatMsg.MsgType, formatMsg })

    }
    return resStr;
}

//event 事件类型处理函数
function eventMsg({ event, formatMsg }) {
    let resStr = '';
    switch (event) {
        case "subscribe": //关注公众号回复的第一条消息
            resStr = `
                ${formatMsg.FromUserName}]]>
                ${formatMsg.ToUserName}]]>
                ${new Date().getTime()}
                
                
            `;
            break;
        case "unsubscribe": //取消关注直接回复成功就OK了,也可以真如手册上说的,去数据库里面把用户相关信息删掉,不过不知道有没有人会干这事儿
            resStr = 'success';
            break;
        default:
            resStr = 'success';
    }
    return resStr;
}

//other 事件类型处理函数,比如在公众号页面直接输入文字给公众号发送消息,走的就是 other 类型
function otherMsg({ MsgType, formatMsg }) {
    let answer = "";
    switch (MsgType) {
        case "text": //这里可以使用正则做一个模糊查询来确定回复的消息到底是啥,暂时直接写死了
            if (formatMsg.Content == '你好') {
                answer = '我不好';
            } else if (formatMsg.Content == '你叫什么') {
                answer = '你脸这么大啊,还问我叫什么,你叫啥';
            } else {
                answer = '让你调戏我,滚蛋,哥是个纯爷们儿,只喜欢御姐萝莉';
            }
            break;
        default:
            answer = "不好意西,俺不认西~~~~~,攻城狮木给俺设置对应的回复";
    }
    resStr = `
            ${formatMsg.FromUserName}]]>
            ${formatMsg.ToUserName}]]>
            ${new Date().getTime()}
            
            ${answer}]]>
        `;
    return resStr;
}

module.exports = router;

公众号测试地址:
https://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login 【GO>>>】

nodejs实现公众号服务URL绑定验证,nodejs实现公众号关注并回发送一条消息,以及关注之后的聊天自动回复消息_第1张图片
这里的服务器 URL 用的内网穿透工具做的,将 127.0.0.1:80 映射到外网上,直接访问映射出去的域名就可以访问到接口了,方便本地调试,不用一遍遍的往服务器上部署代码了,调消息回复的时候不需要调用微信的sdk接口,所以JS安全域名和网页授权回调域名配不配之无所谓

没有用过内网穿透工具的小伙伴可以看这里 【GO>>>】 自家写的,漂不漂亮无所谓,重点是实用就行

你可能感兴趣的:(微信公众号,nodejs,nodejs,微信公众号)