golang飞书与Lark开放平台易用SDK插件库go-larkFeishuLark的使用

go-lark: Golang 飞书与Lark开放平台易用SDK插件库

go-lark 是一个用于飞书和Lark开放平台的易用SDK,实现了消息API,全面支持构建聊天机器人和通知机器人。

特性

  • 支持通知机器人和聊天机器人
  • 发送消息(群组、私聊、富文本和卡片)
  • 使用 MsgBuffer 快速构建消息
  • 轻松创建接收消息的钩子
  • 支持加密和令牌验证
  • 支持Gin和Hertz Web框架的中间件
  • 高度可扩展
  • 完善的文档和测试

安装

go get github.com/go-lark/lark

快速开始

前提条件

go-lark支持两种类型的机器人,需要手动创建:

聊天机器人:

通知机器人:

  • 从群聊创建
  • 需要Web Hook URL

发送消息

聊天机器人:

import "github.com/go-lark/lark"

func main() {
    bot := lark.NewChatBot("<App ID>", "<App Secret>")
    bot.StartHeartbeat()
    bot.PostText("hello, world", lark.WithEmail("someone@example.com"))
}

通知机器人:

import "github.com/go-lark/lark"

func main() {
    bot := lark.NewNotificationBot("<WEB HOOK URL>")
    bot.PostNotificationV2(lark.NewMsgBuffer(lark.MsgText).Text("hello, world").Build())
}

切换到Lark端点

默认API端点是飞书的,要切换到Lark,应使用SetDomain:

bot := lark.NewChatBot("<App ID>", "<App Secret>")
bot.SetDomain(lark.DomainLark)

使用示例

认证

自动续期认证:

// 使用appID和appSecret初始化聊天机器人
bot := lark.NewChatBot(appID, appSecret)
// 定期续期访问令牌
bot.StartHeartbeat()
// 停止续期
bot.StopHeartbeat()

单次认证:

bot := lark.NewChatBot(appID, appSecret)
resp, err := bot.GetTenantAccessTokenInternal(true)
// 现在可以通过`bot.TenantAccessToken()`访问令牌值

消息发送

对于聊天机器人,可以使用以下方法发送简单消息:

  • PostText
  • PostTextMention
  • PostTextMentionAll
  • PostImage
  • PostShareChatCard
  • ReplyMessage
  • AddReaction
  • DeleteReaction

要构建富文本消息,可以使用消息缓冲区(或简称为MsgBuffer),它通过链式方法方便地构建消息。

消息缓冲区

我们可以使用MsgBuffer构建消息体,并使用PostMessage发送,支持以下消息类型:

  • MsgText: 文本
  • MsgPost: 富文本
  • MsgInteractive: 交互式卡片
  • MsgShareCard: 群组分享卡片
  • MsgShareUser: 用户分享卡片
  • MsgImage: 图片
  • MsgFile: 文件
  • MsgAudio: 音频
  • MsgMedia: 媒体
  • MsgSticker: 贴纸

MsgBuffer提供绑定函数和内容函数。

绑定函数:

函数 用途 备注
BindChatID 绑定聊天ID 必须提供OpenIDUserIDEmailChatIDUnionID之一
BindOpenID 绑定用户open ID
BindUserID 绑定用户ID
BindUnionID 绑定union ID
BindEmail 绑定用户邮箱
BindReply 绑定回复ID 回复消息时需要

内容函数与消息内容类型配对。如果不匹配,则无法成功发送。

函数 消息类型 用途 备注
Text MsgText 追加纯文本 可以使用TextBuilder构建
Post MsgPost 追加富文本 可以使用PostBuilder构建
Card MsgInteractive 追加交互式卡片 可以使用CardBuilder构建
Template MsgInteractive 追加卡片模板 需要使用CardKit构建
ShareChat MsgShareCard 追加群组分享卡片
ShareUser MsgShareUser 追加用户分享卡片
Image MsgImage 追加图片 需要提前上传到Lark服务器
File MsgFile 追加文件 需要提前上传到Lark服务器
Audio MsgAudio 追加音频 需要提前上传到Lark服务器
Media MsgMedia 追加媒体 需要提前上传到Lark服务器
Sticker MsgSticker 追加贴纸 需要提前上传到Lark服务器

中间件

我们已经实现了HTTP中间件来支持事件处理:

URL挑战:

r := gin.Default()
middleware := larkgin.NewLarkMiddleware()
middleware.BindURLPrefix("/handle") // 假设URL是http://your.domain.com/handle
r.Use(middleware.LarkChallengeHandler())

事件V2:

Lark提供了事件v2,它自动应用于新创建的机器人。

r := gin.Default()
middleware := larkgin.NewLarkMiddleware()
r.Use(middleware.LarkEventHandler())

