lark

package module
v3.9.9 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 7, 2026 License: MIT Imports: 66 Imported by: 246

README

Feishu OpenPlatform Server SDK

English | Simplified Chinese

Feishu Open Platform offers a series of server-side atomic APIs to achieve diverse functionalities. However, actual coding requires additional work, such as obtaining and maintaining access tokens, encrypting and decrypting data, and verifying request signatures. Furthermore, the lack of semantic descriptions for function calls and type system support can increase coding burdens.

To address these issues, Feishu Open Platform has developed the Open Interface SDK, which incorporates these lengthy logic processes, provides a comprehensive type system, and offers a semantic programming interface to improve the coding experience.

Introduction Documents

Channel Module

The SDK provides a Channel module built on top of WebSocket and the API Client. It encapsulates event listening, message normalization, streaming replies, and media uploads, allowing developers to focus purely on business logic.

One-Click App Registration

The SDK provides registration.RegisterApp for one-click app creation based on OAuth 2.0 Device Authorization Grant (RFC 8628). It returns a verification URL that users can open in Feishu/Lark or render as a QR code. After authorization, the app is created automatically and the SDK returns the App ID and App Secret.

package main

import (
	"context"
	"errors"
	"fmt"
	"time"

	lark "github.com/larksuite/oapi-sdk-go/v3"
	"github.com/larksuite/oapi-sdk-go/v3/scene/registration"
)

func main() {
	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Minute)
	defer cancel()

	result, err := registration.RegisterApp(ctx, &registration.Options{
		OnQRCode: func(info *registration.QRCodeInfo) {
			fmt.Printf("open or scan this url: %s\n", info.URL)
			fmt.Printf("the link expires in %d seconds\n", info.ExpireIn)
		},
		OnStatusChange: func(info *registration.StatusChangeInfo) {
			// status: polling | slow_down | domain_switched
			fmt.Printf("registration status: %s", info.Status)
			if info.Interval > 0 {
				fmt.Printf(", next poll after %d seconds", info.Interval)
			}
			fmt.Println()
		},
	})
	if err != nil {
		var regErr *registration.RegisterAppError
		if errors.As(err, &regErr) {
			fmt.Printf("register app failed: code=%s, description=%s\n", regErr.Code, regErr.Description)
			return
		}
		panic(err)
	}

	fmt.Println("App ID:", result.ClientID)
	fmt.Println("App Secret:", result.ClientSecret)

	client := lark.NewClient(result.ClientID, result.ClientSecret)
	_ = client
}
Custom Scopes, Events, Callbacks, And Updating An Existing App

When creating an app, use Options.Addons to incrementally request scopes, event subscriptions, and callbacks on top of the platform base template. The values are pre-filled into the confirmation page after the user opens the QR code URL and take effect after confirmation. Options.CreateOnly=true only allows creating a new app. Options.AppID starts the update flow for an existing app.

_, err := registration.RegisterApp(ctx, &registration.Options{
	Addons: &registration.AppAddons{
		Scopes: registration.AppAddonsScopes{
			Tenant: []string{"im:message:send_as_bot"},
			User:   []string{"calendar:calendar:read"},
		},
		Events: registration.AppAddonsEvents{
			Items: registration.AppAddonsEventItems{
				Tenant: []string{"im.message.receive_v1"},
			},
		},
		Callbacks: registration.AppAddonsCallbacks{
			Items: []string{"card.action.trigger"},
		},
	},
	CreateOnly: true,
	OnQRCode: func(info *registration.QRCodeInfo) {
		fmt.Println(info.URL)
	},
})
if err != nil {
	panic(err)
}

_, err = registration.RegisterApp(ctx, &registration.Options{
	AppID: "cli_xxx",
	Addons: &registration.AppAddons{
		Scopes: registration.AppAddonsScopes{
			Tenant: []string{"drive:drive.metadata:readonly"},
		},
	},
	OnQRCode: func(info *registration.QRCodeInfo) {
		fmt.Println(info.URL)
	},
})
if err != nil {
	panic(err)
}

