微信开发者模式开启需要服务器域名合法并且把接口配置好,这个接口是接通的关键,接通后微信后台的菜单设置功能,客服功能会失效,需要开发者自定义菜单和智能客服界面,并且接通后可以调用微信网页内部的定位分享等功能

前提条件

  • 先去看koa和mongoose那篇笔记
  • 安装xml2js中间件
  • 安装request中间件【flyio或者axios也行】
  • 创建一个wx文件夹单独使用

借用xml2js封装出方法

  1. // utils/xml.js
  2. const xml2js = require('xml2js')
  3. exports.xmlToJson = (str) => {
  4. return new Promise((resolve, reject) => {
  5. const parseString = xml2js.parseString
  6. parseString(str, (err, result) => {
  7. if (err) {
  8. reject(err)
  9. } else {
  10. resolve(result)
  11. }
  12. })
  13. })
  14. }
  15. exports.jsonToXml = (obj) => {
  16. const builder = new xml2js.Builder()
  17. return builder.buildObject(obj)
  18. }

自定义一个xml的中间件

如果数据是xml格式先处理成json格式

  1. // middleware/xmlParse.js
  2. const xml = require('../util/xml')
  3. module.exports = () => {
  4. return async (ctx, next) => {
  5. if (ctx.method == 'POST' && ctx.is('text/xml')) {
  6. let promise = new Promise(function (resolve, reject) {
  7. let buf = ''
  8. ctx.req.setEncoding('utf8')
  9. ctx.req.on('data', (chunk) => {
  10. buf += chunk
  11. })
  12. ctx.req.on('end', () => {
  13. xml.xmlToJson(buf)
  14. .then(resolve)
  15. .catch(reject)
  16. })
  17. })
  18. await promise.then((result) => {
  19. ctx.req.body = result
  20. })
  21. .catch((e) => {
  22. e.status = 400
  23. })
  24. await next()
  25. } else {
  26. await next()
  27. }
  28. }
  29. }

配置文件

  1. // config.js
  2. ...
  3. wx: {
  4. // 这几个都是微信给的
  5. appid: 'AppSecret',
  6. AppSecret:'AppSecret',
  7. token:'token',
  8. encodingAESKey: 'encodingAESKey',
  9. },
  10. ...

微信的路由

  1. // router/index.js
  2. const wxSignature = require('../wx/wxSignature')
  3. const wxHandle = require('../wx/wxHandle')
  4. router.get('/wxHandle', wxHandle.getHandle)
  5. router.post('/wxHandle', wxHandle.postHandle)

sha1加密

  1. // utils/encode.js
  2. const crypto = require('crypto')
  3. exports.sha1 = (str) => {
  4. const sha1 = crypto.createHash('sha1')
  5. sha1.update(str)
  6. return sha1.digest('hex')
  7. }

微信核心的构造函数

把几个值闭包在构造函数里,过期时间也是,等到token过期再请求一次

  1. // wx/index.js
  2. const config = require('../config')
  3. const request = require('request');
  4. function wxchat(config) {
  5. this.appid = config.appid;
  6. this.AppSecret = config.AppSecret;
  7. this.token = config.token;
  8. this.encodingAESKey = config.encodingAESKey;
  9. this.accessToken = "";
  10. this.accessTokenTime = "";
  11. this.jsapiTicket = "";
  12. this.jsapiTicketTime = "";
  13. }
  14. wxchat.prototype.getAccessToken = async function(){
  15. if(this.accessToken==""){
  16. await this.accessTokenRequest();
  17. }else{
  18. var now = new Date().getTime()
  19. if(now>Number(this.accessTokenTime)){
  20. // 过期了
  21. await this.accessTokenRequest();
  22. }
  23. }
  24. return this.accessToken
  25. }
  26. wxchat.prototype.accessTokenRequest = async function(){
  27. var url = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential';
  28. url += '&appid=' + this.appid;
  29. url += '&secret=' + this.AppSecret;
  30. return new Promise((resolve,reject) => {
  31. request(url,(error, response, body) => {
  32. if(response.statusCode == 200){
  33. var res = JSON.parse(body);
  34. if(res.access_token){
  35. console.log("accessToken成功:"+ res.access_token)
  36. this.accessToken = res.access_token;
  37. this.accessTokenTime = new Date().getTime() + Number(res.expires_in) - 200;
  38. }else{
  39. console.log("获取accessToken接口出错:"+res.errcode)
  40. this.accessToken = "";
  41. this.accessTokenTime = "";
  42. }
  43. }else{
  44. console.log("获取accessToken接口出错")
  45. this.accessToken = "";
  46. this.accessTokenTime = "";
  47. }
  48. resolve()
  49. })
  50. })
  51. }
  52. wxchat.prototype.init=async function () {
  53. await this.getAccessToken()
  54. }
  55. const wx = new wxchat(config.wx);
  56. wx.init()
  57. module.exports = wx;

