侧边栏壁纸
博主头像
搭建网站的历程博主等级

生命不息,折腾不止

  • 累计撰写 36 篇文章
  • 累计创建 4 个标签
  • 累计收到 0 条评论

目 录CONTENT

文章目录

golang对接微信公众号案例代码

甘超良
2023-12-16 / 0 评论 / 0 点赞 / 16 阅读 / 3953 字

main.go

package main

import (
    "crypto/sha1"
    "encoding/xml"
    "fmt"
    "io/ioutil"
    "net/http"
    "sort"
    "strings"
)

// 配置微信公众号相关信息
const (
    Token     = "your_token"         // 微信公众号Token
    AppID     = "your_app_id"        // 微信公众号AppID
    AppSecret = "your_app_secret"    // 微信公众号AppSecret
    EncodingAESKey = "your_aes_key"  // 消息加解密密钥,如果不需要消息加解密,可以不填写
)

// 微信公众号接口验证
func wechatAuth(w http.ResponseWriter, r *http.Request) {
    // 获取请求参数
    signature := r.FormValue("signature")
    timestamp := r.FormValue("timestamp")
    nonce := r.FormValue("nonce")
    echostr := r.FormValue("echostr")
  
    // 将token、timestamp、nonce三个参数进行字典序排序
    strs := []string{Token, timestamp, nonce}
    sort.Strings(strs)
  
    // 将三个参数拼接成一个字符串进行sha1加密
    str := strings.Join(strs, "")
    sha1 := sha1.Sum([]byte(str))
    encryptedStr := fmt.Sprintf("%x", sha1)
  
    // 将加密后的字符串与signature进行对比,如果相等则验证通过
    if encryptedStr == signature {
        fmt.Fprintf(w, echostr)
    } else {
        fmt.Fprintf(w, "auth failed")
    }
}

// 微信公众号消息处理
func wechatMessage(w http.ResponseWriter, r *http.Request) {
    // 读取请求Body
    body, _ := ioutil.ReadAll(r.Body)
  
    // 如果设置了消息加解密,则需要进行解密操作
    // 解密代码...
  
    // 解析XML消息
    var data map[string]string
    xml.Unmarshal(body, &data)
  
    // 根据消息类型进行相应的处理
    switch data["MsgType"] {
    case "text":
        replyTextMessage(w, data, "您发送了一条文本消息")
    case "image":
        replyTextMessage(w, data, "您发送了一条图片消息")
    case "voice":
        replyTextMessage(w, data, "您发送了一条语音消息")
    case "video":
        replyTextMessage(w, data, "您发送了一条视频消息")
    case "location":
        replyTextMessage(w, data, "您发送了一条位置消息")
    case "link":
        replyTextMessage(w, data, "您发送了一条链接消息")
    case "event":
        switch data["Event"] {
        case "subscribe":
            replyTextMessage(w, data, "感谢您的关注")
        case "unsubscribe":
            // 用户取消关注,可以在此处进行相应的业务处理
        case "CLICK":
            // 用户点击自定义菜单事件,可以在此处进行相应的业务处理
        }
    }
}

// 回复文本消息
func replyTextMessage(w http.ResponseWriter, data map[string]string, content string) {
    // 构造响应消息
    response := &struct {
        XMLName xml.Name `xml:"xml"`
        ToUserName string `xml:"ToUserName"`
        FromUserName string `xml:"FromUserName"`
        CreateTime string `xml:"CreateTime"`
        MsgType string `xml:"MsgType"`
        Content string `xml:"Content"`
    }{
        ToUserName:   data["FromUserName"],
        FromUserName: data["ToUserName"],
        CreateTime:   data["CreateTime"],
        MsgType:      "text",
        Content:      content,
    }
  
    // 将响应消息进行XML编码,并输出到响应Body中
    w.Header().Set("Content-Type", "application/xml")
    xml.NewEncoder(w).Encode(response)
}

func main() {
    http.HandleFunc("/", wechatAuth)
    http.HandleFunc("/message", wechatMessage)
    http.ListenAndServe(":80", nil)
}
0

评论区