Notes: Addons is additive only and cannot remove config from the base template. The SDK validates shape and non-empty strings, but does not validate whether scope, event, or callback names exist.

Choosing The Base Template With Preset

AppAddons.Preset selects the base template for app creation (it is unrelated to Options.AppPreset, which pre-fills the app name, description, and avatar):

Value Base template Behavior
unset (nil) Platform default template Same as before this field existed; the encoded payload carries no preset key.
false Minimal base template The confirmation page shows only the scopes, events, and callbacks declared in Addons.
true Platform default template Explicitly requests the default base, same as unset.

With Preset set to false, an Addons without any scope, event, or callback is valid — the page still enters the confirmation flow and creates an app with only the minimal base capabilities:

preset := false
_, err := registration.RegisterApp(ctx, &registration.Options{
	Addons: &registration.AppAddons{
		Preset: &preset,
	},
	OnQRCode: func(info *registration.QRCodeInfo) {
		fmt.Println(info.URL)
	},
})
if err != nil {
	panic(err)
}
registration.RegisterApp Parameters
Parameter Description Type Required Default
ctx Controls timeout and cancellation for the registration flow; canceling the context stops polling. context.Context Yes -
Options.Source Source identifier appended to the QR URL as go-sdk/{source}. string No go-sdk
Options.Domain Custom Feishu accounts domain. A full base URL such as https://accounts.feishu.cn is supported. string No https://accounts.feishu.cn
Options.LarkDomain Custom Lark accounts domain used when tenant_brand=lark is detected. string No https://accounts.larksuite.com
Options.AppPreset Pre-filled app creation values; users can still edit them on the page. *registration.AppPreset No -
Options.AppPreset.Avatar App avatar URLs, 1-6 entries; first entry is selected by default. Pass raw URLs and the SDK encodes them. Page-side display rules are handled by the app creation page. []string No -
Options.AppPreset.Name App name with {user} placeholder support; pass raw value and the SDK encodes it. string No -
Options.AppPreset.Desc App description with {user} placeholder support; pass raw value and the SDK encodes it. string No -
Options.Addons Incremental scopes, events, and callbacks pre-filled into the confirmation page. *registration.AppAddons No -
Options.Addons.Preset Base template selector: unset for the platform default template, false for the minimal base template (empty increments allowed), true for explicitly requesting the default base. *bool No -
Options.Addons.Scopes.Tenant App-identity scopes, for example im:message:send_as_bot. []string No -
Options.Addons.Scopes.User User-identity scopes, for example calendar:calendar:read. []string No -
Options.Addons.Events.Items.Tenant App-identity events, for example im.message.receive_v1. []string No -
Options.Addons.Events.Items.User User-identity events, for example calendar.calendar.event.changed_v4. []string No -
Options.Addons.Callbacks.Items Callback names, for example card.action.trigger. []string No -
Options.CreateOnly When true, the landing page only allows creating a new app. When used together with Options.AppID, the page gives create-new-app flow precedence. bool No false
Options.AppID Existing app ID carried as clientID in the QR URL for the update flow. string No -
Options.OnQRCode Callback invoked when the verification URL is ready. The callback receives { URL, ExpireIn }. func(info *registration.QRCodeInfo) Yes -
Options.OnStatusChange Callback for polling status changes. Status can be polling, slow_down, or domain_switched. func(info *registration.StatusChangeInfo) No -
Return Value
Field Type Description
ClientID string App ID
ClientSecret string App Secret
UserInfo *registration.UserInfo Scanning user info
UserInfo.OpenID string User open_id
UserInfo.TenantBrand string "feishu" or "lark"
Error Handling

Returned errors usually expose Code and Description through registration.RegisterAppError. More specific types include registration.AccessDeniedError and registration.ExpiredError.

Code Description
access_denied User denied authorization
expired_token QR code expired or polling timed out
invalid_response Response is empty or missing required fields