入口文件

  1. // app.js
  2. const xmlParse = require('./src/middleware/xmlParse')
  3. // 这个js是自启动服务,不需要use,每次启动都会自动获取access_token
  4. const wx = require('./src/wx/index')
  5. app.use(xmlParse());

接通服务和智能客服

上面的所有代码都是为了这个js服务

  1. // wx/wxHandle.js
  2. const encode = require('../util/encode')
  3. const config = require('../config')
  4. const xml = require('../util/xml')
  5. //公众号接通服务
  6. exports.getHandle = async (ctx, next) => {
  7. const token = config.wx.token,
  8. signature = ctx.query.signature,
  9. timestamp = ctx.query.timestamp,
  10. nonce = ctx.query.nonce;
  11. // 字典排序
  12. const arr = [token, timestamp, nonce].sort()
  13. const result = encode.sha1(arr.join(''))
  14. if (result === signature) {
  15. ctx.body = ctx.query.echostr
  16. } else {
  17. ctx.body = { code: -1, msg: "你不是微信!"}
  18. }
  19. }
  20. //微信客服,回复
  21. exports.postHandle = (ctx, next) => {
  22. let msg,MsgType,result;
  23. msg = ctx.req.body ? ctx.req.body.xml : ''
  24. if (!msg) {
  25. ctx.body = 'error request.'
  26. return;
  27. }
  28. MsgType = msg.MsgType[0]
  29. if(MsgType=='text'){
  30. // 文字回复
  31. result = xml.jsonToXml({
  32. xml: {
  33. ToUserName: msg.FromUserName,
  34. FromUserName: msg.ToUserName,
  35. CreateTime: Date.now(),
  36. MsgType: msg.MsgType,
  37. Content: msg.Content
  38. }
  39. })
  40. }else if(MsgType=='event'){
  41. // 关注回复
  42. result = xml.jsonToXml({
  43. xml: {
  44. ToUserName: msg.FromUserName,
  45. FromUserName: msg.ToUserName,
  46. CreateTime: Date.now(),
  47. MsgType: 'text',
  48. Content: "感谢关注"
  49. }
  50. })
  51. }else{
  52. // 其他回复
  53. result = 'success'
  54. }
  55. ctx.res.setHeader('Content-Type', 'application/xml')
  56. ctx.res.end(result)
  57. }

上面的代码设置好后,去到外网域名启动服务,如果服务启动成功,去到微信服务器后台点击接通,会需要填接通请求地址,就是服务器域名【/xxx/wxHandle】,点击完成后,微信会向这个地址发出请求,是一个xml请求,请求到达我们刚开启的Koa服务器,被中间件解析成Json,然后通过config.js里的appId的加密计算后返回数据给微信,不出问题就接通了,接通成功后,去到公众号关注,就能收到刚才配置的【欢迎关注】,你再发文字上去,他会把你发的重新发回来,完结撒花

智能客服不能用代码去写,需要做个页面去配置到数据库,服务器要根据用户的请求查数据库回复,还有菜单的配置也是,菜单的配置是需要公众号认证的,每年300,我没搞,还有一个微信网页签名的接口,可以实现获取地址,分享,微信网页里的分享和获取地址怎么写,在Js笔记里有,这个接口怎么写,查看github,有帮助的给个星星谢谢!

微信用户登陆获取信息,查看下一篇

