搭建公众号自动回复功能

程序员爱炫技,写个公众号文章,都想拿点技术整整【自动回复】;程序员爱偷懒,什么都想做个【自动化】,最好所有事情系统都给做了,点点手指头就能达到目标。

今天的主角是如何搭建一个公众号自动回复功能。整个流程如下:

  1. 利用 hapi 开发 web 程序,对接微信公众号后台;
  2. 利用 LeanCloud SDK 将文章存储于 LeanCloud 后端;
  3. 接收用户发送的消息,获取关键词,查询文章,并回复给用户;
  4. 将 web 程序代码托管于 coding.net;
  5. 使用 LeanEngine 部署 hapi 程序。

1. hapi

A rich framework for building applications and services

hapi enables developers to focus on writing reusable application logic instead of spending time building infrastructure.

选择 hapi,主要被它的 logo 和读音(与 happy 同音)吸引,也主要因为自己爱折腾,老想着用不同的框架写写,重点是看看区别,你也可以看看 stackoverflow 上的帖子

https://stackoverflow.com/questions/30469767/how-do-express-and-hapi-compare-to-each-other

在用 hapi 写代码时,有种代码既文档的感觉,更重点的是 hapi 提供了一套 Plugins 方案,所有代码都可以以这种方式进行扩展和分离组织,可读性更高,如我将对接微信公众后台的 API 独立为 Plugin 形式:

server.register([{
  register: require('./api/Books'),
  options: {}
}, {
  register: require('./api/Articles'),
  options: {}
},{
  register: require('./api/Blogs'),
  options: {}
}, {
    register: require('./api/User'),
    options: {}
}, {
    register: require('./api/Comments'),
    options: {}
}], {routes: {prefix: '/api'}}, (err) => {
    if (err) {
        throw err;
    }
});

// wechat
server.register([{
  register: require('./wechat/weixin'),
  options: {}
}], (err) => {
    if (err) {
        throw err;
    }
});

这样就可以将微信公众号后台功能相关的代码独立到wechat/weixin.js中:

const wechat = require('./wechatserver');
const AV = require('leanengine');

const ModelBlog = require('../model/Blogs');
const config = {
  token: '***',
  appid: '***',
  encodingAESKey: '***'
};

exports.register = function (server, options, next) {
    server.route({
        method: ['POST', 'GET'],
        path: '/wechat',
        handler: function (request, reply) {
          wechat(config, request, reply, next, function (req, res, next) {
            // 微信输入信息都在req.weixin上
            var message = req.weixin;
            // 具体逻辑处理 和 自动回复
          });
        }
    });
    return next();
};

exports.register.attributes = {
    name: 'wechat-weixin'
};

具体如何配置开发 hapi 可以参考官网和 github
https://hapijs.com/
https://github.com/hapijs/hapi/

具体和微信后台路由配置就好说了,直接上图:


2. LeanCloud

LeanCloud 领先的 BaaS 提供商,为移动开发提供强有力的后端支持

包括云存储、数据分析、用户关系、消息推送、即时通信等现代应用基础模块,满足移动开发所有需求

https://leancloud.cn/

为什么选择 LeanCloud

  • 云存储。 主要方便自动回复,不需要存储大量数据,完全没必要购买一台【云服务器】或者【云数据库服务器】,而且 LeanCloud 提供 10 GB 免费空间,足够前期使用;
  • 数据。支持任意类型的 JSON 对象,以及对象之间的关联映射,同时提供完整的增删改查操作接口,方便开发;
  • 统计。提供开箱即用的移动统计,没准哪天粉丝数量增多了,也可以做一些统计分析,如分析分析哪个关键词是大家关注的,哪个话题是大家乐于传播分享的,等等。
  • 全平台 SDK 。搭建公众号后台功能,主要也是折腾折腾,这回用 Javascipt SDK 写写接口,没准哪天想换换口味,也可以重新试试用 PHP SDK 来重构复写。满足折腾需求。

JavaScript SDK

使用 SDK 主要三个作用:

  • 存储公众号文章基本信息,便于查询

根据微信公众号文档接口需要,主要存储 title, description, picurl, url 四要素;如果为了结合搜索功能,还需要存储这篇文章的关键词。

