gitee.com/larksuite/oapi-sdk-go/v3@v3.0.3/client.go (about)

     1  //  code generated by oapi sdk gen
     2  /*
     3   * MIT License
     4   *
     5   * Copyright (c) 2022 Lark Technologies Pte. Ltd.
     6   *
     7   * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
     8   *
     9   * The above copyright notice and this permission notice, shall be included in all copies or substantial portions of the Software.
    10   *
    11   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
    12   */
    13  
    14  package lark
    15  
    16  import (
    17  	"context"
    18  	"encoding/base64"
    19  	"encoding/json"
    20  	"fmt"
    21  	"net/http"
    22  	"time"
    23  
    24  	"gitee.com/larksuite/oapi-sdk-go/v3/core"
    25  	"gitee.com/larksuite/oapi-sdk-go/v3/service/acs/v1"
    26  	"gitee.com/larksuite/oapi-sdk-go/v3/service/admin/v1"
    27  	"gitee.com/larksuite/oapi-sdk-go/v3/service/application/v6"
    28  	"gitee.com/larksuite/oapi-sdk-go/v3/service/approval/v4"
    29  	"gitee.com/larksuite/oapi-sdk-go/v3/service/attendance/v1"
    30  	"gitee.com/larksuite/oapi-sdk-go/v3/service/baike/v1"
    31  	"gitee.com/larksuite/oapi-sdk-go/v3/service/bitable/v1"
    32  	"gitee.com/larksuite/oapi-sdk-go/v3/service/block/v2"
    33  	"gitee.com/larksuite/oapi-sdk-go/v3/service/calendar/v4"
    34  	"gitee.com/larksuite/oapi-sdk-go/v3/service/contact/v3"
    35  	"gitee.com/larksuite/oapi-sdk-go/v3/service/docx/v1"
    36  	"gitee.com/larksuite/oapi-sdk-go/v3/service/drive/v1"
    37  	"gitee.com/larksuite/oapi-sdk-go/v3/service/ehr/v1"
    38  	"gitee.com/larksuite/oapi-sdk-go/v3/service/event/v1"
    39  	"gitee.com/larksuite/oapi-sdk-go/v3/service/ext"
    40  	"gitee.com/larksuite/oapi-sdk-go/v3/service/face_detection/v1"
    41  	"gitee.com/larksuite/oapi-sdk-go/v3/service/gray_test_open_sg/v1"
    42  	"gitee.com/larksuite/oapi-sdk-go/v3/service/helpdesk/v1"
    43  	"gitee.com/larksuite/oapi-sdk-go/v3/service/hire/v1"
    44  	"gitee.com/larksuite/oapi-sdk-go/v3/service/human_authentication/v1"
    45  	"gitee.com/larksuite/oapi-sdk-go/v3/service/im/v1"
    46  	"gitee.com/larksuite/oapi-sdk-go/v3/service/mail/v1"
    47  	"gitee.com/larksuite/oapi-sdk-go/v3/service/okr/v1"
    48  	"gitee.com/larksuite/oapi-sdk-go/v3/service/optical_char_recognition/v1"
    49  	"gitee.com/larksuite/oapi-sdk-go/v3/service/passport/v1"
    50  	"gitee.com/larksuite/oapi-sdk-go/v3/service/search/v2"
    51  	"gitee.com/larksuite/oapi-sdk-go/v3/service/sheets/v3"
    52  	"gitee.com/larksuite/oapi-sdk-go/v3/service/speech_to_text/v1"
    53  	"gitee.com/larksuite/oapi-sdk-go/v3/service/task/v1"
    54  	"gitee.com/larksuite/oapi-sdk-go/v3/service/tenant/v2"
    55  	"gitee.com/larksuite/oapi-sdk-go/v3/service/translation/v1"
    56  	"gitee.com/larksuite/oapi-sdk-go/v3/service/vc/v1"
    57  	"gitee.com/larksuite/oapi-sdk-go/v3/service/wiki/v2"
    58  )
    59  
    60  type Client struct {
    61  	config                 *larkcore.Config
    62  	Acs                    *larkacs.AcsService                                         // 智能门禁
    63  	Admin                  *larkadmin.AdminService                                     // 管理后台-企业勋章
    64  	Application            *larkapplication.ApplicationService                         // 应用信息
    65  	Approval               *larkapproval.ApprovalService                               // 审批
    66  	Attendance             *larkattendance.AttendanceService                           // 打卡
    67  	Baike                  *larkbaike.BaikeService                                     // 企业百科
    68  	Bitable                *larkbitable.BitableService                                 // 云文档-多维表格
    69  	Block                  *larkblock.BlockService                                     // 小组件
    70  	Calendar               *larkcalendar.CalendarService                               // 日历
    71  	Contact                *larkcontact.ContactService                                 // 通讯录
    72  	Docx                   *larkdocx.DocxService                                       // 云文档-文档
    73  	Drive                  *larkdrive.DriveService                                     // 云文档-文件管理
    74  	Ehr                    *larkehr.EhrService                                         // 智能人事
    75  	Event                  *larkevent.EventService                                     // 事件订阅
    76  	FaceDetection          *larkface_detection.FaceDetectionService                    // AI能力
    77  	GrayTestOpenSg         *larkgray_test_open_sg.GrayTestOpenSgService                //
    78  	Helpdesk               *larkhelpdesk.HelpdeskService                               // 服务台
    79  	Hire                   *larkhire.HireService                                       // 招聘
    80  	HumanAuthentication    *larkhuman_authentication.HumanAuthenticationService        // 实名认证
    81  	Im                     *larkim.ImService                                           // 消息与群组
    82  	Mail                   *larkmail.MailService                                       // 邮箱
    83  	Okr                    *larkokr.OkrService                                         // OKR
    84  	OpticalCharRecognition *larkoptical_char_recognition.OpticalCharRecognitionService // AI能力
    85  	Passport               *larkpassport.PassportService                               // 帐号
    86  	Search                 *larksearch.SearchService                                   // 搜索
    87  	Sheets                 *larksheets.SheetsService                                   // 云文档-电子表格
    88  	SpeechToText           *larkspeech_to_text.SpeechToTextService                     // AI能力
    89  	Task                   *larktask.TaskService                                       // 任务
    90  	Tenant                 *larktenant.TenantService                                   // 企业信息
    91  	Translation            *larktranslation.TranslationService                         // AI能力
    92  	Vc                     *larkvc.VcService                                           // 视频会议
    93  	Wiki                   *larkwiki.WikiService                                       // 云文档-知识库
    94  	Ext                    *larkext.ExtService
    95  }
    96  
    97  type ClientOptionFunc func(config *larkcore.Config)
    98  
    99  func WithAppType(appType larkcore.AppType) ClientOptionFunc {
   100  	return func(config *larkcore.Config) {
   101  		config.AppType = appType
   102  	}
   103  }
   104  
   105  func WithMarketplaceApp() ClientOptionFunc {
   106  	return func(config *larkcore.Config) {
   107  		config.AppType = larkcore.AppTypeMarketplace
   108  	}
   109  }
   110  
   111  func WithEnableTokenCache(enableTokenCache bool) ClientOptionFunc {
   112  	return func(config *larkcore.Config) {
   113  		config.EnableTokenCache = enableTokenCache
   114  	}
   115  }
   116  
   117  func WithLogger(logger larkcore.Logger) ClientOptionFunc {
   118  	return func(config *larkcore.Config) {
   119  		config.Logger = logger
   120  	}
   121  }
   122  
   123  func WithOpenBaseUrl(baseUrl string) ClientOptionFunc {
   124  	return func(config *larkcore.Config) {
   125  		config.BaseUrl = baseUrl
   126  	}
   127  }
   128  
   129  func WithLogLevel(logLevel larkcore.LogLevel) ClientOptionFunc {
   130  	return func(config *larkcore.Config) {
   131  		config.LogLevel = logLevel
   132  	}
   133  }
   134  
   135  func WithTokenCache(cache larkcore.Cache) ClientOptionFunc {
   136  	return func(config *larkcore.Config) {
   137  		config.TokenCache = cache
   138  	}
   139  }
   140  
   141  func WithLogReqAtDebug(printReqRespLog bool) ClientOptionFunc {
   142  	return func(config *larkcore.Config) {
   143  		config.LogReqAtDebug = printReqRespLog
   144  	}
   145  }
   146  
   147  func WithHttpClient(httpClient larkcore.HttpClient) ClientOptionFunc {
   148  	return func(config *larkcore.Config) {
   149  		config.HttpClient = httpClient
   150  	}
   151  }
   152  
   153  func WithHelpdeskCredential(helpdeskID, helpdeskToken string) ClientOptionFunc {
   154  	return func(config *larkcore.Config) {
   155  		config.HelpDeskId = helpdeskID
   156  		config.HelpDeskToken = helpdeskToken
   157  		if helpdeskID != "" && helpdeskToken != "" {
   158  			config.HelpdeskAuthToken = base64.StdEncoding.EncodeToString([]byte(fmt.Sprintf("%s:%s", helpdeskID, helpdeskToken)))
   159  		}
   160  	}
   161  }
   162  
   163  func WithReqTimeout(reqTimeout time.Duration) ClientOptionFunc {
   164  	return func(config *larkcore.Config) {
   165  		config.ReqTimeout = reqTimeout
   166  	}
   167  }
   168  
   169  func NewClient(appId, appSecret string, options ...ClientOptionFunc) *Client {
   170  	// 构建配置
   171  	config := &larkcore.Config{
   172  		BaseUrl:          FeishuBaseUrl,
   173  		AppId:            appId,
   174  		AppSecret:        appSecret,
   175  		EnableTokenCache: true,
   176  		AppType:          larkcore.AppTypeSelfBuilt,
   177  	}
   178  	for _, option := range options {
   179  		option(config)
   180  	}
   181  
   182  	// 构建日志器
   183  	larkcore.NewLogger(config)
   184  
   185  	// 构建缓存
   186  	larkcore.NewCache(config)
   187  
   188  	// 创建httpclient
   189  	larkcore.NewHttpClient(config)
   190  
   191  	// 创建sdk-client,并初始化服务
   192  	client := &Client{config: config}
   193  	initService(client, config)
   194  
   195  	// 触发重推 appTicket,如果是 ISV 的话
   196  	resendAppTicketIfNeed(client)
   197  	return client
   198  }
   199  
   200  func initService(client *Client, config *larkcore.Config) {
   201  	client.Acs = larkacs.NewService(config)
   202  	client.Admin = larkadmin.NewService(config)
   203  	client.Application = larkapplication.NewService(config)
   204  	client.Approval = larkapproval.NewService(config)
   205  	client.Attendance = larkattendance.NewService(config)
   206  	client.Baike = larkbaike.NewService(config)
   207  	client.Bitable = larkbitable.NewService(config)
   208  	client.Block = larkblock.NewService(config)
   209  	client.Calendar = larkcalendar.NewService(config)
   210  	client.Contact = larkcontact.NewService(config)
   211  	client.Docx = larkdocx.NewService(config)
   212  	client.Drive = larkdrive.NewService(config)
   213  	client.Ehr = larkehr.NewService(config)
   214  	client.Event = larkevent.NewService(config)
   215  	client.FaceDetection = larkface_detection.NewService(config)
   216  	client.GrayTestOpenSg = larkgray_test_open_sg.NewService(config)
   217  	client.Helpdesk = larkhelpdesk.NewService(config)
   218  	client.Hire = larkhire.NewService(config)
   219  	client.HumanAuthentication = larkhuman_authentication.NewService(config)
   220  	client.Im = larkim.NewService(config)
   221  	client.Mail = larkmail.NewService(config)
   222  	client.Okr = larkokr.NewService(config)
   223  	client.OpticalCharRecognition = larkoptical_char_recognition.NewService(config)
   224  	client.Passport = larkpassport.NewService(config)
   225  	client.Search = larksearch.NewService(config)
   226  	client.Sheets = larksheets.NewService(config)
   227  	client.SpeechToText = larkspeech_to_text.NewService(config)
   228  	client.Task = larktask.NewService(config)
   229  	client.Tenant = larktenant.NewService(config)
   230  	client.Translation = larktranslation.NewService(config)
   231  	client.Vc = larkvc.NewService(config)
   232  	client.Wiki = larkwiki.NewService(config)
   233  	client.Ext = larkext.NewService(config)
   234  }
   235  
   236  func resendAppTicketIfNeed(client *Client) {
   237  	defer func() {
   238  		if err := recover(); err != nil {
   239  			client.config.Logger.Error(context.Background(), fmt.Sprintf("resendAppTicketIfNeed, error:%v", err))
   240  		}
   241  	}()
   242  
   243  	if client.config.AppType == larkcore.AppTypeMarketplace {
   244  		ctx := context.Background()
   245  		resp, err := client.ResendAppTicket(ctx, &larkcore.ResendAppTicketReq{
   246  			AppID:     client.config.AppId,
   247  			AppSecret: client.config.AppSecret,
   248  		})
   249  		if err != nil {
   250  			client.config.Logger.Info(ctx, fmt.Sprintf("resend appTicket error:%v", err))
   251  			return
   252  		}
   253  		client.config.Logger.Info(ctx, fmt.Sprintf("resend appTicket resp:%v", resp))
   254  
   255  	}
   256  }
   257  
   258  func (cli *Client) Post(ctx context.Context, httpPath string, body interface{}, accessTokeType larkcore.AccessTokenType, options ...larkcore.RequestOptionFunc) (*larkcore.ApiResp, error) {
   259  	return cli.Do(ctx, &larkcore.ApiReq{
   260  		HttpMethod:                http.MethodPost,
   261  		ApiPath:                   httpPath,
   262  		Body:                      body,
   263  		SupportedAccessTokenTypes: []larkcore.AccessTokenType{accessTokeType},
   264  	}, options...)
   265  }
   266  
   267  func (cli *Client) Do(ctx context.Context, apiReq *larkcore.ApiReq, options ...larkcore.RequestOptionFunc) (*larkcore.ApiResp, error) {
   268  	return larkcore.Request(ctx, apiReq, cli.config, options...)
   269  }
   270  func (cli *Client) Get(ctx context.Context, httpPath string, body interface{}, accessTokeType larkcore.AccessTokenType, options ...larkcore.RequestOptionFunc) (*larkcore.ApiResp, error) {
   271  	return cli.Do(ctx, &larkcore.ApiReq{
   272  		HttpMethod:                http.MethodGet,
   273  		ApiPath:                   httpPath,
   274  		Body:                      body,
   275  		SupportedAccessTokenTypes: []larkcore.AccessTokenType{accessTokeType},
   276  	}, options...)
   277  }
   278  
   279  func (cli *Client) Delete(ctx context.Context, httpPath string, body interface{}, accessTokeType larkcore.AccessTokenType, options ...larkcore.RequestOptionFunc) (*larkcore.ApiResp, error) {
   280  	return cli.Do(ctx, &larkcore.ApiReq{
   281  		HttpMethod:                http.MethodDelete,
   282  		ApiPath:                   httpPath,
   283  		Body:                      body,
   284  		SupportedAccessTokenTypes: []larkcore.AccessTokenType{accessTokeType},
   285  	}, options...)
   286  }
   287  
   288  func (cli *Client) Put(ctx context.Context, httpPath string, body interface{}, accessTokeType larkcore.AccessTokenType, options ...larkcore.RequestOptionFunc) (*larkcore.ApiResp, error) {
   289  	return cli.Do(ctx, &larkcore.ApiReq{
   290  		HttpMethod:                http.MethodPut,
   291  		ApiPath:                   httpPath,
   292  		Body:                      body,
   293  		SupportedAccessTokenTypes: []larkcore.AccessTokenType{accessTokeType},
   294  	}, options...)
   295  }
   296  
   297  func (cli *Client) Patch(ctx context.Context, httpPath string, body interface{}, accessTokeType larkcore.AccessTokenType, options ...larkcore.RequestOptionFunc) (*larkcore.ApiResp, error) {
   298  	return cli.Do(ctx, &larkcore.ApiReq{
   299  		HttpMethod:                http.MethodPatch,
   300  		ApiPath:                   httpPath,
   301  		Body:                      body,
   302  		SupportedAccessTokenTypes: []larkcore.AccessTokenType{accessTokeType},
   303  	}, options...)
   304  }
   305  
   306  func (cli *Client) GetAppAccessTokenBySelfBuiltApp(ctx context.Context, req *larkcore.SelfBuiltAppAccessTokenReq) (*larkcore.AppAccessTokenResp, error) {
   307  	rawResp, err := larkcore.Request(ctx, &larkcore.ApiReq{
   308  		HttpMethod:                http.MethodPost,
   309  		ApiPath:                   larkcore.AppAccessTokenInternalUrlPath,
   310  		Body:                      req,
   311  		SupportedAccessTokenTypes: []larkcore.AccessTokenType{larkcore.AccessTokenTypeNone},
   312  	}, cli.config)
   313  
   314  	if err != nil {
   315  		return nil, err
   316  	}
   317  	resp := &larkcore.AppAccessTokenResp{}
   318  	err = json.Unmarshal(rawResp.RawBody, resp)
   319  	if err != nil {
   320  		return nil, err
   321  	}
   322  	resp.ApiResp = rawResp
   323  
   324  	return resp, nil
   325  }
   326  
   327  func (cli *Client) GetAppAccessTokenByMarketplaceApp(ctx context.Context, req *larkcore.MarketplaceAppAccessTokenReq) (*larkcore.AppAccessTokenResp, error) {
   328  	rawResp, err := larkcore.Request(ctx, &larkcore.ApiReq{
   329  		HttpMethod:                http.MethodPost,
   330  		ApiPath:                   larkcore.AppAccessTokenUrlPath,
   331  		Body:                      req,
   332  		SupportedAccessTokenTypes: []larkcore.AccessTokenType{larkcore.AccessTokenTypeNone},
   333  	}, cli.config)
   334  
   335  	if err != nil {
   336  		return nil, err
   337  	}
   338  	resp := &larkcore.AppAccessTokenResp{}
   339  	err = json.Unmarshal(rawResp.RawBody, resp)
   340  	if err != nil {
   341  		return nil, err
   342  	}
   343  	resp.ApiResp = rawResp
   344  
   345  	return resp, nil
   346  }
   347  
   348  func (cli *Client) GetTenantAccessTokenBySelfBuiltApp(ctx context.Context, req *larkcore.SelfBuiltTenantAccessTokenReq) (*larkcore.TenantAccessTokenResp, error) {
   349  	rawResp, err := larkcore.Request(ctx, &larkcore.ApiReq{
   350  		HttpMethod:                http.MethodPost,
   351  		ApiPath:                   larkcore.TenantAccessTokenInternalUrlPath,
   352  		Body:                      req,
   353  		SupportedAccessTokenTypes: []larkcore.AccessTokenType{larkcore.AccessTokenTypeNone},
   354  	}, cli.config)
   355  
   356  	if err != nil {
   357  		return nil, err
   358  	}
   359  	resp := &larkcore.TenantAccessTokenResp{}
   360  	err = json.Unmarshal(rawResp.RawBody, resp)
   361  	if err != nil {
   362  		return nil, err
   363  	}
   364  	resp.ApiResp = rawResp
   365  
   366  	return resp, nil
   367  }
   368  
   369  func (cli *Client) GetTenantAccessTokenByMarketplaceApp(ctx context.Context, req *larkcore.MarketplaceTenantAccessTokenReq) (*larkcore.TenantAccessTokenResp, error) {
   370  	rawResp, err := larkcore.Request(ctx, &larkcore.ApiReq{
   371  		HttpMethod:                http.MethodPost,
   372  		ApiPath:                   larkcore.TenantAccessTokenUrlPath,
   373  		Body:                      req,
   374  		SupportedAccessTokenTypes: []larkcore.AccessTokenType{larkcore.AccessTokenTypeNone},
   375  	}, cli.config)
   376  
   377  	if err != nil {
   378  		return nil, err
   379  	}
   380  	resp := &larkcore.TenantAccessTokenResp{}
   381  	err = json.Unmarshal(rawResp.RawBody, resp)
   382  	if err != nil {
   383  		return nil, err
   384  	}
   385  	resp.ApiResp = rawResp
   386  
   387  	return resp, nil
   388  }
   389  
   390  func (cli *Client) ResendAppTicket(ctx context.Context, req *larkcore.ResendAppTicketReq) (*larkcore.ResendAppTicketResp, error) {
   391  	rawResp, err := larkcore.Request(ctx, &larkcore.ApiReq{
   392  		HttpMethod:                http.MethodPost,
   393  		ApiPath:                   larkcore.ApplyAppTicketPath,
   394  		Body:                      req,
   395  		SupportedAccessTokenTypes: []larkcore.AccessTokenType{larkcore.AccessTokenTypeNone},
   396  	}, cli.config)
   397  
   398  	if err != nil {
   399  		return nil, err
   400  	}
   401  	resp := &larkcore.ResendAppTicketResp{}
   402  	err = json.Unmarshal(rawResp.RawBody, resp)
   403  	if err != nil {
   404  		return nil, err
   405  	}
   406  	resp.ApiResp = rawResp
   407  
   408  	return resp, nil
   409  }
   410  
   411  var FeishuBaseUrl = "https://open.feishu.cn"
   412  var LarkBaseUrl = "https://open.larksuite.com"