获取事件(例如消息):

r.POST("/", func(c *gin.Context) {
    if evt, ok := middleware.GetEvent(c); ok { // => 使用GetEvent而不是GetMessage
        if evt.Header.EventType == lark.EventTypeMessageReceived {
            if msg, err := evt.GetMessageReceived(); err == nil {
                fmt.Println(msg.Message.Content)
            }
        }
    }
})

卡片回调:

我们也可以为卡片操作(如按钮)设置回调。URL挑战部分相同。

我们可以使用LarkCardHandler来处理操作:

r.Use(middleware.LarkCardHandler())
r.POST("/callback", func(c *gin.Context) {
    if card, ok := middleware.GetCardCallback(c); ok {
    }
})

接收消息(事件V1):

对于旧版机器人,请使用v1:

r := gin.Default()
middleware := larkgin.NewLarkMiddleware()
middleware.BindURLPrefix("/handle") // 假设URL是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
        // 你的业务逻辑
    }
})

安全与加密

Lark开放平台提供AES加密和令牌验证以确保事件安全。

  • AES加密: 开启后,所有流量将使用AES加密
  • 令牌验证: 对传入消息进行简单的令牌验证

我们建议你启用令牌验证。如果你的主机上没有HTTPS,则启用AES加密。

middleware.WithTokenVerfication("<verification-token>")
middleware.WithEncryption("<encryption-key>")

完整示例

发送富文本消息

package main

import (
    "github.com/go-lark/lark"
)

func main() {
    // 初始化聊天机器人
    bot := lark.NewChatBot("your_app_id", "your_app_secret")
    bot.StartHeartbeat()
    
    // 构建富文本消息
    mb := lark.NewMsgBuffer(lark.MsgPost)
    mb.Post(lark.NewPostBuilder().
        Title("富文本消息标题").
        TextTag("这是一条", 1, true).
        TextTag("富文本", 1, true).
        TextTag("消息", 1, true).
        LinkTag("点击这里", "https://example.com").
        AtTag("someone@example.com", "某人").
        Build())
    
    // 发送消息到指定邮箱
    _, err := bot.PostMessage(mb.BindEmail("someone@example.com").Build())
    if err != nil {
        panic(err)
    }
}

接收并处理消息

package main

import (
    "fmt"
    "github.com/gin-gonic/gin"
    "github.com/go-lark/lark-gin"
    "github.com/go-lark/lark"
)

func main() {
    r := gin.Default()
    
    // 初始化中间件
    middleware := larkgin.NewLarkMiddleware()
    middleware.WithTokenVerfication("your_verification_token")
    
    // 处理URL挑战
    r.Use(middleware.LarkChallengeHandler())
    
    // 处理消息事件
    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.Printf("收到消息: %s\n", msg.Message.Content)
                    
                    // 回复消息
                    bot := lark.NewChatBot("your_app_id", "your_app_secret")
                    bot.ReplyMessage(msg.Message.MessageID, lark.NewMsgBuffer(lark.MsgText).Text("已收到你的消息").Build())
                }
            }
        }
    })
    
    r.Run(":8080")
}

发送交互式卡片

package main

import (
    "github.com/go-lark/lark"
    "github.com/go-lark/lark/card"
)

func main() {
    // 初始化聊天机器人
    bot := lark.NewChatBot("your_app_id", "your_app_secret")
    bot.StartHeartbeat()
    
    // 构建交互式卡片
    cardContent := card.NewCardBuilder().
        Header("卡片标题", "blue").
        AddElement(card.NewMarkdownElement("这是一张**交互式**卡片")).
        AddAction(card.NewButtonElement("点击按钮", "primary", map[string]interface{}{
            "value": map[string]interface{}{"key": "value"},
        })).
        Build()
    
    // 发送卡片消息
    mb := lark.NewMsgBuffer(lark.MsgInteractive)
    mb.Card(cardContent)
    
    _, err := bot.PostMessage(mb.BindEmail("someone@example.com").Build())
    if err != nil {
        panic(err)
    }
}

常见问题

  • 发送消息时收到99991401错误
    • 从仪表板移除IP白名单
  • 机器人发送消息失败
    1. 检查认证
    2. 未邀请到群组
    3. 未申请API权限
  • go-lark支持交互式消息卡片吗?
    • 是的,使用CardBuilder

贡献

  • 如果你认为发现了go-lark的bug,请提交issue
  • 欢迎Pull Request

许可证

Copyright © David Zhang, 2018-2024. 遵循MIT许可证。


更多关于golang飞书与Lark开放平台易用SDK插件库go-larkFeishuLark的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于golang飞书与Lark开放平台易用SDK插件库go-larkFeishuLark的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