Extended Examples

We also provide common API composition examples and business scenario examples based on the SDK, such as:

For more examples, see https://github.com/larksuite/oapi-sdk-go-demo

Community

Join the support group

License

MIT

Documentation

Index

Constants

This section is empty.

Variables

View Source
var FeishuBaseUrl = "https://open.feishu.cn"
View Source
var LarkBaseUrl = "https://open.larksuite.com"
View Source
var OAuthBaseUrlFeishu = "https://accounts.feishu.cn"
View Source
var OAuthBaseUrlLark = "https://accounts.larksuite.com"

Functions

This section is empty.

Types

type Client

type Client struct {
	Base                   *base.Service
	Report                 *report.Service
	SecurityAndCompliance  *security_and_compliance.Service
	Block                  *block.Service
	Bitable                *bitable.Service
	Contact                *contact.Service
	Drive                  *drive.Service
	Okr                    *okr.Service
	Cardkit                *cardkit.Service
	Ehr                    *ehr.Service
	Elearning              *elearning.Service
	Spark                  *spark.Service
	Approval               *approval.Service
	Authen                 *authen.Service
	Compensation           *compensation.Service
	Hire                   *hire.Service
	Wiki                   *wiki.Service
	MeetingRoom            *meeting_room.Service
	Minutes                *minutes.Service
	Verification           *verification.Service
	Workplace              *workplace.Service
	Attendance             *attendance.Service
	Calendar               *calendar.Service
	Helpdesk               *helpdesk.Service
	PersonalSettings       *personal_settings.Service
	Auth                   *auth.Service
	Baike                  *baike.Service
	Passport               *passport.Service
	Admin                  *admin.Service
	Application            *application.Service
	Docs                   *docs.Service
	Payroll                *payroll.Service
	Translation            *translation.Service
	Im                     *im.Service
	Moments                *moments.Service
	SpeechToText           *speech_to_text.Service
	Aily                   *aily.Service
	Docx                   *docx.Service
	OpticalCharRecognition *optical_char_recognition.Service
	Vc                     *vc.Service
	Apaas                  *apaas.Service
	Directory              *directory.Service
	Event                  *event.Service
	HumanAuthentication    *human_authentication.Service
	TrustParty             *trust_party.Service
	Acs                    *acs.Service
	Board                  *board.Service
	Mdm                    *mdm.Service
	Search                 *search.Service
	Task                   *task.Service
	Corehr                 *corehr.Service
	Mail                   *mail.Service
	Sheets                 *sheets.Service
	Tenant                 *tenant.Service
	DocumentAi             *document_ai.Service
	Lingo                  *lingo.Service
	Performance            *performance.Service
	AccessToken            *accesstoken.AccessToken
	Ext                    *larkext.ExtService
	// contains filtered or unexported fields
}

func NewClient

func NewClient(appId, appSecret string, options ...ClientOptionFunc) *Client

func (*Client) Delete

func (cli *Client) Delete(ctx context.Context, httpPath string, body interface{}, accessTokeType larkcore.AccessTokenType, options ...larkcore.RequestOptionFunc) (*larkcore.ApiResp, error)

func (*Client) Do added in v3.0.1

func (cli *Client) Do(ctx context.Context, apiReq *larkcore.ApiReq, options ...larkcore.RequestOptionFunc) (*larkcore.ApiResp, error)

func (*Client) Get

func (cli *Client) Get(ctx context.Context, httpPath string, body interface{}, accessTokeType larkcore.AccessTokenType, options ...larkcore.RequestOptionFunc) (*larkcore.ApiResp, error)

func (*Client) GetAppAccessTokenByMarketplaceApp added in v3.0.1

func (cli *Client) GetAppAccessTokenByMarketplaceApp(ctx context.Context, req *larkcore.MarketplaceAppAccessTokenReq) (*larkcore.AppAccessTokenResp, error)

func (*Client) GetAppAccessTokenBySelfBuiltApp added in v3.0.1

