mirror of
https://github.com/silenceper/wechat.git
synced 2026-02-04 12:52:27 +08:00
* feat: enhance WorkAccessToken to include AgentID for improved token management - Added AgentID field to WorkAccessToken struct. - Updated NewWorkAccessToken function to accept AgentID as a parameter. - Modified access token cache key to incorporate AgentID, ensuring unique cache entries per agent. This change improves the handling of access tokens in a multi-agent environment. * refactor: enhance WorkAccessToken to improve cache key handling - Updated the AgentID field in WorkAccessToken struct to clarify its optional nature for distinguishing applications. - Modified the access token cache key construction to support both new and legacy formats based on the presence of AgentID. - Added comments for better understanding of the cache key logic and its compatibility with historical versions. This change improves the flexibility and clarity of access token management in multi-agent scenarios. * feat(work): add JsSdk method for JavaScript SDK integration - Introduced a new JsSdk method in the Work struct to facilitate the creation of a Js instance. - This addition enhances the functionality of the Work module by enabling JavaScript SDK support. This change improves the integration capabilities for developers working with the WeChat Work API. * fix gofmt
119 lines
3.0 KiB
Go
119 lines
3.0 KiB
Go
package credential
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"sync"
|
|
"time"
|
|
|
|
"github.com/silenceper/wechat/v2/cache"
|
|
"github.com/silenceper/wechat/v2/util"
|
|
)
|
|
|
|
// TicketType ticket类型
|
|
type TicketType int
|
|
|
|
const (
|
|
// TicketTypeCorpJs 企业jsapi ticket
|
|
TicketTypeCorpJs TicketType = iota
|
|
// TicketTypeAgentJs 应用jsapi ticket
|
|
TicketTypeAgentJs
|
|
)
|
|
|
|
// 企业微信相关的 ticket URL
|
|
const (
|
|
// 企业微信 jsapi ticket
|
|
getWorkJsTicketURL = "https://qyapi.weixin.qq.com/cgi-bin/get_jsapi_ticket?access_token=%s"
|
|
// 企业微信应用 jsapi ticket
|
|
getWorkAgentJsTicketURL = "https://qyapi.weixin.qq.com/cgi-bin/ticket/get?access_token=%s&type=agent_config"
|
|
)
|
|
|
|
// WorkJsTicket 企业微信js ticket获取
|
|
type WorkJsTicket struct {
|
|
corpID string
|
|
agentID string
|
|
cacheKeyPrefix string
|
|
cache cache.Cache
|
|
jsAPITicketLock *sync.Mutex
|
|
}
|
|
|
|
// NewWorkJsTicket new WorkJsTicket
|
|
func NewWorkJsTicket(corpID, agentID, cacheKeyPrefix string, cache cache.Cache) *WorkJsTicket {
|
|
return &WorkJsTicket{
|
|
corpID: corpID,
|
|
agentID: agentID,
|
|
cache: cache,
|
|
cacheKeyPrefix: cacheKeyPrefix,
|
|
jsAPITicketLock: new(sync.Mutex),
|
|
}
|
|
}
|
|
|
|
// GetTicket 根据类型获取相应的jsapi_ticket
|
|
func (js *WorkJsTicket) GetTicket(accessToken string, ticketType TicketType) (ticketStr string, err error) {
|
|
var cacheKey string
|
|
switch ticketType {
|
|
case TicketTypeCorpJs:
|
|
cacheKey = fmt.Sprintf("%s_corp_jsapi_ticket_%s", js.cacheKeyPrefix, js.corpID)
|
|
case TicketTypeAgentJs:
|
|
if js.agentID == "" {
|
|
err = fmt.Errorf("agentID is empty")
|
|
return
|
|
}
|
|
cacheKey = fmt.Sprintf("%s_agent_jsapi_ticket_%s_%s", js.cacheKeyPrefix, js.corpID, js.agentID)
|
|
default:
|
|
err = fmt.Errorf("unsupported ticket type: %v", ticketType)
|
|
return
|
|
}
|
|
|
|
if val := js.cache.Get(cacheKey); val != nil {
|
|
return val.(string), nil
|
|
}
|
|
|
|
js.jsAPITicketLock.Lock()
|
|
defer js.jsAPITicketLock.Unlock()
|
|
|
|
// 双检,防止重复从微信服务器获取
|
|
if val := js.cache.Get(cacheKey); val != nil {
|
|
return val.(string), nil
|
|
}
|
|
|
|
var ticket ResTicket
|
|
ticket, err = js.getTicketFromServer(accessToken, ticketType)
|
|
if err != nil {
|
|
return
|
|
}
|
|
expires := ticket.ExpiresIn - 1500
|
|
err = js.cache.Set(cacheKey, ticket.Ticket, time.Duration(expires)*time.Second)
|
|
ticketStr = ticket.Ticket
|
|
return
|
|
}
|
|
|
|
// getTicketFromServer 从服务器中获取ticket
|
|
func (js *WorkJsTicket) getTicketFromServer(accessToken string, ticketType TicketType) (ticket ResTicket, err error) {
|
|
var url string
|
|
switch ticketType {
|
|
case TicketTypeCorpJs:
|
|
url = fmt.Sprintf(getWorkJsTicketURL, accessToken)
|
|
case TicketTypeAgentJs:
|
|
url = fmt.Sprintf(getWorkAgentJsTicketURL, accessToken)
|
|
default:
|
|
err = fmt.Errorf("unsupported ticket type: %v", ticketType)
|
|
return
|
|
}
|
|
|
|
var response []byte
|
|
response, err = util.HTTPGet(url)
|
|
if err != nil {
|
|
return
|
|
}
|
|
err = json.Unmarshal(response, &ticket)
|
|
if err != nil {
|
|
return
|
|
}
|
|
if ticket.ErrCode != 0 {
|
|
err = fmt.Errorf("getTicket Error : errcode=%d , errmsg=%s", ticket.ErrCode, ticket.ErrMsg)
|
|
return
|
|
}
|
|
return
|
|
}
|