申请公众号
在构建项目之前,我需要去注册申请一个微信公众号,点击立即注册,选择服务号,只需要按照流程步骤来走即可,这里不详细解说了。
初始化项目
通过命令初始化项目
|
|
项目创建成功后在根目录下创建ecosystem.json,表示最终发布上线的发布脚本。
server目录下index.js为入口文件,定义host和port变量,通过start()
函数开启后台服务。创建nuxt实例new Nuxt(config)
,判断如果当前是dev开发环境下实时编译整个项目await nuxt.build()
,然后通过nuxt.render(ctx.req, ctx.res)
返回页面结果,最后通过app.listen()
启动服务器。
明白了index.js的用处,接着对代码做一些修改。
server/index.js
|
|
中间件
微信公众号是需要我们的服务器和微信服务器有基于消息的http请求交互,在项目中要有一层用于接管来自微信服务器推送消息,这些推送消息的功能统一放到中间件里,这里增加个userMiddleWare()
中间件,中间件不止有一个,这就需要对于多个中间件做统一处理。
为了减少重复添加代码使用map来对中间件进行管理,这里就要借助工具第三方库ramda对中间件做管理。首先声明一个数组MIDDLEWARES
来配置中间件。
|
|
通过R.map()
解析数组中的每一个值,然后交给可以生成绝对路径的函数i => ${r('./middlewares')}/${i}
,再把路径交给require,通过require加载这个模块,再对它传入i,让每个中间件都能拿到app对象同时进行初始化工作。
增加router
server目录下创建middleWares添加router.js文件
|
|
通过router.get()
拿到请求,/wx
表示对服务器配置的路径。接收微信服务器推送的get请求时可以获取到参数,接着对参数进行排序加密。
安装所需要的依赖包
|
|
再回顾一下入口文件server/index.js的执行流程:
在服务器里通过ramda函数式库进行管理中间件MIDDLEWARES
,通过new Server()
开启服务,启动服务后如果能接收到来自微信服务器的请求,router就能通过/wx
的路径规则监听到推送的请求,根据请求获取到参数,然后根据微信的加密规则对这些参数进行排序加密。根据加密的值是否是符合的,对微信服务器进行响应。
启动
在项目根目录下新建start.js,通过start.js间接的调用server/index.js启动整个后台服务。
start.js
|
|
配置启动命令,修改package.json
|
|
启动项目
|
|
同时打开配置好的服务器
|
|
修改url和token,点击提交。
服务器成功相应,说明访问成功!如图:
微信消息
用户在公众号的窗口上可能会录语音、上传图片、输入文案等等,这些交互叫做事件。这些事件触发数据的变化会上报给微信服务器,微信服务器收到这些事件后会按照它们的类型分为相应的标准的xml数据来通知我们,通知的方式就是在微信公众号后台配置的url,也就是已经接入的地址,所有用户交互的数据都会以这个地址来流到我们的服务器里。
如果是本地开发的话会通过Ngrok把本地某个端口的服务代理出去,如果是生产环境下的话,不需要代理工具,通过url的数据流到我们的后台服务器。数据进来之后会经过koa路由的中间件,然后根据get或post请求做响应的解析,如果是post请求的话就把整个数据包解析出来,根据解析出来的数据会进行回复策略的制定,这个回复策略可能会查数据库,可能会读本地的json文件。经过回复策略的处理后,整个回复的内容就已经有了,内容在回复给微信服务器之前需要去同步全局的票据,也就是access_token。
access_token
access_token就相当于是一把钥匙,只有给出这把钥匙微信服务器才会认同发请求的对方是合法的一方,如果access_token不合法或者过期或是不存在,那么相应的回复也不会生效。拿到access_token之后,把内容根据回复策略进行拼接生成一份标准的回复数据,这个回复数据需要套到xml模板里去,最后在把xml模板数据交给微信服务器,下发给触发事件的用户,用户就可以看到之前某个交互带来的结果,这样就形成完整闭环。
闭环里有几个关键点:
1、koa路由中间件来针对微信的请求做拦截和处理。
2、对get或post请求的区分。如果是get请求往往是第一次捕获认证的身份。如果是post请求就意味是一个事件通知或者是一个数据,需要把这个数据解析出来,这里就需要解析的中间件。
3、回复策略。回复策略会产生查询的异步操作,这里也需要中间件。
4、对access_token的处理,需要对它进行存储。
增加数据库中间件
把token存储到数据库里。数据库选择使用mongoose,安装mongoose。
|
|
拿到实例app,设置mongoose连接中断时、出错时、打开时做的处理,连接中断时重新连接数据库,出错时打印错误日志。成功连接数据库后对Scheam进行初始化数据,读取所有的models对它们进行过滤,只筛选出后缀为.js的文件。
server/middlewares/database.js
|
|
新建token.js存放access_token。声明TokenSchema传入token字段,保存每条数据之前先经过中间件的处理,判断是否是新增数据,记录时间。
server/database/schema/token.js
|
|
给TokenSchema增加静态方法,从model调用模型。通过mongoose.model()
拿到token数据模型,创建数据模型实例new Token()
,保存token
|
|
在server/index.js修改MIDDLEWARES
变量
|
|
修改后MIDDLEWARES里面的database就被关联到middlewares/database.js,从而加载schema。