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"