前面介绍过一个使用飞书机器人发送简单文本消息的例子,属于飞书机器人推送消息入门,实际工作中发简单消息的场景相对是比较少的,一般都是以交互式的卡片方式发送消息,卡片式能承载更多的信息,例如图片、Markdown
、按钮等等。
交互式消息与文本消息代码不同之处就在于Send
方法的参数Message(接口)
的不同,对于文本消息Message
是如下结构
type TextMessage struct {
MsgType MsgType `json:"msg_type"`
Content Content `json:"content"`
}
type Content struct {
Text string `json:"text"`
}
而对于交互式的消息Message
结构如下
type InteractiveMessage struct {
MsgType MsgType `json:"msg_type"`
Card string `json:"card"`
}
其中Card
支持传递json字符串
,示例如下
package main
import (
"flag"
"fmt"
"github.com/CatchZeng/feishu/pkg/feishu"
)
func main() {
token := flag.String("token", "", "飞书机器人webhook token")
secretKey := flag.String("secret_key", "", "飞书机器人-安全设置-签名秘钥")
flag.Parse()
client := feishu.NewClient(*token, *secretKey)
// sendMsg(client)
sendCard(client)
}
func sendMsg(client *feishu.Client) {
msg := feishu.NewTextMessage()
msg.Content.Text = "hello world"
_, response, err := client.Send(msg)
if err != nil {
panic(any(err))
}
fmt.Println(response)
}
func sendCard(client *feishu.Client) {
// 相对于文本消息的主要改动点
msg := feishu.NewInteractiveMessage()
// Card为一个JSON字符串
msg.Card = "{\n \"elements\": [\n {\n \"tag\": \"column_set\",\n \"flex_mode\": \"none\",\n \"background_style\": \"grey\",\n \"columns\": [\n {\n \"tag\": \"column\",\n \"width\": \"weighted\",\n \"weight\": 1,\n \"vertical_align\": \"top\",\n \"elements\": [\n {\n \"tag\": \"div\",\n \"text\": {\n \"content\": \"这是一段普通文本😄\",\n \"tag\": \"plain_text\"\n }\n }\n ]\n },\n {\n \"tag\": \"column\",\n \"width\": \"weighted\",\n \"weight\": 1,\n \"vertical_align\": \"top\",\n \"elements\": [\n {\n \"tag\": \"markdown\",\n \"content\": \"普通文本\\n标准emoji 😁😢🌞💼🏆❌✅\\n*斜体*\\n**粗体**\\n~~删除线~~\\n[文字链接](https://www.feishu.cn)\\n<at id=all></at>\"\n }\n ]\n },\n {\n \"tag\": \"column\",\n \"width\": \"weighted\",\n \"weight\": 1,\n \"vertical_align\": \"top\",\n \"elements\": [\n {\n \"tag\": \"img\",\n \"img_key\": \"img_v2_041b28e3-5680-48c2-9af2-497ace79333g\",\n \"alt\": {\n \"tag\": \"plain_text\",\n \"content\": \"\"\n },\n \"mode\": \"fit_horizontal\",\n \"preview\": true\n }\n ]\n }\n ]\n },\n {\n \"tag\": \"action\",\n \"actions\": [\n {\n \"tag\": \"date_picker\",\n \"placeholder\": {\n \"tag\": \"plain_text\",\n \"content\": \"请选择日期时间\"\n }\n }\n ]\n },\n {\n \"tag\": \"action\",\n \"actions\": [\n {\n \"tag\": \"select_static\",\n \"placeholder\": {\n \"tag\": \"plain_text\",\n \"content\": \"默认提示文本\"\n },\n \"value\": {\n \"key\": \"value\"\n },\n \"options\": [\n {\n \"text\": {\n \"tag\": \"plain_text\",\n \"content\": \"选项1\"\n },\n \"value\": \"1\"\n },\n {\n \"text\": {\n \"tag\": \"plain_text\",\n \"content\": \"选项2\"\n },\n \"value\": \"2\"\n },\n {\n \"text\": {\n \"tag\": \"plain_text\",\n \"content\": \"选项3\"\n },\n \"value\": \"3\"\n },\n {\n \"text\": {\n \"tag\": \"plain_text\",\n \"content\": \"选项4\"\n },\n \"value\": \"4\"\n }\n ]\n }\n ]\n },\n {\n \"tag\": \"note\",\n \"elements\": [\n {\n \"tag\": \"img\",\n \"img_key\": \"img_v2_041b28e3-5680-48c2-9af2-497ace79333g\",\n \"alt\": {\n \"tag\": \"plain_text\",\n \"content\": \"\"\n }\n },\n {\n \"tag\": \"plain_text\",\n \"content\": \"备注信息\"\n }\n ]\n },\n {\n \"tag\": \"div\",\n \"fields\": [\n {\n \"is_short\": true,\n \"text\": {\n \"tag\": \"lark_md\",\n \"content\": \"**🗳工单来源:**\\n报事报修\"\n }\n },\n {\n \"is_short\": true,\n \"text\": {\n \"tag\": \"lark_md\",\n \"content\": \"**📝工单类型:**\\n客服工单\"\n }\n }\n ]\n }\n ],\n \"header\": {\n \"template\": \"blue\",\n \"title\": {\n \"content\": \"这是一个标题\",\n \"tag\": \"plain_text\"\n }\n }\n}"
_, response, err := client.Send(msg)
if err != nil {
panic(any(err))
}
fmt.Println(response)
}
执行:go run main.go -token=052f427f-3f57-455a-XXXX-XXXXXXXXX" -secret_key="aQkBeQyAgXXXXXXXXXX"
飞书群便收到了机器人发送的卡片消息
扩展:如何构建自己的卡片消息呢?
进入飞书消息卡片搭建平台,就像搭积木一样将卡片拼装出来,然后复制好生成的JSON
放入代码中即可
卡片中如果需要变量怎么办?
搭建的JSON
是死的,但我们期望的效果是卡片中相关元素可以根据实际代码中的某些变量做替换,这个时候有两种处理办法。
- 如果替换内容不多且不复杂,可以使用
fmt.Sprintf()
将原JSON
中需要替换的地方改为%s
或者%d
,在代码运行时组装为新的JSON
字符串即可 - 如果替换内容多或需要替换的内容比较复杂,可以根据
JSON
的格式定义相应的一些结构体,然后将JSON
模板反序列化到结构体对象中,对该对象进行一些相应修改后再序列化为JSON
即可