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

前提条件

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

借用xml2js封装出方法

// utils/xml.js

const xml2js = require('xml2js')

exports.xmlToJson = (str) => {
return new Promise((resolve, reject) => {
const parseString = xml2js.parseString
parseString(str, (err, result) => {
if (err) {
reject(err)
} else {
resolve(result)
}
})
})
} exports.jsonToXml = (obj) => {
const builder = new xml2js.Builder()
return builder.buildObject(obj)
}

自定义一个xml的中间件

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

// middleware/xmlParse.js

const xml = require('../util/xml')

module.exports = () => {
return async (ctx, next) => {
if (ctx.method == 'POST' && ctx.is('text/xml')) {
let promise = new Promise(function (resolve, reject) {
let buf = ''
ctx.req.setEncoding('utf8')
ctx.req.on('data', (chunk) => {
buf += chunk
})
ctx.req.on('end', () => {
xml.xmlToJson(buf)
.then(resolve)
.catch(reject)
})
})
await promise.then((result) => {
ctx.req.body = result
})
.catch((e) => {
e.status = 400
})
await next()
} else {
await next()
}
}
}

配置文件

// config.js
...
wx: {
// 这几个都是微信给的
appid: 'AppSecret',
AppSecret:'AppSecret',
token:'token',
encodingAESKey: 'encodingAESKey',
},
...

微信的路由

// router/index.js

const wxSignature = require('../wx/wxSignature')
const wxHandle = require('../wx/wxHandle') router.get('/wxHandle', wxHandle.getHandle)
router.post('/wxHandle', wxHandle.postHandle)

sha1加密

// utils/encode.js

const crypto = require('crypto')

exports.sha1 = (str) => {
const sha1 = crypto.createHash('sha1')
sha1.update(str)
return sha1.digest('hex')
}

微信核心的构造函数

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

// wx/index.js

const config = require('../config')
const request = require('request'); function wxchat(config) {
this.appid = config.appid;
this.AppSecret = config.AppSecret;
this.token = config.token;
this.encodingAESKey = config.encodingAESKey;
this.accessToken = "";
this.accessTokenTime = "";
this.jsapiTicket = "";
this.jsapiTicketTime = "";
}
wxchat.prototype.getAccessToken = async function(){
if(this.accessToken==""){
await this.accessTokenRequest();
}else{
var now = new Date().getTime()
if(now>Number(this.accessTokenTime)){
// 过期了
await this.accessTokenRequest();
}
}
return this.accessToken
} wxchat.prototype.accessTokenRequest = async function(){
var url = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential';
url += '&appid=' + this.appid;
url += '&secret=' + this.AppSecret;
return new Promise((resolve,reject) => {
request(url,(error, response, body) => {
if(response.statusCode == 200){
var res = JSON.parse(body);
if(res.access_token){
console.log("accessToken成功:"+ res.access_token)
this.accessToken = res.access_token;
this.accessTokenTime = new Date().getTime() + Number(res.expires_in) - 200;
}else{
console.log("获取accessToken接口出错:"+res.errcode)
this.accessToken = "";
this.accessTokenTime = "";
}
}else{
console.log("获取accessToken接口出错")
this.accessToken = "";
this.accessTokenTime = "";
}
resolve()
})
})
} wxchat.prototype.init=async function () {
await this.getAccessToken()
} const wx = new wxchat(config.wx);
wx.init() module.exports = wx;

入口文件

// app.js

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

接通服务和智能客服

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

// wx/wxHandle.js