go-lark 飞书/Lark开放平台SDK使用指南

go-lark 是一个专为飞书(Lark)开放平台设计的Golang SDK,提供了简洁易用的API来与飞书/Lark开放平台进行交互。下面我将详细介绍如何使用这个库。

安装

go get github.com/go-lark/lark

基础功能

1. 初始化客户端

package main

import (
	"github.com/go-lark/lark"
)

func main() {
	// 初始化机器人客户端
	bot := lark.NewNotificationBot("your-webhook-url")
	
	// 或者初始化应用客户端(需要更多权限)
	app := lark.New(lark.WithAppCredential("app-id", "app-secret"))
}

2. 发送消息

// 发送文本消息
resp, err := bot.PostNotificationV2(lark.NewMsgBuffer(lark.MsgText).Text("Hello, World!").Build())
if err != nil {
    // 处理错误
}

// 发送富文本消息
msg := lark.NewMsgBuffer(lark.MsgPost).
    Post(lark.NewPostBuilder().
        Title("通知标题").
        TextTag("这是一条通知", 1, true).
        AtAll().
        Build()).
    Build()
resp, err = bot.PostNotificationV2(msg)

3. 处理事件回调

// 初始化事件处理器
handler := lark.NewEventCallbackHandler("your-encrypt-key", "your-verification-token")

// 注册事件处理函数
handler.HandleEventCallback(func(ctx context.Context, event *lark.EventCallbackReq) error {
    switch event.Type {
    case "message":
        // 处理消息事件
        msg := event.Event.Message
        fmt.Printf("收到消息: %s\n", msg.Content)
    case "app_ticket":
        // 处理app_ticket事件
        fmt.Println("收到新的app_ticket")
    }
    return nil
})

// 在HTTP服务中使用
http.HandleFunc("/callback", func(w http.ResponseWriter, r *http.Request) {
    handler.ServeHTTP(w, r)
})
http.ListenAndServe(":8080", nil)

高级功能

1. 使用卡片消息

card := lark.NewCardBuilder().
    Header("卡片标题", lark.TemplateRed).
    Elements([]lark.MessageContentCardElement{
        lark.NewMarkdownElement("**加粗文本**\n普通文本"),
        lark.NewActionBlock([]lark.MessageContentCardElement{
            lark.NewButtonElement("按钮1", nil).Primary(),
            lark.NewButtonElement("按钮2", nil).Danger(),
        }),
    }).
    Build()

msg := lark.NewMsgBuffer(lark.MsgInteractive).Card(card).Build()
bot.PostNotificationV2(msg)

2. 获取用户信息

// 使用应用客户端
user, err := app.GetUser(ctx, &lark.GetUserReq{
    UserID:     "user-id",
    UserIDType: lark.IDTypeUserID,
})
if err != nil {
    // 处理错误
}
fmt.Printf("用户信息: %+v\n", user)

3. 上传文件

file, err := os.Open("example.jpg")
if err != nil {
    // 处理错误
}
defer file.Close()

resp, err := app.UploadFile(ctx, &lark.UploadFileReq{
    FileName: "example.jpg",
    File:     file,
})
if err != nil {
    // 处理错误
}
fmt.Printf("文件key: %s\n", resp.FileKey)

最佳实践

  1. 错误处理:所有API调用都可能返回错误,应该妥善处理
resp, err := bot.PostNotificationV2(msg)
if err != nil {
    var larkErr *lark.Error
    if errors.As(err, &larkErr) {
        fmt.Printf("飞书API错误: 状态码=%d, 消息=%s\n", larkErr.StatusCode, larkErr.Msg)
    } else {
        fmt.Printf("其他错误: %v\n", err)
    }
    return
}
  1. 并发控制:使用sync.Pool管理消息缓冲区
var msgPool = sync.Pool{
    New: func() interface{} {
        return lark.NewMsgBuffer(lark.MsgText)
    },
}

func sendMessage(text string) {
    buf := msgPool.Get().(*lark.MsgBuffer)
    defer msgPool.Put(buf)
    defer buf.Clear()
    
    msg := buf.Text(text).Build()
    bot.PostNotificationV2(msg)
}
  1. 日志记录:启用SDK日志
bot := lark.NewNotificationBot(
    "your-webhook-url",
    lark.WithLogLevel(lark.LogLevelDebug), // 设置日志级别
)

常见问题

  1. 权限不足:确保你的应用有正确的权限范围
  2. 签名验证失败:检查加密密钥和验证令牌是否正确
  3. 消息格式错误:使用SDK提供的构建器来确保消息格式正确

go-lark SDK提供了全面的飞书/Lark开放平台API支持,通过合理的封装简化了开发流程。更多高级用法可以参考官方文档和示例代码。

回到顶部