飞书机器人系列9——应用机器人自动回复飞书卡片实操
评论
收藏

飞书机器人系列9——应用机器人自动回复飞书卡片实操

经验分享
花括号
2025-06-17 21:22·浏览量:1645
花括号
影刀专家
发布于 2025-06-17 16:40更新于 2025-06-17 21:221645浏览

上一章实操了用 机器人助手 接收群消息,自定义机器人 回复飞书卡片的案例。

本章准备用 机器人助手 来回复飞书卡片,查看飞书文档发现 机器人助手 不能发送飞书卡片。

那么我们就尝试来用 应用机器人 来发送飞书卡片。


一、创建自动回复机器人应用

详细步骤请见 三分钟快速开发自动回复机器人实现思路文档

该机器人需要实现以下核心功能:

  1. 订阅 接收消息事件 (im.message.receive_v1) 。订阅接收消息事件后,用户向机器人发送消息会触发该事件,之后飞书会将消息内容推送到你的服务端,你可在事件体中获取用户发送的消息内容、 message_id 和 chat_type 等参数。
  2. 根据返回的事件体的 chat_type 参数,判断当前的消息类型是单聊还是群聊:
  • 如果是单聊,则调用 发送消息 接口,将用户发送的消息内容原样返回;
  • 如果是群聊,则基于 message_id 调用回复消息接口,将消息内容原样回复。



二、群消息添加自动回复机器人

  1. 添加机器人

2.@自动回复机器人

自动回复机器人 自动回复了信息,但是回复信息是 原样回复消息内容

我们所要做的就是将自动回复,转变为消息卡片。


三、业务代码

SDK业务代码路径:echo_bot/python/main.py,代码实现逻辑说明如下。

  1. 构建 API Client 用于调用 OpenAPI。
  2. 注册事件处理器,接收接收消息事件(onP2MessageReceiveV1),并解析数据。
  3. 检查消息类型是否为纯文本消息(text),是则进行下一步,不是则提示用户需要发送文本消息。
  4. 通过判断条件 if data.event.message.chat_type == "p2p": 区分单聊与群聊。
  • 如果是单聊(p2p),则调用发送消息接口向对应用户发送消息。
  • 如果是群聊,则调用回复消息接口,回复用户在群组内 @机器人的消息。



四、构造消息卡片

echo_bot/python/路径下新增yingdao_rank.py文件,

def main():
    try:
        rank_data = get_yingdao_rank(None)
        # print("Yingdao Rank Data:", rank_data)
        card_content = generate_card_content(rank_data)
        # print("Generated Card Content:", card_content)
        return card_content
    except Exception as e:
        print("Error fetching Yingdao rank data:", str(e))

if __name__ == "__main__":
    main()

get_yingdao_rank() 函数用来发送HTTP请求获取影刀采纳排行榜json。


import requests

yingdao_rank_api_url = "https://api.yingdao.com/api/noauth/v1/sns/forum/contribution/queryList?timeRange=NEWEST&contributionType=ACCEPT"

def get_yingdao_rank(data):
    """ 
    Fetch the Yingdao rank data.
    """
    response = requests.get(yingdao_rank_api_url)
    if response.status_code != 200:
        raise Exception(f"Failed to fetch data: {response.status_code} - {response.text}")
    return response.json()

generate_card_content() 函数来构造卡片json。

def generate_card_content(data):
    """
    Generate the card content for the Yingdao rank.
    """
    rank_data = get_yingdao_rank(data)
    if not rank_data or 'data' not in rank_data:
        return "No data available"
    rank_data = rank_data['data']
    if not rank_data:
        return "No rank data available"
    card_content = {
        "schema": "2.0",
        "config": {
            "update_multi": True
        },
        "body": {
            "direction": "vertical",
            "horizontal_spacing": "8px",
            "vertical_spacing": "8px",
            "horizontal_align": "left",
            "vertical_align": "top",
            "padding": "12px 12px 12px 12px",
            "elements": [
                {
                    "tag": "table",
                    "columns": [
                        {
                            "data_type": "number",
                            "name": "rank",
                            "display_name": "排名",
                            "horizontal_align": "center",
                            "width": "20%",
                            "format": {
                                "precision": 0
                            }
                        },
                        {
                            "data_type": "text",
                            "name": "name",
                            "display_name": "昵称",
                            "horizontal_align": "center",
                            "width": "auto"
                        },
                        {
                            "data_type": "number",
                            "name": "count",
                            "display_name": "被采纳数",
                            "horizontal_align": "center",
                            "width": "auto",
                            "format": {
                                "precision": 0
                            }
                        }
                    ],
                    "rows": [
                        {
                            "name": item['userName'],
                            "count": item['count'],
                            "rank": i + 1
                        } for i, item in enumerate(rank_data[: 5])
                    ],
                    "row_height": "low",
                    "header_style": {
                        "background_style": "grey",
                        "bold": True,
                        "lines": 1
                    },
                    "page_size": 5,
                    "margin": "0px 0px 0px 0px"
                },
                {
                    "tag": "img",
                    "img_key": "img_v3_02n7_36c1413d-525b-4a06-8e88-d83b48df383g",
                    "preview": True,
                    "transparent": False,
                    "scale_type": "fit_horizontal",
                    "margin": "0px 0px 0px 0px"
                }
            ]
        },
        "header": {
            "title": {
                "tag": "plain_text",
                "content": "6月贡献榜"
            },
            "subtitle": {
                "tag": "plain_text",
                "content": "你敢回答我就敢采纳"
            },
            "template": "blue",
            "padding": "12px 12px 12px 12px"
        }
    }

    return card_content
  
   

card_content通过飞书官方提供的飞书消息卡片搭建工具进行编辑,复制源代码过来。

表格信息 rows 由列表推导式获取当前排行榜信息即可。

修改main.py里回复消息内容,

  • 如果发送消息里包含“影刀”或者“排行”,则调用yingdao_rank.main()生成卡片内容,msg_type设置为“interactive”;
  • 如果不包含“影刀”和“排行”,还是原样回复文本消息,msg_type设置为“text”。

使用OpenAPI回复消息,消息内容content和类别msg_type根据发消息的内容动态取值。

五、@机器人发送消息

  1. 启动 SDK程序。

2. @自动回复机器人,

依次输入“影刀”和“排行”,都返回了飞书卡片。

输入“椰子”,原样回复“椰子”。

这样在保留原有功能的情况下,又开发了新的功能。


以上操作过程,通过完善SDK程序代码,完成了应用机器人自动回复飞书卡片的功能。


应用机器人通过调用SDK的API,还可以完成各类功能,是功能最为强大的机器人。


收藏1
全部评论1
最新
发布评论
评论