### Install go-lark SDK Source: https://github.com/go-lark/lark/blob/main/v2/README.md Install the go-lark SDK using go get. ```shell go get github.com/go-lark/lark/v2 ``` -------------------------------- ### Install go-lark SDK Source: https://github.com/go-lark/lark/blob/main/_autodocs/README.md Install the go-lark SDK using go get. Ensure you are using Go version 1.13 or later. ```bash go get github.com/go-lark/lark ``` -------------------------------- ### Batch Get User Info by Email Example Source: https://github.com/go-lark/lark/blob/main/_autodocs/api-reference/contact-management.md Retrieves information for multiple users by their email addresses. Supports up to 50 users per request. ```go // Batch query by email resp, err := bot.BatchGetUserInfo(lark.UIDEmail, "user1@example.com", "user2@example.com", "user3@example.com", ) if err != nil { log.Fatal(err) } for _, user := range resp.Data.Items { fmt.Printf("User: %s (%s)\n", user.Name, user.Email) } ``` -------------------------------- ### UploadImage Example Source: https://github.com/go-lark/lark/blob/main/_autodocs/api-reference/file-upload.md Example of uploading an image from a file path and using the returned image key in a message. ```go resp, err := bot.UploadImage("/path/to/image.png") if err != nil { log.Fatal(err) } imageKey := resp.Data.ImageKey fmt.Printf("Image uploaded: %s\n", imageKey) // Use in message mb := lark.NewMsgBuffer(lark.MsgImage). BindChatID("oc_xyz789"). Image(imageKey) bot.PostMessage(mb.Build()) ``` -------------------------------- ### UploadFile Example: Upload from File Path Source: https://github.com/go-lark/lark/blob/main/_autodocs/api-reference/file-upload.md Example of uploading a file by specifying its local path. Requires FileType and FileName. ```go resp, err := bot.UploadFile(lark.UploadFileRequest{ FileType: "pdf", FileName: "report.pdf", Path: "/path/to/report.pdf", }) if err != nil { log.Fatal(err) } fileKey := resp.Data.FileKey fmt.Printf("File uploaded: %s\n", fileKey) ``` -------------------------------- ### Initialize and Use ChatBot Source: https://github.com/go-lark/lark/blob/main/_autodocs/README.md Create a ChatBot instance with your app credentials and start automatic token renewal. This example demonstrates sending a simple text message to a user via email. ```go package main import ( "log" "github.com/go-lark/lark" ) func main() { // Create bot with app credentials bot := lark.NewChatBot("your_app_id", "your_app_secret") // Start automatic token renewal if err := bot.StartHeartbeat(); err != nil { log.Fatal(err) } defer bot.StopHeartbeat() // Send a simple text message resp, err := bot.PostText("Hello, world!", lark.WithEmail("user@example.com")) if err != nil { log.Fatal(err) } log.Printf("Message sent: %s", resp.Data.MessageID) } ``` -------------------------------- ### Get User Info Example Source: https://github.com/go-lark/lark/blob/main/_autodocs/api-reference/contact-management.md Retrieves and prints information for a single user. Requires a valid user identifier. ```go resp, err := bot.GetUserInfo(lark.WithEmail("user@example.com")) if err != nil { log.Fatal(err) } user := resp.Data.User fmt.Printf("Name: %s\n", user.Name) fmt.Printf("Email: %s\n", user.Email) fmt.Printf("Job Title: %s\n", user.JobTitle) fmt.Printf("Avatar (72): %s\n", user.Avatar.Avatar72) ``` -------------------------------- ### Batch Get User Info by User ID Example Source: https://github.com/go-lark/lark/blob/main/_autodocs/api-reference/contact-management.md Retrieves information for multiple users by their unique user IDs. Supports up to 50 users per request. ```go resp, err := bot.BatchGetUserInfo(lark.UIDUserID, "ou_user1", "ou_user2", ) if err != nil { log.Fatal(err) } for _, user := range resp.Data.Items { fmt.Printf("User: %s\n", user.Name) } ``` -------------------------------- ### UploadFile Example: Upload from Reader Source: https://github.com/go-lark/lark/blob/main/_autodocs/api-reference/file-upload.md Example of uploading a file using an io.Reader, suitable for in-memory data or streams. Requires FileType and FileName. ```go file, err := os.Open("/path/to/video.mp4") if err != nil { log.Fatal(err) } defer file.Close() resp, err := bot.UploadFile(lark.UploadFileRequest{ FileType: "mp4", FileName: "presentation.mp4", Duration: 120, // 2 minutes Reader: file, }) if err != nil { log.Fatal(err) } fileKey := resp.Data.FileKey ``` -------------------------------- ### UploadFile Example: Upload and Send in Message Source: https://github.com/go-lark/lark/blob/main/_autodocs/api-reference/file-upload.md Demonstrates uploading a file and then immediately sending it as a message. Requires FileType, FileName, and Path. ```go // Upload uploadResp, err := bot.UploadFile(lark.UploadFileRequest{ FileType: "pdf", FileName: "contract.pdf", Path: "/tmp/contract.pdf", }) if err != nil { log.Fatal(err) } // Send message with file mb := lark.NewMsgBuffer(lark.MsgFile). BindChatID("oc_xyz789"). File(uploadResp.Data.FileKey) resp, err := bot.PostMessage(mb.Build()) ``` -------------------------------- ### UploadImageObject Example Source: https://github.com/go-lark/lark/blob/main/_autodocs/api-reference/file-upload.md Example of uploading an image from an image.Image object. The image is encoded as JPEG. ```go // Create or load an image var img image.Image // ... populate img ... resp, err := bot.UploadImageObject(img) if err != nil { log.Fatal(err) } imageKey := resp.Data.ImageKey // Use imageKey in messages ``` -------------------------------- ### Initialize and Use NotificationBot Source: https://github.com/go-lark/lark/blob/main/_autodocs/README.md Create a NotificationBot instance using a webhook URL. This example shows how to send a text message using a message buffer. ```go package main import ( "log" "github.com/go-lark/lark" ) func main() { // Create notification bot with webhook URL bot := lark.NewNotificationBot("https://open.feishu.cn/open-apis/bot/v2/hook/...") // Send message via webhook mb := lark.NewMsgBuffer(lark.MsgText).Text("Hello from notification bot!") resp, err := bot.PostNotificationV2(mb.Build()) if err != nil { log.Fatal(err) } if resp.Code != 0 { log.Printf("Error: %s", resp.Msg) } } ``` -------------------------------- ### Start Authentication Heartbeat Source: https://github.com/go-lark/lark/blob/main/_autodocs/configuration.md Initiate the heartbeat for authentication and handle potential errors. Ensure to defer stopping the heartbeat. ```go if err := bot.StartHeartbeat(); err != nil { log.Fatal(err) } def bot.StopHeartbeat() ``` -------------------------------- ### Image Message to User Pattern Source: https://github.com/go-lark/lark/blob/main/_autodocs/api-reference/file-upload.md Example of uploading an image and then sending it in a message to a specific user via email. Requires the image path. ```go // Upload image uploadResp, err := bot.UploadImage("/downloads/screenshot.png") if err != nil { log.Fatal(err) } // Send message with image resp, err := bot.PostImage(uploadResp.Data.ImageKey, lark.WithEmail("user@example.com")) if err != nil { log.Fatal(err) } fmt.Println("Image message sent:", resp.Data.MessageID) ``` -------------------------------- ### Get User Info by Email Source: https://github.com/go-lark/lark/blob/main/_autodocs/api-reference/contact-management.md Fetches detailed information about a user when their email address is provided. Requires the 'bot' object to be initialized. ```go resp, err := bot.GetUserInfo(lark.WithEmail("john.doe@example.com")) if err != nil { log.Fatal(err) } user := resp.Data.User fmt.Printf("User: %s\n", user.Name) fmt.Printf("Job: %s\n", user.JobTitle) fmt.Printf("Departments: %v\n", user.DepartmentIDs) ``` -------------------------------- ### Full Bot Configuration Source: https://github.com/go-lark/lark/blob/main/_autodocs/configuration.md Customize all aspects of the bot, including HTTP client, domain, logger, context, and user ID type for comprehensive setup. ```go // HTTP client customHTTPClient := &http.Client{ Timeout: 20 * time.Second, Transport: &http.Transport{ MaxIdleConns: 10, }, } // Context ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) def cancel() // Logger customLogger := setupLogger() // Bot setup bot := lark.NewChatBot(appID, appSecret) bot.SetClient(customHTTPClient) bot.SetDomain(lark.DomainLark) bot.SetLogger(customLogger) bot.WithContext(ctx) bot.WithUserIDType(lark.UIDEmail) // Start auth if err := bot.StartHeartbeat(); err != nil { log.Fatal(err) } defer bot.StopHeartbeat() ``` -------------------------------- ### Start Automatic Token Renewal (Heartbeat) Source: https://github.com/go-lark/lark/blob/main/_autodocs/api-reference/authentication.md Starts a background goroutine for automatic token renewal with a default interval adjustment. Blocks until the initial token is obtained. ```go func (bot *Bot) StartHeartbeat() error ``` ```go bot := lark.NewChatBot(appID, appSecret) if err := bot.StartHeartbeat(); err != nil { log.Fatal(err) } defer bot.StopHeartbeat() // Token is automatically renewed in background // Access it anytime with bot.TenantAccessToken() ``` -------------------------------- ### Get Tenant Access Token Source: https://github.com/go-lark/lark/blob/main/_autodocs/api-reference/bot-initialization.md Retrieves the current tenant access token for the bot. ```go bot.TenantAccessToken() ``` -------------------------------- ### Create Post with Image and Link Source: https://github.com/go-lark/lark/blob/main/_autodocs/api-reference/message-builders.md Build a post message that includes an image and a link. First, upload the image to get its key, then use PostBuilder to add text, image, and link tags. Ensure the Lark client is initialized. ```go uploadResp, _ := bot.UploadImage("/path/to/screenshot.png") pb := lark.NewPostBuilder(). Title("New Feature Release"). TextTag("Check out our new dashboard:", 1, false). ImageTag(uploadResp.Data.ImageKey, 400, 300). LinkTag("Learn more", "https://example.com/features") mb := lark.NewMsgBuffer(lark.MsgPost). BindChatID("oc_xyz789"). Post(pb.Render()) resp, err := bot.PostMessage(mb.Build()) ``` -------------------------------- ### Upload Document for File Sharing Source: https://github.com/go-lark/lark/blob/main/_autodocs/api-reference/file-upload.md Uploads a document (PDF) and sends it as a file message to a specified chat. This example also shows sending a preceding text message for context. ```go uploadResp, err := bot.UploadFile(lark.UploadFileRequest{ FileType: "pdf", FileName: "quarterly_report.pdf", Path: "/reports/q3_2024.pdf", }) if err != nil { log.Fatal(err) } // Send to group mb := lark.NewMsgBuffer(lark.MsgFile). BindChatID("oc_xyz789"). File(uploadResp.Data.FileKey) // Send with text context textMb := lark.NewMsgBuffer(lark.MsgText). BindChatID("oc_xyz789"). Text("Here's the Q3 report") bot.PostMessage(textMb.Build()) // Then send the file bot.PostMessage(mb.Build()) ``` -------------------------------- ### Implement Lark Doc API: CopyFile Source: https://github.com/go-lark/lark/blob/main/README.md Example of extending Go-Lark to implement a Lark Doc API function, specifically for copying files. This demonstrates using PostAPIRequest for custom API calls. ```go package lark import "github.com/go-lark/lark" const copyFileAPIPattern = "/open-apis/drive/explorer/v2/file/copy/files/%s" // CopyFileResponse . type CopyFileResponse struct { lark.BaseResponse Data CopyFileData `json:"data"` } // CopyFileData . type CopyFileData struct { FolderToken string `json:"folderToken"` Revision int64 `json:"revision"` Token string `json:"token"` Type string `json:"type"` URL string `json:"url"` } // CopyFile implementation func CopyFile(bot *lark.Bot, fileToken, dstFolderToken, dstName string) (*CopyFileResponse, error) { var respData model.CopyFileResponse err := bot.PostAPIRequest( "CopyFile", fmt.Sprintf(copyFileAPIPattern, fileToken), true, map[string]interface{}{ "type": "doc", "dstFolderToken": dstFolderToken, "dstName": dstName, "permissionNeeded": true, "CommentNeeded": false, }, &respData, ) return &respData, err } ``` -------------------------------- ### ErrMessageNotBuild Example Source: https://github.com/go-lark/lark/blob/main/_autodocs/errors.md This error occurs when a message is built without the required content. Ensure all necessary content fields are set before building the message. ```go var ErrMessageNotBuild = errors.New("Message not build") // Message with no content mb := lark.NewMsgBuffer(lark.MsgText).BindChatID("oc_xyz789") // Forgot to call .Text() _, err := bot.PostMessage(mb.Build()) if err == lark.ErrMessageNotBuild { log.Println("Message content not set") } ``` -------------------------------- ### Batch Get Multiple Users by Email Source: https://github.com/go-lark/lark/blob/main/_autodocs/api-reference/contact-management.md Retrieves information for multiple users simultaneously by providing their email addresses. This is more efficient than individual calls for several users. Requires the 'bot' object. ```go // Get information for a team resp, err := bot.BatchGetUserInfo(lark.UIDEmail, "alice@example.com", "bob@example.com", "charlie@example.com", ) if err != nil { log.Fatal(err) } // Process results for _, user := range resp.Data.Items { fmt.Printf("%s - %s (%s)\n", user.Name, user.JobTitle, user.Email) } ``` -------------------------------- ### Implementing Lark Doc API: CopyFile Extension Source: https://github.com/go-lark/lark/blob/main/v2/README.md An example of extending go-lark to implement a Lark Doc API function, specifically copying a file. It defines request/response structures and the API call logic. ```go package lark import "github.com/go-lark/lark/v2" const copyFileAPIPattern = "/open-apis/drive/explorer/v2/file/copy/files/%s" // CopyFileResponse . type CopyFileResponse struct { lark.BaseResponse Data CopyFileData `json:"data"` } // CopyFileData . type CopyFileData struct { FolderToken string `json:"folderToken"` Revision int64 `json:"revision"` Token string `json:"token"` Type string `json:"type"` URL string `json:"url"` } // CopyFile implementation func CopyFile(ctx context.Context, bot *lark.Bot, fileToken, dstFolderToken, dstName string) (*CopyFileResponse, error) { var respData model.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 } ``` -------------------------------- ### Check for Input Limit Exceeded Error Source: https://github.com/go-lark/lark/blob/main/_autodocs/errors.md This example demonstrates how to catch errors when the input limit for BatchGetUserInfo is exceeded. The method accepts between 1 and 50 user IDs; providing more than 50 will trigger this error. ```go // Too many IDs var ids []string for i := 0; i < 51; i++ { ids = append(ids, fmt.Sprintf("ou_%d", i)) } _, err := bot.BatchGetUserInfo(lark.UIDOpenID, ids...) if err == lark.ErrParamExceedInputLimit { log.Println("Too many user IDs (max 50)") } ``` -------------------------------- ### Get User Departments and Manager Info Source: https://github.com/go-lark/lark/blob/main/_autodocs/api-reference/contact-management.md Retrieves a user's department IDs and their manager's UserID. It then uses the manager's UserID to fetch the manager's name. Requires the 'bot' object. ```go resp, err := bot.GetUserInfo(lark.WithEmail("user@example.com")) if err != nil { log.Fatal(err) } user := resp.Data.User fmt.Printf("User %s belongs to departments: %v\n", user.Name, user.DepartmentIDs) // Get manager information if user.LeaderUserID != "" { managerResp, _ := bot.GetUserInfo(lark.WithUserID(user.LeaderUserID)) fmt.Printf("Manager: %s\n", managerResp.Data.User.Name) } ``` -------------------------------- ### Handling Common HTTP Errors in Go Source: https://github.com/go-lark/lark/blob/main/_autodocs/errors.md Standard Go HTTP errors can occur from any API method. This example shows how to check for timeouts and other generic HTTP errors. ```go _, err := bot.PostText("Test", lark.WithEmail("test@example.com")) if err != nil { // Check for timeout if os.IsTimeout(err) { log.Println("Request timed out") } // Generic HTTP error log.Printf("HTTP error: %v", err) } ``` -------------------------------- ### Configure ChatBot with Options Source: https://github.com/go-lark/lark/blob/main/v2/README.md Initialize a ChatBot with various configuration options, including custom HTTP client and logger. ```go bot := lark.NewChatBot( "", "", lark.WithDomain(lark.DomainLark), lark.WithAutoRenew(false), lark.WithUserIDType(lark.UIDOpenID), lark.WithHTTPClient(myHTTPClient), lark.WithLogger(myLogger), ) ``` -------------------------------- ### Handle Lark Card Callbacks Source: https://github.com/go-lark/lark/blob/main/_autodocs/api-reference/events.md Process callbacks from Lark cards by inspecting the `callback.Action.Tag`. This example covers handling button clicks, static select options, and datepicker selections. ```go func handleCardCallback(callback lark.EventCardCallback) { switch callback.Action.Tag { case "button": fmt.Printf("Button clicked by %s\n", callback.OpenID) case "select_static": fmt.Printf("Option selected: %s\n", callback.Action.Option) case "datepicker": fmt.Printf("Date selected (timezone: %s)\n", callback.Action.Timezone) } } ``` -------------------------------- ### Minimal Bot Configuration Source: https://github.com/go-lark/lark/blob/main/_autodocs/configuration.md Demonstrates the minimal configuration for a bot instance using default settings. This is suitable for simple use cases. ```go bot := lark.NewChatBot(appID, appSecret) bot.StartHeartbeat() // Use with Feishu endpoint, 5s timeout, stderr logging ``` -------------------------------- ### Configure HTTP Client (Optional) Source: https://github.com/go-lark/lark/blob/main/_autodocs/configuration.md Set a custom HTTP client for the bot if default settings are insufficient. ```go bot.SetClient(customClient) ``` -------------------------------- ### Create ChatBot Instance Source: https://github.com/go-lark/lark/blob/main/_autodocs/api-reference/bot-initialization.md Initializes a new ChatBot for app-based authentication using your application ID and secret. ```go bot := lark.NewChatBot("your_app_id", "your_app_secret") ``` -------------------------------- ### Start and Stop Heartbeat for Token Renewal Source: https://github.com/go-lark/lark/blob/main/_autodocs/configuration.md Starts the heartbeat to automatically renew the access token. The renewal interval is calculated based on token expiration, with a minimum of 10 seconds. Ensure to stop the heartbeat when done. ```go bot := lark.NewChatBot(appID, appSecret) if err := bot.StartHeartbeat(); err != nil { log.Fatal(err) } // Token renewed every (expires_in - 20) seconds, minimum 10s defer bot.StopHeartbeat() ``` -------------------------------- ### Get Chat Source: https://github.com/go-lark/lark/blob/main/_autodocs/api-reference/chat-management.md Retrieves information about a specific chat. ```APIDOC ## Get Chat ### Description Retrieves information about a specific chat. ### Method GET ### Endpoint /open-apis/im/v1/chats/{chat_id}?user_id_type={uid_type} ``` -------------------------------- ### Build and Send Media Message using MsgBuffer Source: https://github.com/go-lark/lark/blob/main/v2/README.md Create a media message using `MsgBuffer` and send it with `PostMessage`. The `Media` content function requires a media key obtained from prior upload. ```go buffer := lark.NewMsgBuffer() buffer.BindChatID("") buffer.Media(&lark.MsgMedia{MediaID: ""}) bot.PostMessage(ctx, buffer.Build()) ``` -------------------------------- ### Get Members Source: https://github.com/go-lark/lark/blob/main/_autodocs/api-reference/chat-management.md Retrieves a list of members in a specified chat. ```APIDOC ## Get Members ### Description Retrieves a list of members in a specified chat. ### Method GET ### Endpoint /open-apis/im/v1/chats/{chat_id}/members?member_id_type={id_type} ``` -------------------------------- ### Create Default Bot Instance Source: https://github.com/go-lark/lark/blob/main/_autodocs/configuration.md Initializes a new chat bot with application ID and secret. The default HTTP client has a 5-second timeout. ```go bot := lark.NewChatBot(appID, appSecret) // Default client: 5s timeout ``` -------------------------------- ### Get Application ID Source: https://github.com/go-lark/lark/blob/main/_autodocs/api-reference/bot-initialization.md Retrieves the application ID associated with the bot. ```go bot.AppID() ``` -------------------------------- ### Get Logger Instance Source: https://github.com/go-lark/lark/blob/main/_autodocs/api-reference/bot-initialization.md Retrieves the current logger instance being used by the bot. ```go bot.Logger() ``` -------------------------------- ### Create New Post Builder Source: https://github.com/go-lark/lark/blob/main/_autodocs/api-reference/message-builders.md Initializes a new MsgPostBuilder instance for constructing rich text posts. ```go pb := lark.NewPostBuilder() ``` -------------------------------- ### Set up .env for Local Testing Source: https://github.com/go-lark/lark/blob/main/README.md Configure local testing by creating a .env file with necessary Lark API credentials and identifiers. Ensure LARK_APP_ID and LARK_APP_SECRET are provided. ```bash LARK_APP_ID LARK_APP_SECRET LARK_USER_EMAIL LARK_USER_ID LARK_UNION_ID LARK_OPEN_ID LARK_CHAT_ID LARK_WEBHOOK_V2 LARK_WEBHOOK_V2_SIGNED ``` -------------------------------- ### Get App Access Token Source: https://github.com/go-lark/lark/blob/main/_autodocs/api-reference/bot-initialization.md Retrieves the current app access token for the bot. ```go bot.AccessToken() ``` -------------------------------- ### Get Current API Domain Source: https://github.com/go-lark/lark/blob/main/_autodocs/api-reference/bot-initialization.md Retrieves the current API domain used by the bot. ```go bot.Domain() ``` -------------------------------- ### Custom Logging and Context for Observability Source: https://github.com/go-lark/lark/blob/main/_autodocs/configuration.md Integrate custom logging and a context with a timeout for production deployments requiring enhanced observability. ```go ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) def cancel() customLogger := setupLogger() bot := lark.NewChatBot(appID, appSecret) bot.SetLogger(customLogger) bot.WithContext(ctx) bot.StartHeartbeat() ``` -------------------------------- ### StopHeartbeat Source: https://github.com/go-lark/lark/blob/main/_autodocs/api-reference/authentication.md Stops the automatic token renewal heartbeat. This method is safe to call even if the heartbeat has not been started. ```APIDOC ## StopHeartbeat ### Description Stops the automatic token renewal heartbeat. ChatBot only. ### Method `StopHeartbeat` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```go bot.StartHeartbeat() // ... do work ... bot.StopHeartbeat() ``` ### Response #### Success Response (200) None ### Behavior - Non-blocking send on heartbeat channel - Background renewal goroutine exits - Safe to call even if heartbeat not started ``` -------------------------------- ### Build and Send File Message using MsgBuffer Source: https://github.com/go-lark/lark/blob/main/v2/README.md Create a file message using `MsgBuffer` and send it with `PostMessage`. The `File` content function requires a file key obtained from prior upload. ```go buffer := lark.NewMsgBuffer() buffer.BindChatID("") buffer.File("") bot.PostMessage(ctx, buffer.Build()) ``` -------------------------------- ### Get Bot Type Source: https://github.com/go-lark/lark/blob/main/_autodocs/api-reference/bot-initialization.md Retrieves the type of the bot, indicating whether it is a ChatBot (0) or NotificationBot (1). ```go bot.BotType() ``` -------------------------------- ### Get Chat Information Source: https://github.com/go-lark/lark/blob/main/_autodocs/api-reference/chat-management.md Retrieves information about a specific chat using its ID. Ensure you have the correct chat ID. ```Go resp, err := bot.GetChat("oc_xyz789") if err != nil { log.Fatal(err) } fmt.Printf("Chat: %s (%d members)\n", resp.Data.Name, len(resp.Data.Members)) ``` -------------------------------- ### Create NotificationBot Instance Source: https://github.com/go-lark/lark/blob/main/_autodocs/api-reference/bot-initialization.md Initializes a new NotificationBot for webhook-based messaging using a provided webhook URL. ```go bot := lark.NewNotificationBot("https://open.feishu.cn/open-apis/bot/v2/hook/...") ``` -------------------------------- ### ErrMessageType Example Source: https://github.com/go-lark/lark/blob/main/_autodocs/errors.md This error is returned when UpdateMessage is called with an unsupported message type. Only MsgText, MsgPost, and MsgInteractive are supported for updates. ```go var ErrMessageType = errors.New("Message type error") // Cannot update image message mb := lark.NewMsgBuffer(lark.MsgImage). BindChatID("oc_xyz789"). Image("key") _, err := bot.UpdateMessage("om_msg_id", mb.Build()) if err == lark.ErrMessageType { log.Println("Cannot update image messages") } ``` -------------------------------- ### Batch Get User Info Source: https://github.com/go-lark/lark/blob/main/_autodocs/api-reference/contact-management.md Retrieves information for multiple users in a single request. Users can be specified by their email addresses. ```APIDOC ## GET /open-apis/contact/v3/users/batch?user_id_type={id_type}&user_ids={ids} ### Description Retrieves information for multiple users in a single request. Users can be specified by their email addresses or other user ID types. ### Method GET ### Endpoint /open-apis/contact/v3/users/batch?user_id_type={id_type}&user_ids={ids} ### Parameters #### Query Parameters - **user_id_type** (string) - Required - The type of user IDs provided (e.g., `email`, `user_id`, `open_id`, `chat_id`, `union_id`). - **user_ids** (string) - Required - A comma-separated list of user IDs. ### Request Example ```json { "example": "GET /open-apis/contact/v3/users/batch?user_id_type=email&user_ids=alice@example.com,bob@example.com,charlie@example.com" } ``` ### Response #### Success Response (200) - **Data** (object) - Contains a list of user information. - **Items** (array) - A list of user objects. - Each object contains user details similar to the 'Get User Info' endpoint. #### Response Example ```json { "example": { "data": { "items": [ { "open_id": "ou_abc123", "email": "alice@example.com", "user_id": "ou_12345", "name": "Alice", "job_title": "Developer", "department_ids": ["d1"] }, { "open_id": "ou_def456", "email": "bob@example.com", "user_id": "ou_67890", "name": "Bob", "job_title": "Designer", "department_ids": ["d2"] } ] } } } ``` ``` -------------------------------- ### Configure Context (Optional) Source: https://github.com/go-lark/lark/blob/main/_autodocs/configuration.md Provide a context to the bot, useful for managing request lifecycles and cancellations. ```go bot.WithContext(ctx) ``` -------------------------------- ### Get Element Count Source: https://github.com/go-lark/lark/blob/main/_autodocs/api-reference/message-builders.md Returns the number of elements currently in the post for the active locale. Note that the title is counted separately. ```go pb := lark.NewPostBuilder().Title("Title").TextTag("A", 1, false).TextTag("B", 1, false) fmt.Println(pb.Len()) // Output: 2 (title is separate) ``` -------------------------------- ### Bot Initialization Source: https://github.com/go-lark/lark/blob/main/_autodocs/INDEX.md Defines bot types and provides constructors and configuration methods for creating and setting up bots. ```APIDOC ## Bot Initialization ### Description Provides constructors for creating ChatBot and NotificationBot instances, along with methods for configuring their behavior, such as setting the client, domain, logger, and context. ### Constructors - `NewChatBot()` - `NewNotificationBot()` ### Configuration Methods - `SetClient(client *http.Client)` - `SetDomain(domain string)` - `SetLogger(logger *log.Logger)` - `WithContext(ctx context.Context)` ### Accessor Methods - `Domain() string` - `TenantAccessToken() string` - `BotType() string` ``` -------------------------------- ### StartHeartbeat Source: https://github.com/go-lark/lark/blob/main/_autodocs/api-reference/authentication.md Starts automatic token renewal with a default 10-second interval adjustment. This method is for ChatBots only and will block until the initial token is obtained. ```APIDOC ## StartHeartbeat ### Description Starts automatic token renewal with default 10-second interval adjustment. ChatBot only. ### Method `StartHeartbeat` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```go bot := lark.NewChatBot(appID, appSecret) if err := bot.StartHeartbeat(); err != nil { log.Fatal(err) } defer bot.StopHeartbeat() // Token is automatically renewed in background // Access it anytime with bot.TenantAccessToken() ``` ### Response #### Success Response (200) None (returns error) ### Error Cases - `ErrBotTypeError` — if called on NotificationBot - HTTP errors when fetching initial token ### Behavior - Blocks until initial token is obtained - Spawns background goroutine for periodic renewal - Adjusts interval based on token expiration time (expires_in - 20 seconds) - Falls back to 10 second default if adjustment fails ``` -------------------------------- ### Build and Send Audio Message using MsgBuffer Source: https://github.com/go-lark/lark/blob/main/v2/README.md Construct an audio message using `MsgBuffer` and send it via `PostMessage`. The `Audio` content function requires an audio key obtained from prior upload. ```go buffer := lark.NewMsgBuffer() buffer.BindChatID("") buffer.Audio("") bot.PostMessage(ctx, buffer.Build()) ``` -------------------------------- ### Set Domain (Optional) Source: https://github.com/go-lark/lark/blob/main/_autodocs/configuration.md Specify the domain if you are using Lark instead of Feishu. ```go bot.SetDomain(lark.DomainLark) // if using Lark ``` -------------------------------- ### Get Current Locale Buffer Source: https://github.com/go-lark/lark/blob/main/_autodocs/api-reference/message-builders.md Retrieves the current locale's buffer without altering the locale. Useful for inspecting content. ```go curBuf := pb.CurLocale() fmt.Println(curBuf.Title) ``` -------------------------------- ### Configure Custom HTTP Client Source: https://github.com/go-lark/lark/blob/main/_autodocs/configuration.md Replaces the default HTTP client with a custom one to configure timeout, proxy, or TLS settings. ```go customClient := &http.Client{ Timeout: 30 * time.Second, Transport: &http.Transport{ MaxIdleConns: 100, // Other transport settings }, } bot.SetClient(customClient) ``` -------------------------------- ### Create Bot Instance Source: https://github.com/go-lark/lark/blob/main/_autodocs/configuration.md Initialize a new go-lark ChatBot instance using your application ID and secret. ```go bot := lark.NewChatBot(appID, appSecret) ``` -------------------------------- ### Build and Send Sticker Message using MsgBuffer Source: https://github.com/go-lark/lark/blob/main/v2/README.md Construct a sticker message using `MsgBuffer` and send it via `PostMessage`. The `Sticker` content function requires a sticker ID obtained from prior upload. ```go buffer := lark.NewMsgBuffer() buffer.BindChatID("") buffer.Sticker("") bot.PostMessage(ctx, buffer.Build()) ``` -------------------------------- ### Clear Post Content Source: https://github.com/go-lark/lark/blob/main/_autodocs/api-reference/message-builders.md Clears all existing content from the post builder and resets it to the default locale. Useful for starting a new message from scratch. ```go pb.Title("First Post").TextTag("Content", 1, false) pb.Clear() pb.Title("Second Post") ``` -------------------------------- ### Get Tenant Access Token (Internal) Source: https://github.com/go-lark/lark/blob/main/_autodocs/api-reference/authentication.md Obtains an internal tenant access token. Tenant access tokens are required for most API operations. ```APIDOC ## POST /open-apis/auth/v3/tenant_access_token/internal ### Description Obtains an internal tenant access token. Tenant access tokens are required for most API operations. ### Method POST ### Endpoint /open-apis/auth/v3/tenant_access_token/internal ### Auth Required No ``` -------------------------------- ### Get App Access Token (Internal) Source: https://github.com/go-lark/lark/blob/main/_autodocs/api-reference/authentication.md Obtains an internal app access token. This token is used for specific internal application scenarios. ```APIDOC ## POST /open-apis/auth/v3/app_access_token/internal ### Description Obtains an internal app access token. This token is used for specific internal application scenarios. ### Method POST ### Endpoint /open-apis/auth/v3/app_access_token/internal ### Auth Required No ``` -------------------------------- ### Get Text Element Count Source: https://github.com/go-lark/lark/blob/main/_autodocs/api-reference/message-builders.md Returns the number of distinct text elements (plain text, mentions) currently in the builder's buffer. ```go tb := lark.NewTextBuilder().Text("A").Text("B").Mention("ou_123") fmt.Println(tb.Len()) // Output: 3 ``` -------------------------------- ### Usage Pattern: Single-Shot Token Source: https://github.com/go-lark/lark/blob/main/_autodocs/api-reference/authentication.md Demonstrates obtaining a tenant access token for one-off operations or short-lived processes. The token is then available via bot.TenantAccessToken(). ```go bot := lark.NewChatBot(appID, appSecret) resp, err := bot.GetTenantAccessTokenInternal(true) if err != nil { log.Fatal(err) } // bot.TenantAccessToken() now contains valid token // Use bot for API calls ``` -------------------------------- ### Configure API Domain Source: https://github.com/go-lark/lark/blob/main/_autodocs/configuration.md Sets the API domain for the bot instance. Use DomainFeishu for Feishu or DomainLark for Lark. ```go // Feishu (default) bot.SetDomain(lark.DomainFeishu) // https://open.feishu.cn // Lark bot.SetDomain(lark.DomainLark) // https://open.larksuite.com ``` -------------------------------- ### Build and Send Image Message using MsgBuffer Source: https://github.com/go-lark/lark/blob/main/v2/README.md Construct an image message using `MsgBuffer` and send it via `PostMessage`. The `Image` content function requires an image key obtained from prior upload. ```go buffer := lark.NewMsgBuffer() buffer.BindChatID("") buffer.Image("") bot.PostMessage(ctx, buffer.Build()) ``` -------------------------------- ### Build Simple Text Message to User by Email Source: https://github.com/go-lark/lark/blob/main/_autodocs/api-reference/message-buffer.md Demonstrates a common usage pattern for sending a simple text message to a specific user via email using the MsgBuffer. ```go mb := lark.NewMsgBuffer(lark.MsgText). BindEmail("user@example.com"). Text("Hello, user!") resp, err := bot.PostMessage(mb.Build()) ``` -------------------------------- ### ErrEventTypeNotMatch Example Source: https://github.com/go-lark/lark/blob/main/_autodocs/errors.md This error occurs when the event type in EventV2 does not match the expected type, or when GetMessageReceived is called on a non-message event. Verify the event type before processing. ```go var ErrEventTypeNotMatch = errors.New("Event type not match") var evt lark.EventV2 // evt.Header.EventType = "im.chat.disbanded_v1" msgEvent, err := evt.GetMessageReceived() if err == lark.ErrEventTypeNotMatch { log.Println("Event is not a message received event") } ``` -------------------------------- ### ErrInvalidReceiveID Example Source: https://github.com/go-lark/lark/blob/main/_autodocs/errors.md This error indicates that no recipient was bound in the OutcomingMessage, or all recipient fields are empty. Ensure at least one recipient (e.g., email, user_id) is specified. ```go var ErrInvalidReceiveID = errors.New("Invalid receive ID") // No recipient binding mb := lark.NewMsgBuffer(lark.MsgText).Text("Test") _, err := bot.PostMessage(mb.Build()) if err == lark.ErrInvalidReceiveID { log.Println("No recipient specified (bind email, user_id, etc.)") } ``` -------------------------------- ### ErrUnsupportedUIDType Example Source: https://github.com/go-lark/lark/blob/main/_autodocs/errors.md This error is triggered when PostEphemeralMessage is called with a UnionID type, which is not supported. Use supported UID types like UIDEmail, UIDUserID, UIDOpenID, or UIDChatID. ```go var ErrUnsupportedUIDType = errors.New("Unsupported UID type") mb := lark.NewMsgBuffer(lark.MsgText). BindUnionID("union_123"). Text("Test") _, err := bot.PostEphemeralMessage(mb.Build()) if err == lark.ErrUnsupportedUIDType { log.Println("Ephemeral messages don't support UnionID") } ``` -------------------------------- ### Auto-Renewable Authentication for Chat Bot Source: https://github.com/go-lark/lark/blob/main/README.md Initialize a chat bot with App ID and App Secret, and start its heartbeat to automatically renew the access token periodically. ```go // initialize a chat bot with appID and appSecret bot := lark.NewChatBot(appID, appSecret) // Renew access token periodically bot.StartHeartbeat() // Stop renewal bot.StopHeartbeat() ``` -------------------------------- ### Configure Logger (Optional) Source: https://github.com/go-lark/lark/blob/main/_autodocs/configuration.md Assign a custom logger to the bot for structured logging and observability. ```go bot.SetLogger(customLogger) ``` -------------------------------- ### Get User Avatar URL Source: https://github.com/go-lark/lark/blob/main/_autodocs/api-reference/contact-management.md Retrieves user information using their OpenID and accesses the URL for their avatar. The avatar object contains URLs for different resolutions. ```go resp, err := bot.GetUserInfo(lark.WithOpenID("ou_abc123")) if err != nil { log.Fatal(err) } user := resp.Data.User // Download different sizes of avatar // avatar.Avatar72 - 72x72 pixels // avatar.Avatar240 - 240x240 pixels // avatar.Avatar640 - 640x640 pixels fmt.Printf("Avatar URL: %s\n", user.Avatar.Avatar72) ``` -------------------------------- ### Implement Custom HTTP Wrapper Source: https://github.com/go-lark/lark/blob/main/_autodocs/configuration.md Provides a custom HTTP wrapper for advanced scenarios like request/response logging or custom middleware. The wrapper must implement the Do method. ```go type MyHTTPWrapper struct{} func (w *MyHTTPWrapper) Do(ctx context.Context, method, url string, header http.Header, body io.Reader) (io.ReadCloser, error) { // Custom logic return response, err } bot.SetCustomClient(&MyHTTPWrapper{}) ``` -------------------------------- ### Stop Automatic Token Renewal (Heartbeat) Source: https://github.com/go-lark/lark/blob/main/_autodocs/api-reference/authentication.md Stops the background goroutine responsible for automatic token renewal. This operation is non-blocking and safe to call even if the heartbeat was not started. ```go func (bot *Bot) StopHeartbeat() ``` ```go bot.StartHeartbeat() // ... do work ... bot.StopHeartbeat() ``` -------------------------------- ### Custom HTTP Client with Timeout Source: https://github.com/go-lark/lark/blob/main/_autodocs/configuration.md Configure a custom HTTP client with a specific timeout for stricter control over request durations. ```go customClient := &http.Client{ Timeout: 15 * time.Second, } bot := lark.NewChatBot(appID, appSecret) bot.SetClient(customClient) bot.StartHeartbeat() ``` -------------------------------- ### Get Tenant Access Token Source: https://github.com/go-lark/lark/blob/main/_autodocs/api-reference/authentication.md Obtains a tenant access token for internal ChatBot use. Set updateToken to true to update the bot's stored token. ```go func (bot *Bot) GetTenantAccessTokenInternal(updateToken bool) (*TenantAuthTokenInternalResponse, error) ``` ```go bot := lark.NewChatBot(appID, appSecret) resp, err := bot.GetTenantAccessTokenInternal(true) if err != nil { log.Fatal(err) } fmt.Println("Token:", resp.TenantAppAccessToken) fmt.Println("Expires in:", resp.Expire, "seconds") ``` -------------------------------- ### Get App Access Token Source: https://github.com/go-lark/lark/blob/main/_autodocs/api-reference/authentication.md Obtains an app access token for internal ChatBot use. Set updateToken to true to update the bot's stored token. ```go func (bot *Bot) GetAccessTokenInternal(updateToken bool) (*AuthTokenInternalResponse, error) ``` ```go bot := lark.NewChatBot(appID, appSecret) resp, err := bot.GetAccessTokenInternal(true) if err != nil { log.Fatal(err) } fmt.Println("Token:", resp.AppAccessToken) fmt.Println("Expires in:", resp.Expire, "seconds") ``` -------------------------------- ### Upload Audio File for Audio Message Source: https://github.com/go-lark/lark/blob/main/_autodocs/api-reference/file-upload.md Uploads an audio file and sends it as an audio message to a specified chat. The audio file must be available at the given path. ```go resp, err := bot.UploadFile(lark.UploadFileRequest{ FileType: "mp3", FileName: "instructions.mp3", Path: "/audio/instructions.mp3", }) if err != nil { log.Fatal(err) } mb := lark.NewMsgBuffer(lark.MsgAudio). BindChatID("oc_xyz789"). Audio(resp.Data.FileKey) bot.PostMessage(mb.Build()) ``` -------------------------------- ### Get User Info Source: https://github.com/go-lark/lark/blob/main/_autodocs/api-reference/contact-management.md Retrieves detailed information for a specific user. The user can be identified by email, user ID, open ID, chat ID, or union ID. ```APIDOC ## GET /open-apis/contact/v3/users/{user_id}?user_id_type={id_type} ### Description Retrieves detailed information for a specific user. The user can be identified by email, user ID, open ID, chat ID, or union ID. ### Method GET ### Endpoint /open-apis/contact/v3/users/{user_id}?user_id_type={id_type} ### Parameters #### Path Parameters - **user_id** (string) - Required - The ID of the user to retrieve. #### Query Parameters - **user_id_type** (string) - Required - The type of user ID provided (e.g., `email`, `user_id`, `open_id`, `chat_id`, `union_id`). ### Request Example ```json { "example": "GET /open-apis/contact/v3/users/ou_12345?user_id_type=user_id" } ``` ### Response #### Success Response (200) - **Data** (object) - Contains user information. - **User** (object) - Detailed user object. - **OpenID** (string) - Open ID for this user. - **Email** (string) - Email address. - **UserID** (string) - User ID (employee ID equivalent). - **ChatID** (string) - Private chat ID with this user. - **UnionID** (string) - Union ID for cross-tenant operations. - **Name** (string) - Display name. - **EnglishName** (string) - English name (if set). - **NickName** (string) - Nickname. - **Mobile** (string) - Mobile phone number. - **MobileVisible** (bool) - Whether mobile is visible to others. - **Gender** (int) - Gender (0=unknown, 1=male, 2=female). - **Avatar** (object) - Avatar URLs in different sizes. - **Avatar72** (string) - 72x72 pixels avatar URL. - **Avatar240** (string) - 240x240 pixels avatar URL. - **Avatar640** (string) - 640x640 pixels avatar URL. - **Status** (object) - Account status (frozen, resigned, etc.). - **IsResigned** (bool) - True if the user has resigned. - **IsFrozen** (bool) - True if the user account is frozen. - **IsActivated** (bool) - True if the user account is activated. - **IsUnjoin** (bool) - True if the user has left the organization. - **City** (string) - City location. - **Country** (string) - Country location. - **WorkStation** (string) - Work station or office location. - **JoinTime** (int) - Unix timestamp of join date. - **EmployeeNo** (string) - Employee number. - **EmployeeType** (int) - Employee type classification. - **EnterpriseEmail** (string) - Enterprise email address. - **Geo** (string) - Geographic region. - **JobTitle** (string) - Job title. - **JobLevelID** (string) - Job level identifier. - **JobFamilyID** (string) - Job family identifier. - **DepartmentIDs** (array) - List of department IDs this user belongs to. - **LeaderUserID** (string) - User ID of direct manager. - **IsTenantManager** (bool) - True if the user is a tenant administrator. #### Response Example ```json { "example": { "data": { "user": { "open_id": "ou_abc123", "email": "user@example.com", "user_id": "ou_12345", "chat_id": "oc_xyz789", "union_id": "union_12345", "name": "John Doe", "english_name": "John Doe", "nickname": "JD", "mobile": "+861234567890", "mobile_visible": true, "gender": 1, "avatar": { "avatar_72": "https://example.com/avatar_72.png", "avatar_240": "https://example.com/avatar_240.png", "avatar_640": "https://example.com/avatar_640.png" }, "status": { "is_resigned": false, "is_frozen": false, "is_activated": true, "is_unjoin": false }, "city": "Shanghai", "country": "China", "work_station": "Building A", "join_time": 1678886400, "employee_no": "E12345", "employee_type": 1, "enterprise_email": "john.doe@company.com", "geo": "Asia/Shanghai", "job_title": "Software Engineer", "job_level_id": "L3", "job_family_id": "F1", "department_ids": ["d1", "d2"], "leader_user_id": "ou_67890", "is_tenant_manager": false } } } } ``` ``` -------------------------------- ### Build Source: https://github.com/go-lark/lark/blob/main/_autodocs/api-reference/message-buffer.md Builds the message and returns the OutcomingMessage structure, ready for sending. ```APIDOC ## Build Builds the message and returns the OutcomingMessage structure. ### Method Signature ```go func (m *MsgBuffer) Build() OutcomingMessage ``` ### Return Type `OutcomingMessage` — built message ready for sending ### Example ```go mb := lark.NewMsgBuffer(lark.MsgText). BindEmail("user@example.com"). Text("Hello") msg := mb.Build() resp, err := bot.PostMessage(msg) ``` ``` -------------------------------- ### Create New Text Builder Source: https://github.com/go-lark/lark/blob/main/_autodocs/api-reference/message-builders.md Initializes a new MsgTextBuilder instance for constructing text messages. ```go tb := lark.NewTextBuilder() ``` -------------------------------- ### Upload Video and Thumbnail for Media Message Source: https://github.com/go-lark/lark/blob/main/_autodocs/api-reference/file-upload.md Uploads a video file and its thumbnail, then sends a media message to a specified chat. Ensure the video and thumbnail files are accessible at the provided paths. ```go // Upload video videoResp, err := bot.UploadFile(lark.UploadFileRequest{ FileType: "mp4", FileName: "demo.mp4", Path: "/videos/demo.mp4", Duration: 45, }) if err != nil { log.Fatal(err) } // Upload thumbnail thumbResp, err := bot.UploadImage("/videos/thumbnail.png") if err != nil { log.Fatal(err) } // Send media message mb := lark.NewMsgBuffer(lark.MsgMedia). BindChatID("oc_xyz789"). Media(videoResp.Data.FileKey, thumbResp.Data.ImageKey) resp, err := bot.PostMessage(mb.Build()) ``` -------------------------------- ### Handling JSON Unmarshal Errors in Go Source: https://github.com/go-lark/lark/blob/main/_autodocs/errors.md This example illustrates how JSON unmarshal errors are handled when parsing API responses. The error is typically logged and returned by the API method. ```go var resp lark.PostMessageResponse // If response body is invalid JSON, json.Unmarshal fails // Error is logged and returned from API method ``` -------------------------------- ### Build and Send User Share Card Message Source: https://github.com/go-lark/lark/blob/main/v2/README.md Create a user share card message using `MsgBuffer` and send it with `PostMessage`. The `ShareUser` content function is used for sharing user information. ```go buffer := lark.NewMsgBuffer() buffer.BindChatID("") buffer.ShareUser(&lark.MsgShareUser{UserID: ""}) bot.PostMessage(ctx, buffer.Build()) ``` -------------------------------- ### Configure Request Context Source: https://github.com/go-lark/lark/blob/main/_autodocs/configuration.md Sets a context for request handling, enabling features like request-scoped deadlines and graceful shutdown. Remember to cancel the context when it's no longer needed. ```go ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) defer cancel() bot.WithContext(ctx) ```