一看便会微信后台服务器开发 |Go主题月

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

微信后台服务器开发

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

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

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

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

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

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

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

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

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

  • 开通公众号,注册微信公众号开发平台,这里可以是注册订阅号,详细的后面给你说
  • 配置权限,配置微信后台开发者权限
  • 流程介绍
  • 接入微信后台
  • 功能实现
  • 兵长乱斗带胖sir飞

开通公众号

注册微信公众号开发平台,这里可以是注册订阅号,按照提示进行注册输入信息即可,相信你一看就会

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

image.png

我整理了一个表格来介绍一下订阅号和服务器号的区别,你也可以先初步了解一下区别,后面可以慢慢琢磨

订阅号 服务号
用途 主要目的 为大家传播咨询;类似报纸,杂志,个人输出 偏向企业或组织的交互,如银行,商场,餐厅等;自助服务的服务号,用于企业
群发次数 一天可以发送一次;所有的订阅号推送消息,会被统一收纳到订阅号栏目中 一个月发送4条群发消息
展示位置 全部收录在 订阅号的 信息栏中 展示在好友消息列表之中;关注一个服务号,即相当与加了一个朋友
微信支付 不可开通支付功能 认证后 可以开通微信支付功能
自定义菜单 相对简单 相对高级,微信有接口,可以自行开发

配置权限

配置微信后台开发者权限

  • 进入公众号管理页面,下拉左边侧,进入基本配置

image.png

image.png

  1. URL:填写自己的外网服务器URL,如果没有可以买一个云服务器,现在买云服务器还是很便宜的
  2. Token:自定义Token,用于制作签名,这个非常重要,需要保密
  3. EncodingAESKey:随机生成即可
  4. 消息加解密方式:为了演示方便,我们这里使用明文模式
  • 微信公众号后台接口权限

普通用户只要是接收消息和自动回复消息的权限

image.png

流程介绍

开发被动回复消息流程介绍,简单来说,可以是这样的

image.png

功能实现必备知识点

  • 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算法流程图

image.png