func (cli *Client) GetAppAccessTokenBySelfBuiltApp(ctx context.Context, req *larkcore.SelfBuiltAppAccessTokenReq) (*larkcore.AppAccessTokenResp, error)

func (*Client) GetTenantAccessTokenByMarketplaceApp added in v3.0.1

func (cli *Client) GetTenantAccessTokenByMarketplaceApp(ctx context.Context, req *larkcore.MarketplaceTenantAccessTokenReq) (*larkcore.TenantAccessTokenResp, error)

func (*Client) GetTenantAccessTokenBySelfBuiltApp added in v3.0.1

func (cli *Client) GetTenantAccessTokenBySelfBuiltApp(ctx context.Context, req *larkcore.SelfBuiltTenantAccessTokenReq) (*larkcore.TenantAccessTokenResp, error)

func (*Client) Patch

func (cli *Client) Patch(ctx context.Context, httpPath string, body interface{}, accessTokeType larkcore.AccessTokenType, options ...larkcore.RequestOptionFunc) (*larkcore.ApiResp, error)

func (*Client) Post

func (cli *Client) Post(ctx context.Context, httpPath string, body interface{}, accessTokeType larkcore.AccessTokenType, options ...larkcore.RequestOptionFunc) (*larkcore.ApiResp, error)

func (*Client) Put

func (cli *Client) Put(ctx context.Context, httpPath string, body interface{}, accessTokeType larkcore.AccessTokenType, options ...larkcore.RequestOptionFunc) (*larkcore.ApiResp, error)

func (*Client) ResendAppTicket added in v3.0.1

func (cli *Client) ResendAppTicket(ctx context.Context, req *larkcore.ResendAppTicketReq) (*larkcore.ResendAppTicketResp, error)

type ClientOptionFunc

type ClientOptionFunc func(config *larkcore.Config)

func WithAppType

func WithAppType(appType larkcore.AppType) ClientOptionFunc

func WithClientAssertionProvider added in v3.7.1

func WithClientAssertionProvider(provider larkcore.ClientAssertionProvider) ClientOptionFunc

func WithEnableTokenCache

func WithEnableTokenCache(enableTokenCache bool) ClientOptionFunc

func WithHeaders added in v3.0.3

func WithHeaders(header http.Header) ClientOptionFunc

设置每次请求都会携带的 header

func WithHelpdeskCredential

func WithHelpdeskCredential(helpdeskID, helpdeskToken string) ClientOptionFunc

func WithHttpClient

func WithHttpClient(httpClient larkcore.HttpClient) ClientOptionFunc

func WithLogLevel

func WithLogLevel(logLevel larkcore.LogLevel) ClientOptionFunc

func WithLogReqAtDebug added in v3.0.1

func WithLogReqAtDebug(printReqRespLog bool) ClientOptionFunc

func WithLogger

func WithLogger(logger larkcore.Logger) ClientOptionFunc

func WithMarketplaceApp

func WithMarketplaceApp() ClientOptionFunc

func WithOAuthBaseUrl added in v3.9.1

func WithOAuthBaseUrl(oauthBaseUrl string) ClientOptionFunc

func WithOpenBaseUrl

func WithOpenBaseUrl(baseUrl string) ClientOptionFunc

func WithReqTimeout

func WithReqTimeout(reqTimeout time.Duration) ClientOptionFunc

func WithSerialization added in v3.0.10

func WithSerialization(serializable larkcore.Serializable) ClientOptionFunc

func WithSource added in v3.8.1

func WithSource(source string) ClientOptionFunc

设置 User-Agent 中附加的 source 标识

func WithTokenCache

func WithTokenCache(cache larkcore.Cache) ClientOptionFunc

Directories

Path Synopsis
dispatcher
Package dispatcher code generated by oapi sdk gen
Package dispatcher code generated by oapi sdk gen
scene
service
acs
ehr
ext
im
mdm
okr
vc

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL