heritage-api/service/wechat-service.go

190 lines
4.5 KiB
Go
Raw Permalink Normal View History

2026-03-20 04:30:58 +00:00
package service
import (
2026-03-20 08:45:29 +00:00
"context"
2026-03-20 04:30:58 +00:00
"encoding/json"
"fmt"
"os"
"strconv"
2026-03-20 08:45:29 +00:00
"strings"
"time"
2026-03-20 04:30:58 +00:00
"github.com/silenceper/wechat/v2"
"github.com/silenceper/wechat/v2/cache"
"github.com/silenceper/wechat/v2/officialaccount"
"github.com/silenceper/wechat/v2/officialaccount/config"
2026-03-20 08:45:29 +00:00
"github.com/silenceper/wechat/v2/officialaccount/message"
2026-03-20 04:30:58 +00:00
"github.com/sirupsen/logrus"
2026-03-20 08:45:29 +00:00
"myschools.me/heritage/heritage-api/model"
"myschools.me/heritage/heritage-api/mysql"
"myschools.me/heritage/heritage-api/redis"
2026-03-20 04:30:58 +00:00
)
type ticketRequest struct {
ExpireSeconds int `json:"expire_seconds"`
ActionName string `json:"action_name"`
ActionInfo struct {
Scene struct {
SceneStr string `json:"scene_str"`
} `json:"scene"`
} `json:"action_info"`
}
type ticketResponse struct {
ErrCode int `json:"errcode"`
ErrMsg string `json:"errmsg"`
Ticket string `json:"ticket"`
ExpireSeconds int `json:"expire_seconds"`
Url string `json:"url"`
}
type WechatGetQrCodeResponse struct {
Ticket string `json:"ticket"`
ExpireSeconds string `json:"expire_seconds"`
Url string `json:"url"`
}
var (
mp *officialaccount.OfficialAccount
)
func init() {
wx := wechat.NewWechat()
2026-03-20 08:45:29 +00:00
wx.SetCache(cache.NewRedis(context.TODO(), &cache.RedisOpts{
2026-03-20 04:30:58 +00:00
Host: os.Getenv("REDIS_HOST"),
Password: os.Getenv("REDIS_PWD"),
Database: func() int {
db := os.Getenv("REDIS_DB")
n, err := strconv.Atoi(db)
if err != nil {
logrus.WithFields(logrus.Fields{
"func": "init",
}).Warnf("strconv.Atoi failed: %v", err)
n = 0
}
return n
}(),
MaxIdle: 3,
MaxActive: 300,
IdleTimeout: 600,
}))
mp = wx.GetOfficialAccount(&config.Config{
AppID: os.Getenv("APPID"),
AppSecret: os.Getenv("APPSECRET"),
Token: os.Getenv("TOKEN"),
EncodingAESKey: os.Getenv("EncodingAESKey"),
Cache: nil,
})
}
// 通过ID获取临时二维码
func WechatQrGet(reqid *string) (any, error) {
token, err := mp.GetAccessToken()
if err != nil {
logrus.WithFields(logrus.Fields{
"func": "WechatQrGet",
}).Errorf("mp.GetAccessToken: %v", err)
return nil, err
}
accurl := "https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=" + token
data := ticketRequest{
ExpireSeconds: 180,
ActionName: "QR_STR_SCENE",
ActionInfo: struct {
Scene struct {
SceneStr string `json:"scene_str"`
} `json:"scene"`
}{
Scene: struct {
SceneStr string `json:"scene_str"`
}{
SceneStr: *reqid,
},
},
}
marshal, err := json.Marshal(&data)
if err != nil {
return nil, err
}
body, err := httpDO(accurl, "post", nil, marshal)
if err != nil {
return nil, err
}
var result *ticketResponse
err = json.Unmarshal(body, &result)
if err != nil {
return nil, err
}
resp := &WechatGetQrCodeResponse{
Ticket: result.Ticket,
ExpireSeconds: fmt.Sprintf("%d", result.ExpireSeconds),
Url: result.Url,
}
return resp, nil
}
2026-03-20 08:45:29 +00:00
// 消息处理
func WechatEvent(msg *message.MixMessage) *message.Reply {
e := &model.WechatEvent{
FromUserName: string(msg.FromUserName),
ToUserName: string(msg.ToUserName),
EventKey: msg.EventKey,
EventTime: time.Unix(msg.CreateTime, 0),
EventType: string(msg.Event),
CreatedAt: time.Now(),
}
//打印请求参数
logrus.WithFields(logrus.Fields{
"func": "WechatEvent",
}).Warnf("EventMessage.EventKey: %s", msg.EventKey)
if err := mysql.WechatEventCreate(e); err != nil {
logrus.WithFields(logrus.Fields{
"func": "WechatEvent",
}).Warnf("mysql.WechatEventSet: %s,Event: %v", err.Error(), msg)
return nil
}
key := strings.Split(msg.EventKey, "_")
e.EventKey = key[len(key)-1]
switch msg.Event {
case message.EventScan:
if err := redis.WechatEventSet(&e.EventKey, e); err != nil {
logrus.WithFields(logrus.Fields{
"func": "WechatEvent",
}).Warnf("redis.WechatEventSet: %s", err.Error())
return nil
}
case message.EventSubscribe:
if err := redis.WechatEventSet(&e.EventKey, e); err != nil {
logrus.WithFields(logrus.Fields{
"func": "WechatEvent",
}).Warnf("redis.WechatEventSet: %s", err.Error())
return nil
}
// text := message.NewText("欢迎登录")
case message.EventUnsubscribe:
}
return nil
}
func WechatAuth(reqid *string) (*string, error) {
event, err := redis.WechatEventGet(reqid)
if err != nil {
if !strings.Contains(err.Error(), "redigo: nil returned") {
logrus.WithFields(logrus.Fields{
"func": "WechatAuth",
}).Warnf("redis.WechatEventGet: %v", err)
return nil, err
}
return nil, nil
}
return &event.FromUserName, nil
2026-03-20 04:30:58 +00:00
}