feishu.go 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. package feishu
  2. import (
  3. "context"
  4. "encoding/json"
  5. "errors"
  6. "fmt"
  7. lark "github.com/larksuite/oapi-sdk-go/v3"
  8. larkcore "github.com/larksuite/oapi-sdk-go/v3/core"
  9. larkauth "github.com/larksuite/oapi-sdk-go/v3/service/auth/v3"
  10. "github.com/patrickmn/go-cache"
  11. "github.com/sirupsen/logrus"
  12. "net/http"
  13. "os"
  14. "time"
  15. )
  16. var tokenCache *cache.Cache
  17. var tokenCacheKey = "feishuTenantAccessToken"
  18. var appId, appSecret string
  19. var LarkClient *lark.Client
  20. func InitFeiShuClient() {
  21. appId = os.Getenv("APP_ID")
  22. appSecret = os.Getenv("APP_SECRET")
  23. fmt.Println("init feishu client", appId, appSecret)
  24. LarkClient = lark.NewClient(appId, appSecret, // 默认配置为自建应用
  25. // lark.WithMarketplaceApp(), // 可设置为商店应用
  26. lark.WithLogLevel(larkcore.LogLevelDebug),
  27. lark.WithReqTimeout(3*time.Second),
  28. lark.WithEnableTokenCache(true),
  29. lark.WithHelpdeskCredential("id", "token"),
  30. lark.WithHttpClient(http.DefaultClient),
  31. )
  32. tokenCache = cache.New(10*time.Minute, 10*time.Minute)
  33. }
  34. // 获取TenantAccessToken
  35. func GetTenantAccessToken() (string, error) {
  36. if token, ok := tokenCache.Get(tokenCacheKey); ok && token.(string) != "" {
  37. return token.(string), nil
  38. }
  39. // 创建请求对象
  40. req := larkauth.NewInternalTenantAccessTokenReqBuilder().
  41. Body(larkauth.NewInternalTenantAccessTokenReqBodyBuilder().
  42. AppId(appId).
  43. AppSecret(appSecret).
  44. Build()).
  45. Build()
  46. // 发起请求
  47. resp, err := LarkClient.Auth.V3.TenantAccessToken.Internal(context.Background(), req)
  48. // 处理错误
  49. if err != nil {
  50. logrus.Warnf("GetTenantAccessToken error: %v", err)
  51. return "", err
  52. }
  53. // 服务端错误处理
  54. if !resp.Success() {
  55. logrus.Warnf("GetTenantAccessToken error: %v", resp.Msg)
  56. return "", errors.New(resp.Msg)
  57. }
  58. type tokenResp struct {
  59. Code int `json:"code"`
  60. Expire int `json:"expire"`
  61. Msg string `json:"msg"`
  62. TenantAccessToken string `json:"tenant_access_token"`
  63. }
  64. respData := new(tokenResp)
  65. err = json.Unmarshal(resp.RawBody, respData)
  66. if err != nil {
  67. logrus.Warnf("GetTenantAccessToken error: %v", err)
  68. return "", err
  69. }
  70. tokenCache.Set(tokenCacheKey, respData.TenantAccessToken, time.Duration(respData.Expire)*time.Second)
  71. return respData.TenantAccessToken, nil
  72. }