2023-02-22 09:57:10 星期三

目的

微信公众号后台管理,实现简单的文本接收与信息回复。

前提

  • 配置好微信服务器,并正常启动
  • 安装了 golang
  • 安装了 wechat

示例代码

演示一个接收用户向公众号发送的消息,如果消息类型是文本格式的话,就回复用户 “收到你的消息: ” 加上用户发的内容。如果用户发的是非文本消息,如图片,表情包等,则回复用户 “仅支持文本消息哦~”。

点击查看代码
package main

import (
	"fmt"
	"log"
	"net/http"

	wechat "github.com/silenceper/wechat/v2"
	"github.com/silenceper/wechat/v2/cache"
	offConfig "github.com/silenceper/wechat/v2/officialaccount/config"
	"github.com/silenceper/wechat/v2/officialaccount/message"
)

// 一个分词函数,输入字符串,输出

func serveWechat(rw http.ResponseWriter, req *http.Request) {
	wc := wechat.NewWechat()
	//这里本地内存保存access_token,也可选择redis,memcache或者自定cache
	memory := cache.NewMemory()
	cfg := &offConfig.Config{
		AppID:          "XXXXXXX",
		AppSecret:      "XXXXXXXXX",
		Token:          "tokenhere",
		EncodingAESKey: "QfG7Xd2utub6P1aIc276jFXiYvCPuTcrn6vv0bshe0T",
		Cache:          memory,
	}
	// 微信公众号后台接口校验
	officialAccount := wc.GetOfficialAccount(cfg)

	// 传入request和responseWriter
	server := officialAccount.GetServer(req, rw)
	//设置接收消息的处理方法
	server.SetMessageHandler(func(msg *message.MixMessage) *message.Reply {
		var info string
		log.Print(msg.MsgType)
		if msg.MsgType == "text" {
			//回复消息:演示回复用户发送的消息
			log.Print("获得用户消息:", msg.Content)
			fmt.Printf("%T\n", msg.Content)
			info = "收到你的消息: " + msg.Content
		} else {
			log.Print("仅支持文本消息哦~")
			info = "仅支持文本消息哦~"
		}
		text := message.NewText(info)
		return &message.Reply{MsgType: message.MsgTypeText, MsgData: text}
	})

	//处理消息接收以及回复
	err := server.Serve()
	if err != nil {
		log.Print(err)
		return
	}
	//发送回复的消息
	server.Send()
}

func main() {
	http.HandleFunc("/", serveWechat)
	log.Print("wechat server listener at", ":8001")
	err := http.ListenAndServe(":8001", nil)
	if err != nil {
		log.Print("start server error , err=%v", err)
	}
}

其中的配置项分别对应微信公众号管理页面内的配置项,如下图:
image

功能拓展

利用全面的免费 API 网站: https://api.aa1.cn/ ,拓展微信自动回复功能。 API 网站站长介绍如图,接口示例代码如下:
image

点击查看代码
// 2. 简易 API
func simple_API(url string) string {
	resp, err := http.Get("https://tenapi.cn/v2/yiyan")
	if err != nil {
		log.Fatal(err)
	}
	defer resp.Body.Close()

	bodyText, err := io.ReadAll(resp.Body)
	if err != nil {
		log.Fatal(err)
	}
	res := strings.Replace(string(bodyText), "<p>", "", -1)
	res = strings.Replace(res, "</p>", "", -1)
	return res
}

// 3. 热点接口
func hot_API(url string) string {
	log.Print("热搜接口")
	resp, err := http.Get(url)
	if err != nil {
		log.Fatal(err)
	}
	defer resp.Body.Close()

	bodyText, err := io.ReadAll(resp.Body)
	if err != nil {
		log.Fatal(err)
	}
	reg := regexp.MustCompile("\"name\": \"([^\"]+)\",")
	matchs := reg.FindAllStringSubmatch(string(bodyText), -1)
	var res string
	for i, m := range matchs {
		if i > 9 {
			continue
		}
		res = fmt.Sprintf("%s\n%d:%s", res, i+1, m[1])
	}
	return strings.TrimSpace(res)
}

func instruct() string {
	return "<<指令>>:\n" +
		"【一言】: 随机一句话\n" +
		"【笑话】:随机笑话\n" +
		"【抖音热搜】\n" +
		"【微博热搜】\n" +
		"【百度热搜】\n" +
		"【知乎热搜】\n" +
		"【今日头条热搜】\n" +
		"默认情况下非指令消息会进行中英文互译."
}

// 区分用户文本行为
func info_parse(s string) string {
	//回复消息:演示回复用户发送的消息
	log.Print("获得用户消息:", s)
	switch s {
	case "$$":
		return instruct()
	case "一言":
		return simple_API("https://tenapi.cn/v2/yiyan")
	case "笑话":
		return simple_API("https://v.api.aa1.cn/api/api-wenan-gaoxiao/index.php?aa1=text")
	case "抖音热搜":
		return hot_API("https://tenapi.cn/v2/douyinhot")
	case "微博热搜":
		return hot_API("https://tenapi.cn/v2/weibohot")
	case "百度热搜":
		return hot_API("https://tenapi.cn/v2/baiduhot")
	case "知乎热搜":
		return hot_API("https://tenapi.cn/v2/zhihuhot")
	case "今日头条热搜":
		return hot_API("https://tenapi.cn/v2/toutiaohot")
	default:
		return simple_API("https://sktie.cn/api/fanyi2.php?msg=" + s)
	}
}