go-lark SDK

repository·main·Indexed 42 days ago

https://github.com/go-lark/lark

A Go SDK for interacting with the Feishu and Lark Open Platforms, specializing in building Chat Bots and Notification Bots. It provides high-level abstractions for messaging via MsgBuffer, authentication with automatic token renewal (StartHeartbeat), and event handling through Gin middleware for URL challenges, Event V2, and interactive card callbacks.

Tokens
52.7K
Snippets
208
Records
241
Agent score
53%

What's inside go-lark

  1. Build complex messages with MsgBuffer

    main

    For rich messages, use MsgBuffer (or lark.NewMsgBuffer) which allows for method chaining to build message bodies.

    Supported Message Types

    • MsgText: Plain text
    • MsgPost: Rich text
    • MsgInteractive: Interactive cards
    • MsgShareCard: Group share cards
    • MsgShareUser: User share cards
    • MsgImage: Images
    • MsgFile: Files
    • MsgAudio: Audio
    • MsgMedia: Media
    • MsgSticker: Stickers

    Binding Functions

    Use these to specify the recipient or context:

    • BindChatID: Bind to OpenID, UserID, Email, ChatID, or UnionID.
    • BindOpenID: Bind to a user's Open ID.
    • BindUserID: Bind to a user's User ID.
    • BindUnionID: Bind to a user's Union ID.
    • BindEmail: Bind to a user's email.
    • BindReply: Required when replying to a specific message ID.

    Content Functions

    Pair these with the appropriate message type:

    • Text for MsgText
    • Post for MsgPost
    • Card for MsgInteractive
    • Template for MsgInteractive (requires CardKit)
    • ShareChat for MsgShareCard
    • ShareUser for MsgShareUser
    • Image, File, Audio, Media, Sticker (requires prior upload to Lark server)
  2. Manage Authentication (Chat Bot)

    main

    Auto-renewable authentication

    To ensure your bot stays authenticated, use StartHeartbeat() to renew the access token periodically. Use StopHeartbeat() to cease renewal.

    Single-pass authentication

    If you need to manually fetch a token once, use GetTenantAccessTokenInternal(true). You can then access the token via bot.TenantAccessToken().

    // Auto-renewable
    bot := lark.NewChatBot(appID, appSecret)
    bot.StartHeartbeat()
    
    // Single-pass
    resp, err := bot.GetTenantAccessTokenInternal(true)
    token := bot.TenantAccessToken()
  3. Construct complex messages with MsgBuffer

    main

    For simple messages, use direct methods like PostText, PostImage, or ReplyMessage. For complex messages, use MsgBuffer to chain construction before calling PostMessage.

    Supported Message Types

    • MsgText: Text
    • MsgPost: Rich Text
    • MsgInteractive: Interactive Cards (supports Card or Template)
    • MsgShareUser: User Card
    • MsgShareCard: Group Card
    • MsgImage, MsgFile, MsgAudio, MsgMedia, MsgSticker: Media types (requires prior upload to Lark/Feishu servers)

    MsgBuffer Bind Functions (Targeting)

    Use these to specify who receives the message:

    • BindChatID, BindOpenID, BindUserID, BindUnionID, BindEmail, BindReply (for replies).

    MsgBuffer Content Functions

    These are type-specific:

    • Text (for MsgText)
    • Post (for MsgPost)
    • Card / Template (for MsgInteractive)
    • ShareChat (for MsgShareCard)
    • ShareUser (for MsgShareUser)
    • Image, File, Audio, Media, Sticker (for media types)
  4. Extend go-lark with custom APIs

    main

    You can extend go-lark to support new Lark Open Platform APIs by leveraging its existing infrastructure for authentication and HTTP handling. Use the bot.PostAPIRequest method to implement new functionality.

    To implement a custom API:

    1. Define the API URL pattern.
    2. Define response structures that embed lark.BaseResponse.
    3. Use bot.PostAPIRequest to execute the request, passing the context, a name for the operation, the URL, a boolean indicating if it's a POST request, the request body, and a pointer to your response object.
    package lark
    
    import "github.com/go-lark/lark/v2"
    
    const copyFileAPIPattern = "/open-apis/drive/explorer/v2/file/copy/files/%s"
    
    type CopyFileResponse struct {
    	lark.BaseResponse
    	Data CopyFileData `json:"data"`
    }
    
    type CopyFileData struct {
    	FolderToken string `json:"folderToken"`
    	Revision    int64  `json:"revision"`
    	Token       string `json:"token"`
    	Type        string `json:"type"`
    	URL         string `json:"url"`
    }
    
    func CopyFile(ctx context.Context, bot *lark.Bot, fileToken, dstFolderToken, dstName string) (*CopyFileResponse, error) {
    	var respData CopyFileResponse
    	err := bot.PostAPIRequest(
    		ctx,
    		"CopyFile",
    		fmt.Sprintf(copyFileAPIPattern, fileToken),
    		true,
    		map[string]interface{}{
    			"type":             "doc",
    			"dstFolderToken":   dstFolderToken,
    			"dstName":          dstName,
    			"permissionNeeded": true,
    			"CommentNeeded":    false,
    		},
    		&respData,
    	)
    	return &respData, err
    }
  5. Manage Tenant Access Token authentication

    main

    go-lark v2 enables automatic token renewal by default. You can call APIs directly without manual intervention.

    Manual Authentication: Use GetTenantAccessTokenInternal(ctx) to retrieve the token.

    Disabling Auto-Renew:

    • At creation: lark.WithAutoRenew(false)
    • At runtime: bot.SetAutoRenew(false)

    Note: If auto-renew is disabled and no token is pre-set, API calls will return ErrTenantAccessTokenEmpty.

    // Manual retrieval
    resp, err := bot.GetTenantAccessTokenInternal(ctx)
    // Access value via resp.TenantAccessToken
  6. Manage Authentication (Access Tokens)

    main

    The SDK supports two authentication modes:

    1. Automatic Renewal: Call bot.StartHeartbeat() to periodically renew the access token in the background. Use bot.StopHeartbeat() to stop it.
    2. Single Authorization: Manually fetch a token using bot.GetTenantAccessTokenInternal(true). You can then access the value via bot.TenantAccessToken().
    // Automatic renewal
    bot := lark.NewChatBot(appID, appSecret)
    bot.StartHeartbeat()
    
    // Single authorization
    bot := lark.NewChatBot(appID, appSecret)
    resp, err := bot.GetTenantAccessTokenInternal(true)
    token := bot.TenantAccessToken()
  7. Secure events with Token Verification and AES Encryption

    main

    To ensure messages come from the Lark platform, use Token Verification. If you are not using HTTPS, you should also enable AES encryption.

    // Enable both
    middleware.WithTokenVerfication("<verification-token>")
    middleware.WithEncryption("<encryption-key>")
    middleware.WithTokenVerfication("<verification-token>")
    middleware.WithEncryption("<encryption-key>")
  8. Quick Start: Initialize and send messages

    main

    go-lark supports two types of bots: Chat Bots (requiring App ID and App Secret) and Notification Bots (requiring a Webhook URL).

    Chat Bot Example

    Use lark.NewChatBot to initialize. It is recommended to call StartHeartbeat() to handle automatic token renewal.

    Notification Bot Example

    Use lark.NewNotificationBot with a Webhook URL. Use MsgBuffer to construct the message body.

    import "github.com/go-lark/lark"
    
    // Chat Bot
    func main() {
        bot := lark.NewChatBot("<App ID>", "<App Secret>")
        bot.StartHeartbeat()
        bot.PostText("hello, world", lark.WithEmail("someone@example.com"))
    }
    
    // Notification Bot
    func main() {
        bot := lark.NewNotificationBot("<WEB HOOK URL>")
        bot.PostNotificationV2(lark.NewMsgBuffer(lark.MsgText).Text("hello, world").Build())
    }
  9. Configure environment variables for local testing

    main

    When developing or running tests locally, go-lark uses godotenv to load configuration. You must create a .env file in your code directory containing the following environment variables:

    • LARK_APP_ID (Required)
    • LARK_APP_SECRET (Required)
    • LARK_USER_EMAIL (Optional)
    • LARK_USER_ID (Optional)
    • LARK_UNION_ID (Optional)
    • LARK_OPEN_ID (Optional)
    • LARK_CHAT_ID (Optional)
    • LARK_WEBHOOK_V2 (Optional)
    • LARK_WEBHOOK_V2_SIGNED (Optional)
    LARK_APP_ID=your_app_id
    LARK_APP_SECRET=your_app_secret
    # ... other optional variables
  10. Handle Events with Gin Middleware

    main

    To receive events (like messages or URL challenges) in a Gin web server, use the lark-gin middleware.

    URL Challenge

    Required for verifying your webhook URL with Lark.

    Event V2

    Lark's current standard for new bots. Use LarkEventHandler() to register the handler and GetEvent(c) to extract the event data.

    Card Callback

    To handle interactions from interactive cards (e.g., button clicks), use LarkCardHandler() and GetCardCallback(c).

    r := gin.Default()
    middleware := larkgin.NewLarkMiddleware()
    
    // 1. Handle URL Challenge
    middleware.BindURLPrefix("/handle")
    r.Use(middleware.LarkChallengeHandler())
    
    // 2. Handle Event V2
    r.Use(middleware.LarkEventHandler())
    r.POST("/", func(c *gin.Context) {
        if evt, ok := middleware.GetEvent(c); ok {
            if evt.Header.EventType == lark.EventTypeMessageReceived {
                if msg, err := evt.GetMessageReceived(); err == nil {
                    fmt.Println(msg.Message.Content)
                }
            }
        }
    })
    
    // 3. Handle Card Callbacks
    r.Use(middleware.LarkCardHandler())
    r.POST("/callback", func(c *gin.Context) {
        if card, ok := middleware.GetCardCallback(c); ok {
            // Handle card action
        }
    })
  11. Initialize a ChatBot or NotificationBot

    main

    The SDK supports two types of bots:

    1. ChatBot: Created via the Feishu or Lark Developer platforms. Requires an App ID and App Secret.
    2. NotificationBot: Created via a group chat Webhook. Requires a WebHook URL.

    ChatBot Example

    bot := lark.NewChatBot("<App ID>", "<App Secret>")
    bot.PostText(context.Background(), "hello, world", lark.WithEmail("someone@example.com"))

    NotificationBot Example

    bot := lark.NewNotificationBot("<WEB HOOK URL>")
    bot.PostNotification(context.Background(), lark.NewMsgBuffer(lark.MsgText).Text("hello, world").Build())
    import (
        "context"
        "github.com/go-lark/lark/v2"
    )
    
    func main() {
        // ChatBot
        bot := lark.NewChatBot("<App ID>", "<App Secret>")
        bot.PostText(context.Background(), "hello, world", lark.WithEmail("someone@example.com"))
    
        // NotificationBot
        nBot := lark.NewNotificationBot("<WEB HOOK URL>")
        nBot.PostNotification(context.Background(), lark.NewMsgBuffer(lark.MsgText).Text("hello, world").Build())
    }