An easy-to-use SDK for Feishu and Lark Open Platform (Instant Messaging API only)
go-lark is an easy-to-use SDK for Feishu and Lark Open Platform, which implements messaging APIs, with full-fledged supports on building Chat Bot and Notification Bot.
It is widely used and tested by ~650 ByteDance in-house developers with over 3k Go packages.
MsgBuffer
go get github.com/go-lark/lark
There are two types of bot that is supported by go-lark. We need to create a bot manually.
Chat Bot:
ChatBot
.Notification Bot:
Chat Bot:
import "github.com/go-lark/lark"
func main() {
bot := lark.NewChatBot("<App ID>", "<App Secret>")
bot.StartHeartbeat()
bot.PostText("hello, world", lark.WithEmail("[email protected]"))
}
Notification Bot:
import "github.com/go-lark/lark"
func main() {
bot := lark.NewNotificationBot("<WEB HOOK URL>")
bot.PostNotificationV2(lark.NewMsgBuffer(lark.MsgText).Text("hello, wolrd").Build())
}
Feishu/Lark API offers more features, please refers to Usage for further documentation.
The default API endpoints are for Feishu, in order to switch to Lark, we should use SetDomain
:
bot := lark.NewChatBot("<App ID>", "<App Secret>")
bot.SetDomain(lark.DomainLark)
Auto-renewable authentication:
// initialize a chat bot with appID and appSecret
bot := lark.NewChatBot(appID, appSecret)
// Renew access token periodically
bot.StartHeartbeat()
// Stop renewal
bot.StopHeartbeat()
Single-pass authentication:
bot := lark.NewChatBot(appID, appSecret)
resp, err := bot.GetTenantAccessTokenInternal(true)
// and we can now access the token value with `bot.TenantAccessToken()`
Example: examples/auth
For Chat Bot, we can send simple messages with the following method:
PostText
PostTextMention
PostTextMentionAll
PostImage
PostShareChatCard
ReplyMessage
AddReaction
DeleteReaction
Basic message examples: examples/basic-message
To build rich messages, we may use Message Buffer (or simply MsgBuffer
),
which builds message conveniently with chaining methods.
Apart from the general auth and messaging chapter, there are comprehensive examples for almost all APIs.
Here is a collection of ready-to-run examples for each part of go-lark
:
We can build message body with MsgBuffer
and send with PostMessage
, which supports the following message types:
MsgText
: TextMsgPost
: Rich TextMsgInteractive
: Interactive CardMsgShareCard
: Group Share CardMsgShareUser
: User Share CardMsgImage
: ImageMsgFile
: FileMsgAudio
: AudioMsgMedia
: MediaMsgSticker
: StickerMsgBuffer
provides binding functions and content functions.
Binding functions:
Function | Usage | Comment |
---|---|---|
BindChatID | Bind a chat ID | Either OpenID , UserID , Email , ChatID or UnionID should be present |
BindOpenID | Bind a user open ID | |
BindUserID | Bind a user ID | |
BindUnionID | Bind a union ID | |
BindEmail | Bind a user email | |
BindReply | Bind a reply ID | Required when reply a message |
Content functions pair with message content types. If it mismatched, it would not have sent successfully. Content functions:
Function | Message Type | Usage | Comment |
---|---|---|---|
Text | MsgText |
Append plain text | May build with TextBuilder |
Post | MsgPost |
Append rich text | May build with PostBuilder |
Card | MsgInteractive |
Append interactive card | May build with CardBuilder |
ShareChat | MsgShareCard |
Append group share card | |
ShareUser | MsgShareUser |
Append user share card | |
Image | MsgImage |
Append image | Required to upload to Lark server in advance |
File | MsgFile |
Append file | Required to upload to Lark server in advance |
Audio | MsgAudio |
Append audio | Required to upload to Lark server in advance |
Media | MsgMedia |
Append media | Required to upload to Lark server in advance |
Sticker | MsgSticker |
Append sticker | Required to upload to Lark server in advance |
Each go-lark
API function returns response
and err
.
err
is the error from HTTP client, when it was not nil
, HTTP might have gone wrong.
While response
is HTTP response from Lark API server, in which Code
and OK
represent whether it succeeds.
The meaning of Code
is defined here.
Lark provides a number of events and they are in two different schema (1.0/2.0). go-lark now only implements a few of them, which are needed for interacting between bot and Lark server:
We recommend HTTP middlewares to handle these events.
We have already implemented HTTP middlewares to support event handling:
Example: examples/gin-middleware examples/hertz-middleware
r := gin.Default()
middleware := larkgin.NewLarkMiddleware()
middleware.BindURLPrefix("/handle") // supposed URL is http://your.domain.com/handle
r.Use(middleware.LarkChallengeHandler())
Lark has provided event v2 and it applied automatically to newly created bots.
r := gin.Default()
middleware := larkgin.NewLarkMiddleware()
r.Use(middleware.LarkEventHandler())
Get the event (e.g. Message):
r.POST("/", func(c *gin.Context) {
if evt, ok := middleware.GetEvent(c); ok { // => GetEvent instead of GetMessage
if evt.Header.EventType == lark.EventTypeMessageReceived {
if msg, err := evt.GetMessageReceived(); err == nil {
fmt.Println(msg.Message.Content)
}
}
}
})
We may also setup callback for card actions (e.g. button). The URL challenge part is the same.
We may use LarkCardHandler
to handle the actions:
r.Use(middleware.LarkCardHandler())
r.POST("/callback", func(c *gin.Context) {
if card, ok := middleware.GetCardCallback(c); ok {
}
})
For older bots, please use v1:
r := gin.Default()
middleware := larkgin.NewLarkMiddleware()
middleware.BindURLPrefix("/handle") // supposed URL is http://your.domain.com/handle
r.POST("/handle", func(c *gin.Context) {
if msg, ok := middleware.GetMessage(c); ok && msg != nil {
text := msg.Event.Text
// your awesome logic
}
})
Lark Open Platform offers AES encryption and token verification to ensure security for events.
We recommend you to enable token verification. If HTTPS is not available on your host, then enable AES encryption.
middleware.WithTokenVerfication("<verification-token>")
middleware.WithEncryption("<encryption-key>")
Lark does not provide messaging API debugger officially. Thus, we have to debug with real Lark conversation. We recommend ngrok to debug events.
And we add PostEvent
to simulate message sending to make it even easier.
PostEvent
can also be used to redirect events, which acts like a reverse proxy.
Dotenv Setup
go-lark uses godotenv
test locally. You may have to create a .env
file in repo directory, which contains environmental variables:
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
LARK_APP_ID
and LARK_APP_SECRET
are mandatory. Others are required only by specific API tests.
Run Test
GO_LARK_TEST_MODE=local ./scripts/test.sh
go-lark's dev utilities (authentication, HTTP handling, and etc.) are capable for easily implementing most of APIs provided by Lark Open Platform. And we may use that as an extension for go-lark.
Here is an example that implementing a Lark Doc API with go-lark:
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
}
99991401
when sending messages
Copyright (c) David Zhang, 2018-2024. Licensed under MIT License.