结合 LeanCloud SDK,存储代码就很简单了:

    var blog = new Blog();
    blog.set('title', request.payload.title);
    blog.set('url', request.payload.url);
    blog.set('desc', request.payload.desc);
    blog.set('picurl', request.payload.picurl);
    blog.set('tags', request.payload.tags);
    blog.save().then(function (blog) {
        // 成功保存之后,执行其他逻辑.
        console.log('成功保存:New object created with objectId: ' + blog.id);
        reply(blog);
    }, function (error) {
        // 失败之后执行其他逻辑
        console.log('Failed to create new object, with error message: ' + error.message);
        return reply(Boom.wrap(error, 'error'));
    });
  • 获取最新的一篇文章;
    当一个新粉丝首次进入公众号,或者发了一些暂时没处理的信息时,可以直接回复最新的一篇文章:
    const query = new AV.Query(Blog);
    query.descending('createdAt');
    
    query.first().then(function (data) {
      res.reply([
          {
              title: data.get('title'),
              description: data.get('desc'),
              picurl: data.get('picurl'),
              url: data.get('url')
          }
      ]);
    }, function (error) {
    });
  • 通过【关键词】查询相关文章。

搜索【关键词】,主要搜索 title, description, tags等:

    const titleQuery = new AV.Query(Blog)
    titleQuery.contains('title', words);
    
    const descQuery = new AV.Query(Blog)
    descQuery.contains('desc', words);
    
    const tagsQuery = new AV.Query(Blog)
    tagsQuery.contains('tags', words);
    
    const wordsQuery = AV.Query.or(titleQuery, descQuery, tagsQuery);
    
    wordsQuery.descending('createdAt');
    wordsQuery.limit(5);
    wordsQuery.find().then(function (results) {
        res(results);
    }, function (error) {
        res([]);
    });

最后可以将查询结果转成【图文信息】回复

ModelBlog.search(message.Content, results => {
    if (results.length === 0) {
        res.reply({
            content: message.Content,
            type: 'text'
        });
    } else {
        let data = [];
        results.forEach(function(v) {
            let wrap = {};

            wrap.title = v.get('title');
            wrap.description = v.get('desc');
            wrap.picurl = v.get('picurl');
            wrap.url = v.get('url');

            data.push(wrap);
        });
        res.reply(data);
    }
});

当然,根据情况需要,如果在找不到查询结果时,我们可以内建一些【智能聊天】、【生活信息查询】等等。

3. LeanEngine

云引擎(LeanEngine)是 LeanCloud 推出的服务端托管平台。提供了多种运行环境(Node.js, Python 等)来运行服务端程序。你只需要提供服务端的业务逻辑(网站或云函数等),而服务端的多实例负载均衡,不中断服务的平滑升级等都由云引擎提供支持。

当写了服务端代码后,总要有个地方托管。对于大网站或者项目来说,找一家如阿里云、腾讯云等云服务平台, 但对于个人只是想简单的搭建一个公众号管理——自动回复功能,终究有些大材小用了;LeanEngine 结合 LeanCloud 使用相得映彰,而且 LeanEngine 可以根据需要升级扩展。


部署

部署主要有两种途径:命令行部署和 Git 部署

  • 命令行部署

只要在项目的根目录运行:

lean deploy

使用命令行工具可以方便的部署、发布应用,查看应用状态,查看日志,甚至进行多应用部署。具体可参考网站文档:
https://leancloud.cn/docs/leanengine_cli.html#使用

  • Git 部署

代码都有一个版本控制,为了配合 LeanEngine 使用,我将代码托管到 https://coding.net/ 进行源码的版本管理,只要在 LeanCloud 后台一键部署即可,具体可参考网站文档:

https://leancloud.cn/docs/leanengine_webhosting_guide-node.html#Git_部署

总结

写代码太无聊了,偶尔折腾折腾挺好,如何将不同的技术和工具,以及第三方服务结合在一起,做一些事情也挺好的。

  • LeanCloud 负责后台数据存储;
  • LeanEngine 负责服务端托管平台,来运行服务端程序;
  • hapi 负责服务端 web 程序开发;
  • coding.net 负责源码的版本控制管理;

下一步要做:

  1. 搭建一个录入微信文章的后台;
  2. 如何解析和加解密微信的消息体;

coding01 期待您关注

qrcode
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342

推荐阅读更多精彩内容