Koa微信公众号开发的更多相关文章

  1. nodejs 中koa框架下的微信公众号开发初始篇

    最近在搞微信公众号开发,后端采用的是nodejs下的koa框架,初识后端的菜鸟,自己搞难度太大了,网上找了很多文章,采用的中间件大都是express框架下的,不过好在爬了许多坑之后总算看见点曙光了,遂 ...

  2. 微信公众号开发(一)--验证服务器地址的Java实现

    现在主流上都用php写微信公众号后台,其实作为后端语言之一的java也可以实现. 这篇文章将对验证服务器地址这一步做出实现. 参考资料:1.慕课网-<初识java微信公众号开发>,2.微信 ...

  3. C#微信公众号开发系列教程三(消息体签名及加解密)

    http://www.cnblogs.com/zskbll/p/4139039.html C#微信公众号开发系列教程一(调试环境部署) C#微信公众号开发系列教程一(调试环境部署续:vs远程调试) C ...

  4. C#微信公众号开发系列教程二(新手接入指南)

    http://www.cnblogs.com/zskbll/p/4093954.html 此系列前面已经更新了两篇博文了,都是微信开发的前期准备工作,现在切入正题,本篇讲解新手接入的步骤与方法,大神可 ...

  5. 微信公众号开发系列教程一(调试环境部署续:vs远程调试)

    http://www.cnblogs.com/zskbll/p/4080328.html 目录 C#微信公众号开发系列教程一(调试环境部署) C#微信公众号开发系列教程一(调试环境部署续:vs远程调试 ...

  6. NET微信公众号开发-5.0微信支付(待测试)

    开发前准备. 1.0微信支付官方开发者文档 2.0官方demo下载 我们用c#所以选择.net版本 不过这个官方的demo根本跑步起来 3.0官方demo运行起来解决方案 4.0微信支付官方.net版 ...

  7. .NET开发者如何愉快的进行微信公众号开发

    (此文章同时发表在本人微信公众号"dotNET每日精华文章",欢迎右边二维码来关注.) 题记:这篇文章只是一个如何提高开发效率的简单指导和记录,不会涉及具体的微信公众号开发内容. ...

  8. 微信公众号开发之被逼学web服务端1-----使用SecureCRT连接Linux服务器

    做Android的进新公司后安排做微信公众号开发,这基本是后台和前端的活都要由小白的我来做,这两天基本成鸭子了,被填的满满的,却还是不够,博文仅作记录,希望能给后来的小白一点参考吧 今天做的是如何配置 ...

  9. 利用OpenShift托管Node.js Web服务进行微信公众号开发

    最近写了一个微信的翻译机器人.用户只要关注该公众号,发送英文的消息,就能收到中文翻译的回复.有兴趣的读者可以扫描下面的二维码关注该公众号,尝试发送英文单词试试看.(有时候第一次发送单词会收到“该公众号 ...

随机推荐

  1. 从零构建以太坊(Ethereum)智能合约到项目实战——第24章 IPFS + 区块链

    P93 .1-IPFS环境配置P94 .2-IPFS+P .IPNS+P .个人博客搭建 - 如何在IPFS新增一个文件P95 .3-IPFS+P .IPNS+P .个人博客搭建 - 通过ipfs创建 ...

  2. Java入门程序“hello,world!”

    1.程序开发步骤说明 开发环境已经搭建完毕,可以开发我们第一个Java程序了. Java程序开发三步骤:编写.编译.运行.(图片介绍)   2.编写Java程序 新建一个普通的记事本,给其命名为Hel ...

  3. 110、Java中String类之字符串文本拆分

    01.代码如下: package TIANPAN; /** * 此处为文档注释 * * @author 田攀 微信382477247 */ public class TestDemo { public ...

  4. 算法设计与分析 - AC 代码 - 第 6 弹(重复第 3 弹)

    PTA-算法设计与分析 - c++(g++) #include<bits/stdc++.h> using namespace std; long max3(long a,long b,lo ...

  5. JAVA培训—线程同步--卖票问题

    线程同步方法: (1).同步代码块,格式: synchronized (同步对象){ //同步代码 } (2).同步方法,格式: 在方法前加synchronized修饰 问题: 多个人同时买票. 1. ...

  6. runas的替代品CPAU使用

    runas替代软件CPAU 在windows系统下,想要实现某个程序不论何时都以指定的用户身份登录,因此找到了CPAU这个软件 cpau官方网站:https://www.joeware.net/fre ...

  7. 吴裕雄 Bootstrap 前端框架开发——Bootstrap 辅助类:元素浮动到右边

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  8. 吴裕雄 Bootstrap 前端框架开发——Bootstrap 辅助类:"text-warning" 类的文本样式

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  9. 利用Python进行多项式拟合

    多项式拟合的简单代码: import matplotlib.pyplot as plt import numpy as np x=[,,,,,,,] y=[,,,,,,,] a=np.polyfit( ...

  10. 怎样实现android 返回到上一个Activity并重新执行一次onCreate方法

    1.onCreate 方法只在activity一开始创建的时候执行.2.也就是在该activity销毁后才能再次执行,假如当前activity上再打开一个activity,并且原来的activity已 ...