package feishu import ( "context" "encoding/json" "errors" "fmt" lark "github.com/larksuite/oapi-sdk-go/v3" larkcore "github.com/larksuite/oapi-sdk-go/v3/core" larkauth "github.com/larksuite/oapi-sdk-go/v3/service/auth/v3" "github.com/patrickmn/go-cache" "github.com/sirupsen/logrus" "net/http" "os" "time" ) var tokenCache *cache.Cache var tokenCacheKey = "feishuTenantAccessToken" var appId, appSecret string var LarkClient *lark.Client func InitFeiShuClient() { appId = os.Getenv("APP_ID") appSecret = os.Getenv("APP_SECRET") fmt.Println("init feishu client", appId, appSecret) LarkClient = lark.NewClient(appId, appSecret, // 默认配置为自建应用 // lark.WithMarketplaceApp(), // 可设置为商店应用 lark.WithLogLevel(larkcore.LogLevelDebug), lark.WithReqTimeout(3*time.Second), lark.WithEnableTokenCache(true), lark.WithHelpdeskCredential("id", "token"), lark.WithHttpClient(http.DefaultClient), ) tokenCache = cache.New(10*time.Minute, 10*time.Minute) } // 获取TenantAccessToken func GetTenantAccessToken() (string, error) { if token, ok := tokenCache.Get(tokenCacheKey); ok && token.(string) != "" { return token.(string), nil } // 创建请求对象 req := larkauth.NewInternalTenantAccessTokenReqBuilder(). Body(larkauth.NewInternalTenantAccessTokenReqBodyBuilder(). AppId(appId). AppSecret(appSecret). Build()). Build() // 发起请求 resp, err := LarkClient.Auth.V3.TenantAccessToken.Internal(context.Background(), req) // 处理错误 if err != nil { logrus.Warnf("GetTenantAccessToken error: %v", err) return "", err } // 服务端错误处理 if !resp.Success() { logrus.Warnf("GetTenantAccessToken error: %v", resp.Msg) return "", errors.New(resp.Msg) } type tokenResp struct { Code int `json:"code"` Expire int `json:"expire"` Msg string `json:"msg"` TenantAccessToken string `json:"tenant_access_token"` } respData := new(tokenResp) err = json.Unmarshal(resp.RawBody, respData) if err != nil { logrus.Warnf("GetTenantAccessToken error: %v", err) return "", err } tokenCache.Set(tokenCacheKey, respData.TenantAccessToken, time.Duration(respData.Expire)*time.Second) return respData.TenantAccessToken, nil }