微信后盾服务器开发

就要上班了,兵长关上手机,看到弹出的某微信聊天机器人广告便点了进去,于是有了如下故事...

最近兵长在看微信的时候突发奇想的去玩了一下某微信机器人,可能像智能语音助手一下和本人聊天

兵长就在想,这机器人是咋做的,咱们是做服务器开发的,咱用go语言疾速实现一下给本人玩玩,实现一个定制化的聊天机器人可好

胖sir听到兵长喃喃自语的不明所以,便走上前说,咋开始玩起聊天了,不来峡谷游了吗?

上次带你原本是想带你成为winer的,没想到,每一把都是loser,我打算最近收收手,管制一下情绪,找机器人安慰一下我手上的心灵

你是说微信聊天机器人吗?哪些不都是千篇一律的嘛

那么你能弄个定制化的嘛?把我情绪弄好了,我带你来大乱斗吧

~~(偷笑),小伙子,还好我留了一手,我先给你说说微信后盾服务器如何初步开发一个简略的你问我答性能吧,授人以渔,不如授人以鱼是不

开发一个微信后盾服务器作为被动回复机器人,大抵分为如下几步:

  • 开明公众号,注册微信公众号开发平台,这里能够是注册订阅号,具体的前面给你说
  • 配置权限,配置微信后盾开发者权限
  • 流程介绍
  • 接入微信后盾
  • 性能实现
  • 兵长乱斗带胖sir飞

开明公众号

注册微信公众号开发平台,这里能够是注册订阅号,依照提醒进行注册输出信息即可,置信你一看就会

注册地址:https://mp.weixin.qq.com/cgi-bin/registermidpage?action=index&lang=zh_CN&token=

我整顿了一个表格来介绍一下订阅号和服务器号的区别,你也能够先初步理解一下区别,前面能够缓缓推敲

订阅号服务号
用处次要目标 为大家流传征询;相似报纸,杂志,集体输入偏差企业或组织的交互,如银行,商场,餐厅等;自助服务的服务号,用于企业
群发次数一天能够发送一次;所有的订阅号推送音讯,会被对立收纳到订阅号栏目中一个月发送4条群发音讯
展现地位全副收录在 订阅号的 信息栏中展现在好友音讯列表之中;关注一个服务号,即相当与加了一个敌人
微信领取不可开明领取性能认证后 能够开明微信领取性能
自定义菜单绝对简略绝对高级,微信有接口,能够自行开发

配置权限

配置微信后盾开发者权限

  • 进入公众号治理页面,下拉右边侧,进入根本配置

  1. URL:填写本人的外网服务器URL,如果没有能够买一个云服务器,当初买云服务器还是很便宜的
  2. Token:自定义Token,用于制作签名,这个十分重要,须要窃密
  3. EncodingAESKey:随机生成即可
  4. 音讯加解密形式:为了演示不便,咱们这里应用明文模式
  • 微信公众号后盾接口权限

普通用户只有是接管音讯和主动回复音讯的权限

流程介绍

开发被动回复音讯流程介绍,简略来说,能够是这样的

性能实现必备知识点

  • http服务进行通信
  • Token机制
  • 微信后盾开发xml的数据序列化

http服务

做上述被动回复音讯的性能,此处仅须要后盾服务器实现get办法和post办法即可

  • get办法

    次要是用于,咱们在微信后盾设置token的时候,微信后盾会向咱们的服务器发送get申请,判断咱们服务是否有正确的数据

  • post办法

    次要是用于,粉丝在咱们的微信后盾发送音讯的时候,是以post的形式发送给咱们的后盾服务器的

Token机制

参数形容
signature微信加密签名,signature联合了开发者填写的token参数和申请中的timestamp参数、nonce参数。
timestamp工夫戳
nonce随机数
echostr随机字符串

开发者通过测验signature对申请进行校验(上面有校验形式)。若确认此次GET申请来自微信服务器,请原样返回echostr参数内容,则接入失效,成为开发者胜利,否则接入失败。加密/校验流程如下:

1)将token、timestamp、nonce三个参数进行字典序排序

2)将三个参数字符串拼接成一个字符串进行sha1加密

3)开发者取得加密后的字符串可与signature比照,标识该申请来源于微信

token算法流程图

验证办法(get)

  • 1.服务器端获取token、nonce、timestamp组成列表
  • 2.列表排成字典序
  • 3.排序后的元素进行摘要
  • 4.摘要比对signature
  • 5.响应echostr

参考微信后盾开发文档连贯:https://developers.weixin.qq.com/doc/offiaccount/Getting_Started/Getting_Started_Guide.html

xml数据解析

兵长,不晓得你有没有用过xml来做数据的序列化,此处你必定会问,为什么用xml,而不必json,不必protobuf

来我给你简略介绍一下xml:

XML是可扩大标记语言,其中标记指的是计算机中所能了解的信息符号,通过标记计算机之间能够解决蕴含各种信息的资源,咱们能够通过通用的标记语言来进行标记

用人话来说就是,xml是数据序列化的其中一种形式,微信定下来应用该形式来对数据进行序列化,咱们须要对此进行开发,因而也须要遵循微信的规定

例如 微信后盾的 text音讯类型 申请 xml格局如下