const encode = require('../util/encode')
const config = require('../config')
const xml = require('../util/xml') //公众号接通服务
exports.getHandle = async (ctx, next) => {
const token = config.wx.token,
signature = ctx.query.signature,
timestamp = ctx.query.timestamp,
nonce = ctx.query.nonce;
// 字典排序
const arr = [token, timestamp, nonce].sort()
const result = encode.sha1(arr.join('')) if (result === signature) {
ctx.body = ctx.query.echostr
} else {
ctx.body = { code: -1, msg: "你不是微信!"}
}
} //微信客服,回复
exports.postHandle = (ctx, next) => {
let msg,MsgType,result;
msg = ctx.req.body ? ctx.req.body.xml : '' if (!msg) {
ctx.body = 'error request.'
return;
}
MsgType = msg.MsgType[0]
if(MsgType=='text'){
// 文字回复
result = xml.jsonToXml({
xml: {
ToUserName: msg.FromUserName,
FromUserName: msg.ToUserName,
CreateTime: Date.now(),
MsgType: msg.MsgType,
Content: msg.Content
}
})
}else if(MsgType=='event'){
// 关注回复
result = xml.jsonToXml({
xml: {
ToUserName: msg.FromUserName,
FromUserName: msg.ToUserName,
CreateTime: Date.now(),
MsgType: 'text',
Content: "感谢关注"
}
})
}else{
// 其他回复
result = 'success'
}
ctx.res.setHeader('Content-Type', 'application/xml')
ctx.res.end(result)
}

上面的代码设置好后,去到外网域名启动服务,如果服务启动成功,去到微信服务器后台点击接通,会需要填接通请求地址,就是服务器域名【/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. python脚本调用iftop 统计业务应用流量

    因公司服务器上部署应用较多,在有大并发访问.业务逻辑有问题的情况下反复互相调用或者有异常流量访问的时候,需要对业务应用进行故障定位,所以利用python调用iftop命令来获取应用进程流量,结合zab ...

  2. Python 爬取 热词并进行分类数据分析-[云图制作+数据导入]

    日期:2020.01.28 博客期:136 星期二 [本博客的代码如若要使用,请在下方评论区留言,之后再用(就是跟我说一声)] 所有相关跳转: a.[简单准备] b.[云图制作+数据导入](本期博客) ...

  3. 时间复杂度Big O以及Python 内置函数的时间复杂度

    声明:本文部分内容摘自 原文 本文翻译自Python Wiki 本文基于GPL v2协议,转载请保留此协议. 本页面涵盖了Python中若干方法的时间复杂度(或者叫"大欧",&qu ...

  4. [转]Java监听器的原理与实现

    原文链接 监听器是一个专门用于对其他对象身上发生的事件或状态改变进行监听和相应处理的对象,当被监视的对象发生情况时,立即采取相应的行动.监听器其实就是一个实现特定接口的普通java程序,这个程序专门用 ...

  5. 重新学习CSS,认识CSS3中的属性

    之前学css,觉得会改个样式就不错了,直到现在,在做前端开发的时候,才发现自己的前端页面是有多垃圾,而且还不知道该怎么适应各个浏览器,总是很“词穷”,最近是想着好久没去慕课上面了,于是就报着逛一逛的心 ...

  6. 【转】CGI 和 FastCGI 协议的运行原理

    介绍 深入CGI协议 CGI的运行原理 CGI协议的缺陷 深入FastCGI协议 FastCGI协议运行原理 为什么是 FastCGI 而非 CGI 协议 CGI 与 FastCGI 架构 再看 Fa ...

  7. 5G时代,行业市场用户的公网与专网如何选择

    导读 今年,5G开启了真刀真枪的商用元年,尤其中国5G正式启动商用服务,5G规模商用进程再次大提速.除了面向消费者领域,5G更大的商业价值还是寄望于进入各个垂直行业,赋能千行百业数字化转型. 5G进入 ...

  8. 计算xx年xx月xx日是星期几

    代码: #include <iostream> #include <string> #include <vector> using namespace std; i ...

  9. R语言 table()函数

    table函数 用 table() 函数统计因子各水平的出现次数(称为频数或频率).也可以对一般的向量统计每个不同元素的出现次数.如 sex = c("女","女&quo ...

  10. <c:foreach>指定循环次数

    <c:forEach begin="0" end="4" var="i"> <c:set var="ans&qu ...