Просмотр исходного кода

微信订阅 消息token 从五秒获取

DESKTOP-HN5QP3V\Administrator 2 месяцев назад
Родитель
Сommit
a270c8063a
1 измененных файлов с 127 добавлено и 1 удалено
  1. 127 1
      pkg/helper/wechat/wechatHelper.go

+ 127 - 1
pkg/helper/wechat/wechatHelper.go

@@ -2,13 +2,21 @@ package wechat
 
 import (
 	"context"
+	"crypto/md5"
 	"dsbqj-admin/pkg/cache"
 	"dsbqj-admin/pkg/logger"
 	"dsbqj-admin/pkg/util"
+	"encoding/hex"
+	"fmt"
 	"github.com/goccy/go-json"
 	"github.com/silenceper/wechat"
+	wechatCtx "github.com/silenceper/wechat/context"
 	"os"
+	"sort"
+	"strconv"
+	"strings"
 	"sync/atomic"
+	"time"
 
 	wechatCache "dsbqj-admin/pkg/cache/wechat"
 )
@@ -28,9 +36,125 @@ type WechatHelper struct {
 }
 
 const (
-	subscribeUrl = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token="
+	subscribeUrl   = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token="
+	accessTokenURL = "http://fx.wumiao666.com/cp/getaccesstoken"
 )
 
+type SignResult struct {
+	Param string
+	Line  string
+	Sign  string
+}
+
+func AppSign(params map[string]string, key string) SignResult {
+	var builder strings.Builder
+
+	// 1. 排序 key
+	keys := make([]string, 0, len(params))
+	for k := range params {
+		keys = append(keys, k)
+	}
+	sort.Strings(keys)
+	// 2. 拼接 key=value&
+	for _, k := range keys {
+		builder.WriteString(k)
+		builder.WriteString("=")
+		builder.WriteString(params[k])
+		builder.WriteString("&")
+	}
+
+	strForWX := builder.String()
+	str := strings.TrimSuffix(strForWX, "&")
+	line := str + key
+	sign := md5Hex(line)
+
+	return SignResult{
+		Param: str,
+		Line:  line,
+		Sign:  strings.ToLower(sign),
+	}
+}
+
+func md5Hex(s string) string {
+	sum := md5.Sum([]byte(s))
+	return hex.EncodeToString(sum[:])
+}
+
+type TokenData struct {
+	AccessToken   string `json:"accessToken"`
+	ExpiresSecond *int64 `json:"expiresSecond"`
+}
+
+type ResAccessToken struct {
+	Msg  string     `json:"msg"`
+	Code string     `json:"code"`
+	Data *TokenData `json:"data"`
+}
+
+type ResAccessToken2 struct {
+	Msg  string                 `json:"msg"`
+	Code string                 `json:"code"`
+	Data map[string]interface{} `json:"data"`
+}
+
+func GetAccessTokenFromServer(ctx *wechatCtx.Context) (resAccessToken ResAccessToken, err error) {
+	var params = map[string]string{}
+	params["platformId"] = os.Getenv("SDK_PLATFORMID")
+	params["appId"] = os.Getenv("SDK_APPID")
+	params["wxAppId"] = os.Getenv("WECHAT_APPID")
+	params["clearCache"] = "1"
+	params["requestTime"] = strconv.Itoa(int(util.GetNowSecond()))
+
+	res := AppSign(params, os.Getenv("SDK_APPKEY"))
+	url := fmt.Sprintf("%s?%s&sign=%s", accessTokenURL, res.Param, res.Sign)
+	var body []byte
+	body, err = util.HTTPGet(url)
+	if err != nil {
+		return
+	}
+	var temp1 map[string]interface{}
+	err = json.Unmarshal(body, &temp1)
+
+	var temp ResAccessToken2
+	err = json.Unmarshal(body, &temp)
+
+	err = json.Unmarshal(body, &resAccessToken)
+	if err != nil {
+		return
+	}
+	if resAccessToken.Code != "0" {
+		err = fmt.Errorf("get access_token error : errcode=%v , errormsg=%v", resAccessToken.Msg)
+		return
+	}
+
+	accessTokenCacheKey := fmt.Sprintf("access_token_%s", ctx.AppID)
+	var expires int64 = 600
+	if resAccessToken.Data.ExpiresSecond != nil {
+		expires = *resAccessToken.Data.ExpiresSecond
+	}
+	err = ctx.Cache.Set(accessTokenCacheKey, resAccessToken.Data.AccessToken, time.Duration(expires)*time.Second)
+	return
+}
+
+func MyAccessTokenFunc(ctx *wechatCtx.Context) (accessToken string, err error) {
+	accessTokenCacheKey := fmt.Sprintf("access_token_%s", ctx.AppID)
+	val := ctx.Cache.Get(accessTokenCacheKey)
+	if val != nil {
+		accessToken = val.(string)
+		return
+	}
+
+	//从微信服务器获取
+	var resAccessToken ResAccessToken
+	resAccessToken, err = GetAccessTokenFromServer(ctx)
+	if err != nil {
+		return
+	}
+
+	accessToken = resAccessToken.Data.AccessToken
+	return
+}
+
 func NewWechatHelper() *WechatHelper {
 	appID := os.Getenv("WECHAT_APPID")
 	appSecret := os.Getenv("WECHAT_SECRET")
@@ -40,6 +164,8 @@ func NewWechatHelper() *WechatHelper {
 		Cache:     wechatCache.NewAccessToken(cache.RedisReport),
 	})
 
+	wx.Context.SetGetAccessTokenFunc(MyAccessTokenFunc)
+
 	return &WechatHelper{
 		ctx:       context.Background(),
 		AppId:     appID,