文本音讯,微信公众平台申请微信后盾服务器会带的字段有:FromUserNameToUserNameCreateTime,MsgTypeContentMsgId

咱们开发的微信后盾服务器,须要依照如下数据格式做回复:xml 带上如下字段ToUserNameFromUserNameCreateTime,MsgTypeContent

兵长,再给你回顾一下,实现微信后盾服务器被动回复音讯的服务,须要用到上述说到的3点,http服务、token机制、xml解析,记住咯,我要开始撸代码了

具体实现

main.go

  • 启动http服务器,开始监听80端口
package mainimport (   "fmt"   "github.com/wonderivan/logger"   "net/http"   "time")const (   port     = 80 //后盾服务器端口号80,本人的公网服务器 须要设置防火墙,关上80端口   token    = "XXXXXXX")// 须要本人批改token,以适应本人公众号的tokenfunc main() {   logger.SetLogger("./log.json")   logger.Info(" ------------ start  main ------------")   server := http.Server{      Addr:           fmt.Sprintf(":%d", port), // 设置监听地址, ip:port      Handler:        &httpHandler{},           // 具体应用哪个handler来解决      ReadTimeout:    5 * time.Second,          // 读写超时 微信给进去 5秒      WriteTimeout:   5 * time.Second,      MaxHeaderBytes: 0,   }   logger.Info(fmt.Sprintf("Listen: %d", port))   logger.Fatal(server.ListenAndServe())}

route.go

  • 路由性能 , 具体实现get 和post办法
  • 定义Handler 以及 ServeHTTP 接口的实现
package mainimport (   "fmt"   "github.com/wonderivan/logger"   "io"   "net/http"   "regexp"   "time"   "wechat/wx")type WebController struct {   Function func(http.ResponseWriter, *http.Request)   Method   string   Pattern  string}var mux []WebController // 本人定义的路由// ^ 匹配输出字符串的开始地位func init() {   mux = append(mux, WebController{post, "POST", "^/"})   mux = append(mux, WebController{get, "GET", "^/"})}type httpHandler struct{} //httpHandler 本人实现了 ServeHTTP 接口,能够通过源码看到,创立httpHandler 对象的时候,理论源码逻辑是会调用ServeHTTP进行解决func (*httpHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {   t := time.Now()   for _, webController := range mux { // 遍历路由      // 匹配申请的   r.URL.Path  -> webController.Pattern      if m, _ := regexp.MatchString(webController.Pattern, r.URL.Path); m { // 匹配URL         logger.Info("webController.Pattern  == ", webController.Pattern)         logger.Info("r.URL.Path  == ", r.URL.Path)         if r.Method == webController.Method { // 匹配办法            logger.Info("webController.Method  == ", webController.Method)            webController.Function(w, r) // 调用对应的处理函数            d := time.Now().Sub(t)            l := fmt.Sprintf("[ACCESS] | % -10s | % -40s | % -16s", r.Method, r.URL.Path, d.String())            logger.Info(l)            return         }      }   }   d := time.Now().Sub(t)   l := fmt.Sprintf("[ACCESS] | % -10s | % -40s | % -16s", r.Method, r.URL.Path, d.String())   logger.Info(l)   io.WriteString(w, "")   return}// 解决token的认证func get(w http.ResponseWriter, r *http.Request) {   client, err := wx.NewClient(r, w, token)   if err != nil {      logger.Info(err)      w.WriteHeader(403) // 校验失败      return   }   if len(client.Query.Echostr) > 0 {      logger.Info("Echostr == ", client.Query.Echostr)      w.Write([]byte(client.Query.Echostr)) // 校验胜利返回的是Echostr      return   }   w.WriteHeader(403)   return}// 微信平台过去音讯, 解决 ,而后返回微信平台func post(w http.ResponseWriter, r *http.Request) {   client, err := wx.NewClient(r, w, token)   if err != nil {      logger.Info(err)      w.WriteHeader(403)      return   }   // 到这一步签名曾经验证通过了   client.Run()   return}

具体代码实现还有1个定义构造文件和外围实现文件:

  • structs.go

    xml序列化音讯对应的构造体的定义,蕴含根本音讯字段,FromUserNameToUserNameMsgTypeCreateTime,以及文本音讯,图片音讯,录音音讯,音乐音讯,地理位置音讯,视频音讯等须要哪一些字段,都能够参考微信后盾给出的规定

  • wx.go

    token + 随机数 + 工夫戳 排成字典序,并应用sha1加密后生成 signature

    NewClient的具体实现

    文本音讯,图片音讯等的音讯解决以及被动回复性能

上述2个外围文件若是感兴趣,本人有想法并且冀望本人实现的小伙伴,能够增加我的微信,能够给大家共享一下

当然,微信后盾开发波及的性能还很多,明天给大家分享到的还只是冰山一角,沿途的风光还是须要大家一步一个脚印去感触,能够在微信的开发文档中纵情实战,如下图,感兴趣的能够多多交换。

技术是凋谢的,咱们共享技术,心态也应是凋谢的,咱们拥抱变动,你违心一直摸索后退,你必将播种你冀望的货色。

以上是本期全部内容,保持原创,实际本人的想法,咱们下期见

作者:小魔童哪吒