-
微信
-
支付宝
# 飞书通知机器人
## 目标 & 背景
前段时间钉钉的 webhook 机器人,进行了改版,现如今已经和企业微信通知差不多了,比之前麻烦了很多,正好我司接下来要换到飞书,借着这个机会对飞书的机器人相关内容熟悉了一下
首先明确在接入机器人时,我希望最终接入时,仅需要引入 shell 脚本,不需要借助其他语言二次开发
## 创建企业 app
首先来到 [飞书开放平台](https://open.feishu.cn),创建企业自建应用,对于通知类型的机器人,我们需要添加 **机器人** 能力,以及对应的通知权限
![](https://blog.liuocean.synology.me:9001/blog/old/17032098531026.jpg)
![](https://blog.liuocean.synology.me:9001/blog/old/17032098758746.jpg)
这里的权限一般需要企业的管理员进行审核后,才可以使用
## 消息卡片模板
飞书提供了很多种消息类型,其中我个人比较喜欢的是 card 类型,可以完成很多复杂的消息推送,而且飞书还通了一个可视化的搭建工具,具体可点击链接尝试 [消息卡片搭建工具](https://open.feishu.cn/tool/cardbuilder)
![](https://blog.liuocean.synology.me:9001/blog/old/17032115183434.jpg)
这里我使用模板 ID 作为推送的类型,因此需要在变量列表中配置通知时需要上传的参数列表,如 **我是内容** 这段文字对应的 markdown 信息,就需要传入 **content** 变量,基于这种配置方式,我们在搭建好通知后台后,可以随意修改卡片的样式等信息
## 访问凭证
[获取访问凭证文档](https://open.feishu.cn/document/server-docs/api-call-guide/calling-process/get-access-token)
飞书的官方文档还是非常不错的,我们这里使用的是第一种 **tenant_access_token**,这里主要讲一下如何将请求的返回结果取出我们要的字段
```shell
curl -X POST 'https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal' \
-H 'Content-Type: application/json' \
-d '{
"app_id": "xxx",
"app_secret": "xxx"
}'
```
在执行这段代码后,飞书会返回如下内容
```json
{
"code": 0,
"expire": 3096,
"msg": "ok",
"tenant_access_token": "t-xxx"
}
```
我们需要的是最后一段 **tenant_access_token** 对应的字符串,这里需要借助 **jq** 指令的辅助,我们只需要在请求的最后加入 **| jq -r '.tenant_access_token'** 即可
```shell
token=$(curl -X POST 'https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal' \
-H 'Content-Type: application/json' \
-d '{
"app_id": "xxx",
"app_secret": "xxx"
}' | jq -r '.tenant_access_token')
echo $token
```
## 群 ID
- [群 ID 说明](https://open.feishu.cn/document/server-docs/group/chat/chat-id-description)
- [API 调试](https://open.feishu.cn/document/server-docs/group/chat/list)
在我们调用最后的发送 API 之前,需要明确这条消息到底发给谁,我这里的需求是发送到专门的通知群中,因此需要透过飞书的 API 获取正确的群 ID
在 API 调试界面,手动获取 token 后,飞书会直接返回给你当前机器人所在的所有群的基本信息,具体返回参考如下
```json
{
"code": 0,
"data": {
"has_more": false,
"items": [
{
"avatar": "xxx",
"chat_id": "xxx",
"description": "",
"external": false,
"name": "xxx",
"owner_id": "xxx",
"owner_id_type": "open_id",
"tenant_key": "xxx"
}
],
"page_token": ""
},
"msg": "success"
}
```
这里的 **chat_id** 对应的值就是我们所需要的
## 发送消息
[发送消息文档](https://open.feishu.cn/document/server-docs/im-v1/message/create)
这个部分我们主要做的是对 send 行为进行封装,并处理好字符串的转换。在发送之前,我们需要准备好如下参数
- **receive_id_type** 这里是 **chat_id**
- **tenant_access_token**
- **receive_id** 对应群的 **chat_id**
- **template_id** 对应 card 模板 ID
- **template_variable** 对应 card 模板中的变量
- **app_id** 机器人应用 ID
- **app_secret** 机器人的 sign
```shell
#!/bin/bash
raw_content='
{
"type":"template",
"data":
{
"template_id":"xxx", # 填入你的模板ID
"template_variable":
{
"title":"我是标题", # 这里可以封装为函数,使用 $1 等参数进行接收
"content":"我是内容",
"btn_name":"我是按钮",
"btn_url":"https://www.baidu.com"
}
}
}
'
# 飞书对于 content 的定义为 string,因此这里必须是一个转义后的 json
# 比如 "type":"template" 就必须是 \"type\":\"template\"
# 借助 jq 的 tostring 方法,可以保证上面模板 json 的书写体验
content=$(echo $raw_content | jq -c '.|tostring')
card='
{
"msg_type": "interactive",
"receive_id": "xxx", # 群的 chat_id
"content":'$content'
}
'
token=$(curl -X POST 'https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal' \
-H 'Content-Type: application/json' \
-d '{
"app_id": "xxx", # 企业应用的 app_id
"app_secret": "xxx" # 企业应用的 sign
}' | jq -r '.tenant_access_token')
curl -i -X POST 'https://open.feishu.cn/open-apis/im/v1/messages?receive_id_type=chat_id' \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer '$token'' \
-d "$card"
```
## 一些恶趣味
在我使用过程中发现,card 后台也可以动态配置图片,而且飞书也支持 gif 格式,这就有意思了,搭建工具可以手动上传你需要的图片,记录下来这张图片的 key,然后在 shell 脚本中根据情况选择不同的 key,这样就可以有不同的通知效果
> 虽然飞书也支持 api upload 图片,但是我懒的写了~
![](https://blog.liuocean.synology.me:9001/blog/old/17032145777517.jpg)
我把通知的三种类型,对应了三个不同 魔性八哥 的表情包
- 开始打包
- 打包成功
- 打包失败
哈哈哈哈哈,这个通知非常欢乐,你都不用看文字,就知道结果
## 最后
这次了解了一下飞书的通知,对比了一下钉钉的 webhook,差距非常明显