调用任何其他接口的时候,都需要先获取access_token

并且不能频繁调用,需要有缓存机制

 

package wechat_kf_sdk

import (

"bytes"

"encoding/json"

"encoding/xml"

"errors"

"fmt"

"github.com/patrickmn/go-cache"

"io"

"io/ioutil"

"log"

"net/http"

"sync"

"time"

)

// 定义获取access_token的响应数据结构体

type AccessTokenResponse struct {

ErrCode int `json:"errcode"` // 错误码

ErrMsg string `json:"errmsg"` // 错误信息

AccessToken string `json:"access_token"` // access_token

ExpiresIn int `json:"expires_in"` // 过期时间

}

// 定义微信客服API的封装结构体

type KefuWework struct {

corpid string // 企业ID

corpsecret string // 企业密钥

Token string // 令牌

EncodingAESKey string // AES加密密钥

mutex sync.Mutex // 互斥锁,用于保护access_token的获取

}

var weworkCache = cache.New(5*time.Minute, 10*time.Minute) // 缓存,用于存储access_token

// 创建微信客服API的封装结构体实例

func NewKefuWework(corpid string, corpsecret, Token, EncodingAESKey string) *KefuWework {

return &KefuWework{

corpid: corpid,

corpsecret: corpsecret,

Token: Token,

EncodingAESKey: EncodingAESKey,

}

}

// 获取access_token的函数

func (s *KefuWework) GetAccessToken() (string, error) {

// 加锁,避免并发调用获取access_token接口

s.mutex.Lock()

defer s.mutex.Unlock()

// 判断access_token是否过期,如果未过期则直接返回

cacheKey := "wework_access_" + s.corpid

if accessToken, ok := weworkCache.Get(cacheKey); ok {

return accessToken.(string), nil

}

// 发送GET请求,构建请求URL

reqURL := fmt.Sprintf("%s?corpid=%s&corpsecret=%s", "https://qyapi.weixin.qq.com/cgi-bin/gettoken", s.corpid, s.corpsecret)

resp, err := http.Get(reqURL)

if err != nil {

return "", err

}

defer resp.Body.Close()

// 解析响应数据到AccessTokenResponse结构体

var tokenResp AccessTokenResponse

if err := json.NewDecoder(resp.Body).Decode(&tokenResp); err != nil {

return "", err

}

// 判断获取access_token是否成功

if tokenResp.ErrCode != 0 {

return "", fmt.Errorf("GetAccessToken failed: %s", tokenResp.ErrMsg)

}

weworkCache.Set(cacheKey, tokenResp.AccessToken, time.Duration(tokenResp.ExpiresIn-3600)*time.Second)

log.Printf("GetAccessToken kefuWework:%s\n", tokenResp.AccessToken)

// 返回access_token

return tokenResp.AccessToken, nil

}

测试用例

func TestGetAccessToken(t *testing.T) {

corpid := "xx"

corpsecret := "xxxxxxxxxxx"

// 创建微信客服API的封装结构体实例

kefuWework := NewKefuWework(corpid, corpsecret, "", "")

// 获取access_token

accessToken, err := kefuWework.GetAccessToken()

if err != nil {

fmt.Println(err)

return

}

fmt.Println(accessToken)

}

可以正确拿到access_token

 

查看原文