验证方法(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格式如下

image.png

文本消息,微信公众平台请求微信后台服务器会带的字段有:FromUserNameToUserNameCreateTime,MsgTypeContentMsgId

我们开发的微信后台服务器,需要按照如下数据格式做回复:xml 带上如下字段ToUserNameFromUserNameCreateTime,MsgTypeContent

image.png

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

具体实现

main.go

  • 启动http服务器,开始监听80端口
package main
import (
   "fmt"
   "github.com/wonderivan/logger"
   "net/http"
   "time"
)
const (
   port     = 80 //后台服务器端口号80,自己的公网服务器 需要设置防火墙,打开80端口
   token    = "XXXXXXX"
)
// 需要自己修改token,以适应自己公众号的token
func 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 main
import (
   "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序列化消息对应的结构体的定义,包含基本消息字段,FromUserName,ToUserName,MsgType,CreateTime,以及文本消息,图片消息,录音消息,音乐消息,地理位置消息,视频消息等需要哪一些字段,都可以参考微信后台给出的规则
  • wx.go
    token + 随机数 + 时间戳  排成字典序,并使用sha1加密后生成 signature
    NewClient的具体实现
    文本消息,图片消息等的消息处理以及被动回复功能

上述2个核心文件若是感兴趣,自己有想法并且期望自己实现的小伙伴,可以添加我的微信,可以给大家共享一下

当然,微信后台开发涉及的功能还很多,今天给大家分享到的还只是冰山一角,沿途的风景还是需要大家一步一个脚印去感受,可以在微信的开发文档中尽情实战,如下图,感兴趣的可以多多交流。

image.png

技术是开放的,我们共享技术,心态也应是开放的,我们拥抱变化,你愿意不断摸索前进,你必将收获你期望的东西。

以上是本期全部内容,坚持原创,实践自己的想法,我们下期见

欢迎点赞,关注,收藏

朋友们,你的支持和鼓励,是我坚持分享,提高质量的动力

image.png

好了,本次就到这里

技术是开放的,我们的心态,更应是开放的。拥抱变化,向阳而生,努力向前行。

我是阿兵云原生,欢迎点赞关注收藏,下次见~

相关文章
|
5月前
|
算法 Java Go
【GoGin】(1)上手Go Gin 基于Go语言开发的Web框架,本文介绍了各种路由的配置信息;包含各场景下请求参数的基本传入接收
gin 框架中采用的路优酷是基于httprouter做的是一个高性能的 HTTP 请求路由器,适用于 Go 语言。它的设计目标是提供高效的路由匹配和低内存占用,特别适合需要高性能和简单路由的应用场景。
505 5
|
7月前
|
数据采集 数据挖掘 测试技术
Go与Python爬虫实战对比:从开发效率到性能瓶颈的深度解析
本文对比了Python与Go在爬虫开发中的特点。Python凭借Scrapy等框架在开发效率和易用性上占优,适合快速开发与中小型项目;而Go凭借高并发和高性能优势,适用于大规模、长期运行的爬虫服务。文章通过代码示例和性能测试,分析了两者在并发能力、错误处理、部署维护等方面的差异,并探讨了未来融合发展的趋势。
713 0
|
5月前
|
JavaScript 前端开发 Java
【GoWails】Go做桌面应用开发?本篇文章带你上手Wails框架!一步步带你玩明白前后端双端的数据绑定!
wails是一个可以让你使用Go和Web技术编写桌面应用的项目 可以将它看作Go的快并且轻量级的Electron替代品。可以使用Go的功能,并结合现代化UI完成桌面应用程序的开发
1093 5
|
6月前
|
监控 前端开发 数据可视化
Github 12.3kstar, 3分钟起步做中后台?Go+Vue 脚手架,把权限、代码生成、RBAC 都封装好了
Go-admin 是基于 Gin + Vue 的中后台脚手架,集成 Casbin RBAC 权限、JWT 鉴权、GORM 数据库操作与 Swagger 文档,内置用户、角色、菜单等管理模块。提供代码生成器与表单构建器,支持多租户与多前端框架(Element UI/Arco/Ant Design),3 分钟快速搭建企业级后台,助力高效交付。
539 4
|
9月前
|
JSON 中间件 Go
Go 网络编程:HTTP服务与客户端开发
Go 语言的 `net/http` 包功能强大,可快速构建高并发 HTTP 服务。本文从创建简单 HTTP 服务入手,逐步讲解请求与响应对象、URL 参数处理、自定义路由、JSON 接口、静态文件服务、中间件编写及 HTTPS 配置等内容。通过示例代码展示如何使用 `http.HandleFunc`、`http.ServeMux`、`http.Client` 等工具实现常见功能,帮助开发者掌握构建高效 Web 应用的核心技能。
467 61
|
8月前
|
人工智能 负载均衡 监控
使用 Go 和 Gin 实现高可用负载均衡代理服务器
本文基于Go语言和Gin框架,实现了一个企业级负载均衡代理服务器,支持动态路由、健康检查、会话保持等功能。具备高可用性与高性能,单节点支持100k+ QPS,延迟达亚毫秒级,并提供完整的压力测试方案与优化建议。
249 7
|
9月前
|
开发框架 安全 前端开发
Go Web开发框架实践:模板渲染与静态资源服务
Gin 是一个功能强大的 Go Web 框架,不仅适用于构建 API 服务,还支持 HTML 模板渲染和静态资源托管。它可以帮助开发者快速搭建中小型网站,并提供灵活的模板语法、自定义函数、静态文件映射等功能,同时兼容 Go 的 html/template 引擎,具备高效且安全的页面渲染能力。
|
8月前
|
JSON 前端开发 Go
Go语言实战:创建一个简单的 HTTP 服务器
本篇是《Go语言101实战》系列之一,讲解如何使用Go构建基础HTTP服务器。涵盖Go语言并发优势、HTTP服务搭建、路由处理、日志记录及测试方法,助你掌握高性能Web服务开发核心技能。
|
8月前
|
Go
如何在Go语言的HTTP请求中设置使用代理服务器
当使用特定的代理时,在某些情况下可能需要认证信息,认证信息可以在代理URL中提供,格式通常是:
561 0
|
10月前
|
人工智能 缓存 安全
Go开发遇见的一次Data Race
本文通过一段 Go 语言代码示例,分析了并发编程中的数据竞争(Data Race)问题。代码实现了一个带缓存的内存存储系统,包含 `LRUCache` 和 `MemoryCache` 两个核心组件。尽管在 `MemoryCache` 的 `Set` 方法中加了锁保护,但由于直接调用 `LRUCache` 的 `GetLength` 方法时未加锁,导致底层数据结构在多 goroutine 环境下被同时读写,从而触发 Data Race。文章详细解析了问题根源,并提出了解决方案:为 `LRUCache` 的 `Add` 方法添加锁保护,确保并发安全。
127 1

热门文章

最新文章