飞书机器人 (lark_bot)
pywayne.lark_bot 是应用机器人侧的主能力封装,覆盖主动发消息、引用回复、消息编辑、撤回、reaction、置顶、群管理、资源上传下载、历史消息查询等常见飞书 IM 能力。
如果把整个模块按对象分层,可以理解为:
TextContent: 文本格式工具,解决 @、加粗、链接等轻量文本拼接PostContent: rich_text 富文本构造器,适合做结构化文本、代码块、Markdown 表格降级CardContentV2: schema 2.0 卡片构造器,适合大段 Markdown 和轻交互展示LarkBot: 统一 API 封装,负责真正和飞书 OpenAPI 通信
能力概览
LarkBot 当前重点覆盖这些能力:
主动发送消息
文本
图片
音频
媒体
文件
rich_text 富文本
card 卡片
分享群聊
分享用户
系统消息
Markdown 自动路由发送
消息后处理
引用回复
线程内回复
转发消息
撤回消息
获取单条消息
获取历史消息列表
编辑文本 / rich_text / card 消息
原位更新 card 卡片
查询已读用户
加急消息
加 / 删 / 查 reaction
置顶 / 取消置顶 / 查询置顶
群管理
创建群聊
删除群聊
修改群名称 / 描述 / 头像 / 群主
拉人入群
移出成员
设置 / 取消管理员
转让群主
获取群公告
patch 群公告
资源与基础信息
上传 / 下载图片
上传 / 下载文件
下载消息资源
批量下载消息内资源
查询用户信息
查询群列表
通过群名找群 ID
取群成员
通过成员名找 open_id
获取群名和用户名
重点能力
如果你想快速抓住这个模块最核心的扩展能力,优先关注这几组:
消息生命周期补齐
reply_messageforward_messagerecall_messageget_messageget_message_listedit_text_messageedit_post_messageedit_card_message
消息状态操作
get_message_read_usersurgent_messageadd_reaction/delete_reaction/list_reactionspin_message/unpin_message/list_pinned_messages
流式卡片回复
reply_streaming_cardupdate_streaming_cardrecolor_streaming_cardstream_reply_cardastream_reply_card
群管理增强
create_chat/update_chat/delete_chatadd_members_to_chat/remove_members_from_chatset_chat_admin/transfer_chat_ownerget_chat_announcement/set_chat_announcement
批量发消息
batch_send_message支持按用户 / 部门触达
如果你在做机器人业务闭环,最常见的组合一般是:
收到用户消息 ->
reply_message引用回复长任务开始 ->
reply_streaming_card-> 多次update_streaming_card-> 完成后recolor_streaming_card(..., template="green")告警消息 ->
forward_message给值班人 ->urgent_message加急重要结论 ->
reply_message->pin_message任务处理中 ->
add_reaction-> 完成 / 失败后delete_reaction项目群初始化 ->
create_chat->add_members_to_chat->set_chat_admin->send_card_to_chat
快速开始
from pywayne.lark_bot import LarkBot
bot = LarkBot(app_id="cli_xxx", app_secret="sec_xxx")
bot.send_text_to_user("ou_xxx", "你好")
bot.send_text_to_chat("oc_xxx", "群消息测试")
TextContent
TextContent 适合快速拼出飞书文本消息里常见的富文本标记。
常用方法:
make_at_all_pattern()make_at_someone_pattern(someone_open_id, username, id_type)make_bold_pattern(content)make_italian_pattern(content)make_underline_pattern(content)make_delete_line_pattern(content)make_url_pattern(url, text)
示例:构造一条带 @ 和链接的文本
from pywayne.lark_bot import LarkBot, TextContent
bot = LarkBot(app_id="cli_xxx", app_secret="sec_xxx")
msg = (
TextContent.make_at_someone_pattern("ou_xxx", "Wayne", "open_id")
+ " "
+ TextContent.make_bold_pattern("发布完成")
+ ",请查看 "
+ TextContent.make_url_pattern("https://example.com", "详情页")
)
bot.send_text_to_chat("oc_xxx", msg)
PostContent
PostContent 适合构造复杂 rich_text 富文本,尤其适合:
多段结构化说明
一行混排文字 / 链接 / @ / 图片
代码块
Markdown 分块发送
Markdown 表格降级为等宽代码块
常用方法:
make_text_contentmake_link_contentmake_at_contentmake_image_contentmake_media_contentmake_emoji_contentmake_hr_contentmake_code_block_contentmake_markdown_contentadd_markdownadd_content_in_lineadd_contents_in_lineadd_content_in_new_lineadd_contents_in_new_linelist_emoji_types
示例:混排 rich_text 消息
from pywayne.lark_bot import LarkBot, PostContent
bot = LarkBot(app_id="cli_xxx", app_secret="sec_xxx")
post = PostContent(title="发布通知")
post.add_contents_in_new_line([
post.make_text_content("构建完成", styles=["bold"]),
post.make_emoji_content("OK"),
])
post.add_contents_in_new_line([
post.make_link_content("查看 Jenkins", "https://jenkins.example.com"),
post.make_at_content("ou_xxx"),
])
post.add_content_in_new_line(
post.make_code_block_content("bash", "deploy.sh --env prod")
)
bot.send_rich_text_to_chat("oc_xxx", post.get_content())
示例:Markdown 表格安全降级
md = """
## 回归结果
| 模块 | 结果 | 负责人 |
| --- | --- | --- |
| 登录 | pass | Alice |
| 支付 | pass | Bob |
| 推荐 | running | Carol |
"""
post = PostContent(title="测试日报")
post.add_markdown(md, table_as="code_block", max_chunk_bytes=8000)
bot.send_rich_text_to_chat("oc_xxx", post.get_content())
CardContentV2
CardContentV2 是面向 schema 2.0 card 卡片的轻量构造器,适合大段 Markdown 公告、日报、状态展示。
常用方法:
add_markdownadd_hradd_imageget_cardlist_header_templates
示例:日报卡片
from pywayne.lark_bot import CardContentV2
card = CardContentV2(title="日报", template="blue")
card.add_markdown("# 今日进展\n\n- 接口联调完成\n- 修复 3 个问题\n- 代码已合并")
card.add_hr()
card.add_image("img_xxx")
bot.send_card_to_chat("oc_xxx", card.get_card())
示例:查看常用卡片头部模板色
from pywayne.tools import wayne_print
wayne_print(CardContentV2.list_header_templates(), color="cyan")
LarkBot 类
- class LarkBot(app_id: str, app_secret: str)
主应用机器人封装。
发送消息
文本
send_text_to_user(user_open_id, text)send_text_to_chat(chat_id, text)
bot.send_text_to_user("ou_xxx", "私聊你好")
bot.send_text_to_chat("oc_xxx", "群里你好")
图片
upload_image(image_path)send_image_to_user(user_open_id, image_key)send_image_to_chat(chat_id, image_key)download_image(image_key, image_save_path)
image_key = bot.upload_image("/tmp/report.png")
bot.send_image_to_chat("oc_xxx", image_key)
音频 / 媒体 / 文件
upload_file(file_path, file_type="stream")send_audio_to_user/send_audio_to_chatsend_media_to_user/send_media_to_chatsend_file_to_user/send_file_to_chatdownload_file(file_key, file_save_path)
opus_key = bot.upload_file("/tmp/voice.opus", file_type="opus")
bot.send_audio_to_chat("oc_xxx", opus_key)
mp4_key = bot.upload_file("/tmp/demo.mp4", file_type="mp4")
bot.send_media_to_chat("oc_xxx", mp4_key)
pdf_key = bot.upload_file("/tmp/spec.pdf", file_type="pdf")
bot.send_file_to_chat("oc_xxx", pdf_key)
rich_text 富文本
send_rich_text_to_usersend_rich_text_to_chat
post = PostContent(title="值班提醒")
post.add_content_in_new_line(post.make_text_content("今晚 20:00 发布", styles=["bold"]))
bot.send_rich_text_to_chat("oc_xxx", post.get_content())
card 卡片
send_card_to_usersend_card_to_chat
bot.send_card_to_chat(
"oc_xxx",
{
"header": {"title": {"content": "状态卡片", "tag": "plain_text"}},
"elements": [{"tag": "markdown", "content": "**服务正常**"}]
}
)
分享消息
share_chat_to_user/share_chat_to_chatshare_user_to_user/share_user_to_chat
系统消息
send_system_message_to_user
适合做系统通知类场景,不走普通文本样式。
推荐入口:send_markdown_message_to_chat
- send_markdown_message_to_chat(chat_id: str, md_text: str, *, title: str = '', prefer: str = 'card_v2', table_fallback: str = 'code_block', max_message_bytes: int | None = None)
这是推荐的高层发送入口,适合绝大多数“我要发 Markdown”场景。
特性:
自动按字节分包
支持
card_v2与post两条发送路由post路由下支持表格降级
示例 1:默认发 schema 2.0 卡片
bot.send_markdown_message_to_chat(
"oc_xxx",
md_text="# 发布完成\n\n- API: pass\n- Worker: pass",
title="发布结果"
)
示例 2:强制走 rich_text 路由,并处理 Markdown 表格
bot.send_markdown_message_to_chat(
"oc_xxx",
md_text="""
# 回归看板
| 模块 | 状态 |
| --- | --- |
| 登录 | pass |
| 支付 | pass |
""",
title="回归结果",
prefer="post",
table_fallback="code_block"
)
示例 3:超长日报自动分片
bot.send_markdown_message_to_chat(
"oc_xxx",
md_text=very_long_markdown,
title="长文日报",
prefer="card_v2",
max_message_bytes=12000
)
消息后处理
引用回复
- reply_message(message_id: str, msg_type: str, content, *, reply_in_thread: bool = False, uuid: str = '')
这是监听场景里最常用的方法。
示例:引用回复文本
bot.reply_message(
message_id="om_xxx",
msg_type="text",
content={"text": "收到文本"}
)
示例:在线程中回复
bot.reply_message(
message_id="om_xxx",
msg_type="text",
content={"text": "这条回复会进入 thread"},
reply_in_thread=True
)
示例:引用回复卡片
card = CardContentV2(title="处理结果")
card.add_markdown("已收到你的请求,正在执行。")
bot.reply_message("om_xxx", "interactive", card.get_card())
示例:按消息类型动态引用回复
def reply_by_type(message_id: str, kind: str):
mapping = {
"text": "收到文本",
"image": "收到图片",
"file": "收到文件",
"audio": "收到音频",
"post": "收到 rich_text",
"interactive": "收到 card",
}
bot.reply_message(
message_id,
"text",
{"text": mapping.get(kind, f"收到 {kind}")}
)
转发消息
- forward_message(message_id: str, receive_id: str, *, receive_id_type: str = 'chat_id', uuid: str = '')
示例:把群里的告警转发给值班人
bot.forward_message(
message_id="om_alert_xxx",
receive_id="ou_duty_xxx",
receive_id_type="open_id"
)
示例:先引用回复,再把原始消息转发给二线支持
bot.reply_message("om_xxx", "text", {"text": "已转交二线支持"})
bot.forward_message("om_xxx", "ou_level2_xxx", receive_id_type="open_id")
撤回消息
- recall_message(message_id: str)
适合“发错消息立即撤回”或“临时状态消息在成功后撤回”。
示例:短暂提示后立即撤回
sent = bot.send_text_to_chat("oc_xxx", "这是一条临时提示")
bot.recall_message(sent["message_id"])
查询消息
get_message(message_id)get_message_list(chat_id, start_time, end_time, sort_type="", page_size=50, page_token="")
示例:拉取某时间范围内的历史消息
history = bot.get_message_list(
chat_id="oc_xxx",
start_time="1735603200000",
end_time="1735689600000",
sort_type="ByCreateTimeAsc"
)
示例:先查单条消息,再决定是否转发
detail = bot.get_message("om_xxx")
content = detail["body"]["content"]
if "紧急" in content:
bot.forward_message("om_xxx", "ou_duty_xxx", receive_id_type="open_id")
编辑消息
edit_text_message(message_id, text)edit_post_message(message_id, post_content)edit_card_message(message_id, card)
注意:
edit_text_message/edit_post_message底层对应飞书PUT /im/v1/messages/:message_id,只适用于text/post消息,也就是文本 / rich_text 消息edit_card_message底层对应飞书卡片更新接口,适用于交互式卡片;做“同一条消息持续刷新”的效果时,通常也是走卡片更新飞书官方限制一条消息最多编辑
20次;且只能编辑自己发送、未撤回、未超出可编辑时间的消息文本 / 富文本和卡片更新接口是分开的,不能混用;例如不能拿卡片 JSON 去调
edit_text_message/edit_post_message如果你只是想按消息类型做原位编辑,优先使用这 3 个
edit_*接口,不再需要区分旧的底层方法名
示例:把“处理中”卡片更新成“已完成”
bot.edit_card_message(
message_id="om_xxx",
card={
"type": "template",
"data": {
"template_id": "AAqC5c999",
"template_variable": {"status": "已完成"}
}
}
)
示例:先发文本,再更新文本内容
sent = bot.send_text_to_chat("oc_xxx", "初版结论")
bot.edit_text_message(sent["message_id"], "初版结论\n补充说明:影响范围仅限灰度环境")
示例:先发富文本,再更新富文本内容
post = PostContent(title="阶段播报")
post.add_markdown("第一版结果")
sent = bot.send_rich_text_to_chat("oc_xxx", post.get_content())
post2 = PostContent(title="阶段播报")
post2.add_markdown("第一版结果\n\n补充:已完成二次校验")
bot.edit_post_message(sent["message_id"], post2.get_content())
示例:直接编辑已发送的卡片
bot.edit_card_message(
"om_xxx",
{
"type": "template",
"data": {
"template_id": "AAqC5c999",
"template_variable": {"status": "处理中", "detail": "第 2 步 / 共 5 步"}
}
}
)
已读与加急
get_message_read_users(message_id, ...)urgent_message(message_id, urgent_type, user_open_ids, ...)
urgent_type 支持:
appphonesms
示例:先发消息,再给值班人加急
sent = bot.send_text_to_chat("oc_xxx", "生产告警,请处理")
bot.urgent_message(
sent["message_id"],
urgent_type="app",
user_open_ids=["ou_duty_xxx"]
)
示例:查询哪些人已读,再决定是否继续催办
readers = bot.get_message_read_users("om_xxx")
if not readers.get("items"):
bot.urgent_message("om_xxx", "sms", ["ou_duty_xxx"])
reaction
add_reaction(message_id, emoji_type)delete_reaction(message_id, reaction_id)list_reactions(message_id, ...)
emoji_type 使用飞书 reaction code,不是 Unicode 字符。
常用值包括:
THUMBSUPOKHEARTHAHAWITTY
完整列表可通过 PostContent.list_emoji_types() 打开飞书官方表情页。
示例:临时 reaction
reaction = bot.add_reaction("om_xxx", "THUMBSUP")
bot.delete_reaction("om_xxx", reaction["reaction_id"])
示例:统计某条消息有哪些 reaction
from pywayne.tools import wayne_print
data = bot.list_reactions("om_xxx")
wayne_print(data, color="cyan")
示例:把 reaction 当作任务状态灯
reaction = bot.add_reaction("om_xxx", "WITTY")
try:
bot.reply_message("om_xxx", "text", {"text": "处理中"})
except Exception:
bot.add_reaction("om_xxx", "HAHA")
raise
finally:
bot.delete_reaction("om_xxx", reaction["reaction_id"])
置顶
pin_message(message_id)unpin_message(message_id)list_pinned_messages(chat_id, ...)
示例:先回复,再置顶
reply = bot.reply_message("om_xxx", "text", {"text": "这是最终结论"})
bot.pin_message(reply["message_id"])
示例:查询置顶消息并输出摘要
from pywayne.tools import wayne_print
pinned = bot.list_pinned_messages("oc_xxx")
for item in pinned.get("items", []):
wayne_print(item["message_id"], color="cyan")
流式卡片回复
这一组方法用于“先回复一张卡片,再不断原位刷新同一张卡片内容”,适合接 LLM 流式输出。
build_streaming_card(md_text, ...)reply_streaming_card(message_id, ...)update_streaming_card(message_id, md_text, ...)recolor_streaming_card(message_id, md_text, ...)stream_reply_card(source_message_id, text_stream, ...)astream_reply_card(source_message_id, text_stream, ...)
设计约束:
走的是“先发 card 卡片,再反复更新该消息”的路径
更新时传入的是“当前完整文本”,不是 delta
默认
update_interval=0.25,是为了尽量避开单消息高频更新限制卡片默认带
config.update_multi=true颜色不是任意 RGB,而是飞书卡片头部的预设模板色
final_template用于流式结束后的最终颜色recolor_streaming_card适合手动切换为成功 / 失败 / 警告状态色
常用头部模板色:
bluewathetturquoisegreenyelloworangeredcarminevioletpurpleindigogrey
你也可以直接调用 CardContentV2.list_header_templates() 获取当前内置常用列表。
示例 1:手工启动 + 手工更新
reply = bot.reply_streaming_card(
"om_xxx",
title="AI 回复中",
initial_md="正在思考..."
)
card_message_id = reply["message_id"]
bot.update_streaming_card(card_message_id, "第一段输出", title="AI 回复中")
bot.update_streaming_card(card_message_id, "完整输出内容", title="AI 回复完成", done=True)
示例 2:完成后自动从蓝色切到绿色
def fake_stream():
yield "第一段输出\\n"
yield "第二段输出\\n"
yield "第三段输出\\n"
result = bot.stream_reply_card(
"om_xxx",
fake_stream(),
title="AI 回复中",
template="blue",
final_template="green",
status_text="生成中...",
final_status_text="已完成"
)
示例 3:失败时改成红色
reply = bot.reply_streaming_card(
"om_xxx",
title="任务执行中",
template="blue",
initial_md="开始执行..."
)
card_message_id = reply["message_id"]
try:
bot.update_streaming_card(card_message_id, "步骤 1 成功\\n步骤 2 成功", title="任务执行中")
raise RuntimeError("第三步失败")
except Exception as exc:
bot.recolor_streaming_card(
card_message_id,
f"步骤 1 成功\\n步骤 2 成功\\n\\n错误信息:{exc}",
title="任务执行失败",
template="red",
status_text="执行失败",
done=True
)
示例 4:逐字更新,完成后自动变绿色
import time
def char_stream():
sentence = "这是一个逐字流式卡片回复示例。"
for ch in sentence:
yield ch
time.sleep(0.3)
bot.stream_reply_card(
"om_xxx",
char_stream(),
title="逐字输出中",
template="blue",
final_template="green",
status_text="生成中...",
final_status_text="已完成",
update_interval=0.25
)
示例 5:处理中为蓝色,待人工确认切橙色,最终完成切绿色
reply = bot.reply_streaming_card(
"om_xxx",
title="审批任务",
template="blue",
initial_md="系统已开始自动分析"
)
card_message_id = reply["message_id"]
bot.update_streaming_card(
card_message_id,
"自动分析完成,等待人工确认",
title="审批任务",
template="orange",
done=False,
status_text="等待人工确认"
)
bot.recolor_streaming_card(
card_message_id,
"自动分析完成\n人工确认通过",
title="审批任务",
template="green",
status_text="已完成"
)
示例 6:直接消费同步生成器
def fake_stream():
yield "你好,"
yield "这是"
yield "一段流式输出。"
result = bot.stream_reply_card(
"om_xxx",
fake_stream(),
title="AI 回复中"
)
示例 7:异步生成器版本
async def fake_astream():
yield "第一段"
yield "第二段"
result = await bot.astream_reply_card(
"om_xxx",
fake_astream(),
title="AI 回复中",
template="wathet",
final_template="green",
final_status_text="回答完成"
)
群管理
创建 / 删除 / 更新群
create_chatdelete_chatupdate_chattransfer_chat_owner
示例:创建一个项目群并设置群主
chat = bot.create_chat(
name="项目 Alpha",
user_open_ids=["ou_a", "ou_b", "ou_c"],
description="Alpha 项目协作群",
owner_open_id="ou_a"
)
示例:修改群资料
bot.update_chat(
chat_id="oc_xxx",
name="项目 Alpha - 灰度群",
description="用于灰度发布值守"
)
示例:转让群主后再更新群描述
bot.transfer_chat_owner("oc_xxx", "ou_new_owner")
bot.update_chat(
chat_id="oc_xxx",
description="群主已更新,请按新流程协作"
)
成员管理
add_members_to_chatremove_members_from_chatset_chat_admin
示例:加人并设置管理员
bot.add_members_to_chat("oc_xxx", ["ou_dev1", "ou_dev2"])
bot.set_chat_admin("oc_xxx", ["ou_dev1"], is_admin=True)
示例:移除管理员权限
bot.set_chat_admin("oc_xxx", ["ou_dev1"], is_admin=False)
示例:拉人、踢人、再补发说明
bot.add_members_to_chat("oc_xxx", ["ou_new1", "ou_new2"])
bot.remove_members_from_chat("oc_xxx", ["ou_old1"])
bot.send_text_to_chat("oc_xxx", "成员已调整,请关注新的值班安排")
群公告
get_chat_announcementset_chat_announcement
set_chat_announcement 走的是飞书 patch 语义,参数 requests 需要直接传飞书公告 API 的 patch 操作列表。
示例:读取公告
announcement = bot.get_chat_announcement("oc_xxx")
示例:用 patch 语义更新公告
bot.set_chat_announcement(
"oc_xxx",
requests=[
{
"op": "replace",
"path": "/content",
"value": "今晚 23:00 维护,请提前保存工作内容。"
}
]
)
资源与下载
下载单条消息中的资源
download_message_resource(message_id, resource_type, save_path, file_key=None)
resource_type 常见取值:
imagefileaudiomediavideo
示例:下载图片消息中的原图
bot.download_message_resource(
message_id="om_xxx",
resource_type="image",
save_path="/tmp/msg.png",
file_key="img_xxx"
)
批量下载消息中的全部资源
download_message_resources(message_id, message_content, save_dir)
适合“你已经拿到消息正文 JSON,想把里面所有 file_key/image_key 对应的资源一次性落盘”。
示例:下载一条消息中的全部资源后统一归档
import json
detail = bot.get_message("om_xxx")
content = json.loads(detail["body"]["content"])
bot.download_message_resources("om_xxx", content, "/tmp/msg_assets")
用户与群信息
get_user_info(emails, mobiles)get_group_list()find_chat_ids_by_name(group_name)get_chat_members(chat_id)find_member_open_ids_by_name(chat_id, member_name)get_chat_and_user_name(chat_id, user_id)
示例:按群名查 ID,再按用户名查成员 open_id
chat_ids = bot.find_chat_ids_by_name("项目 Alpha")
if chat_ids:
open_ids = bot.find_member_open_ids_by_name(chat_ids[0], "Wayne")
示例:同时查群名和发件人姓名
group_name, user_name = bot.get_chat_and_user_name("oc_xxx", "ou_xxx")
批量发送
- batch_send_message(msg_type: str, *, content=None, card=None, user_open_ids=None, department_ids=None, user_ids=None, union_ids=None)
这不是发到群,而是批量发给用户或部门。
特点:
底层走
/message/v4/batch_send/支持文本和卡片
支持 open_id / user_id / union_id / department_id 目标
批量消息不是普通群消息,不能像普通消息那样引用回复
示例:批量发文本通知
bot.batch_send_message(
"text",
content="今晚 23:00 系统维护",
user_open_ids=["ou_a", "ou_b", "ou_c"]
)
示例:批量发卡片
bot.batch_send_message(
"interactive",
card={
"header": {"title": {"content": "运维通知", "tag": "plain_text"}},
"elements": [{"tag": "markdown", "content": "请及时确认"}]
},
department_ids=["od_xxx"]
)
示例:批量发通知后轮询进度
from pywayne.tools import wayne_print
result = bot.batch_send_message(
"text",
content="请在今晚 18:00 前完成确认",
user_open_ids=["ou_a", "ou_b"]
)
task_id = result.get("task_id")
if task_id:
progress = bot.get_batch_message_progress(task_id)
wayne_print(progress, color="cyan")
组合场景示例
场景 1:发日报卡片,用户点击后再原位更新
card = CardContentV2(title="日报提交")
card.add_markdown("请点击按钮确认今天已提交日报。")
bot.send_card_to_chat("oc_xxx", card.get_card())
# 按钮点击后的更新逻辑放到 LarkBotListener.card_action_handler 中处理
场景 2:收到用户消息后引用回复,并把回复置顶
reply = bot.reply_message("om_xxx", "text", {"text": "这是最终处理结论"})
bot.pin_message(reply["message_id"])
场景 3:先发“处理中”,完成后更新成最终状态
msg = bot.send_card_to_chat(
"oc_xxx",
{
"header": {"title": {"content": "任务状态", "tag": "plain_text"}},
"elements": [{"tag": "markdown", "content": "处理中..."}]
}
)
bot.edit_card_message(
msg["message_id"],
{
"header": {"title": {"content": "任务状态", "tag": "plain_text"}},
"elements": [{"tag": "markdown", "content": "已完成"}]
}
)
场景 4:收到告警后,转发给值班人并加急
bot.forward_message("om_alert_xxx", "ou_duty_xxx", receive_id_type="open_id")
bot.urgent_message("om_alert_xxx", "app", ["ou_duty_xxx"])
场景 5:使用 reaction 作为处理中状态
reaction = bot.add_reaction("om_xxx", "WITTY")
try:
bot.reply_message("om_xxx", "text", {"text": "处理中"})
finally:
bot.delete_reaction("om_xxx", reaction["reaction_id"])
场景 5.1:把 LLM 流式输出刷到同一张回复卡片上
def llm_stream():
yield "今天的分析如下:\n\n"
yield "1. 指标整体稳定\n"
yield "2. 风险点主要在支付链路\n"
yield "3. 建议先观察 30 分钟\n"
bot.stream_reply_card(
"om_xxx",
llm_stream(),
title="分析结果生成中",
final_status_text="已完成"
)
场景 5.2:逐字流式输出,完成态改绿色,失败态改红色
import time
reply = bot.reply_streaming_card(
"om_xxx",
title="逐字输出测试",
template="blue",
initial_md=""
)
card_message_id = reply["message_id"]
text = "这是一段逐字输出的测试文本。"
current = ""
try:
for ch in text:
current += ch
bot.update_streaming_card(
card_message_id,
current,
title="逐字输出测试",
template="blue",
status_text="生成中..."
)
time.sleep(0.3)
bot.recolor_streaming_card(
card_message_id,
current,
title="逐字输出测试",
template="green",
status_text="已完成"
)
except Exception as exc:
bot.recolor_streaming_card(
card_message_id,
current + f"\n\n错误信息:{exc}",
title="逐字输出测试",
template="red",
status_text="失败"
)
场景 6:创建专项群,拉人,设管理员,发欢迎卡片
group = bot.create_chat(
name="专项推进群",
user_open_ids=["ou_a", "ou_b", "ou_c"],
description="专项推进"
)
chat_id = group["chat_id"]
bot.set_chat_admin(chat_id, ["ou_a"], is_admin=True)
card = CardContentV2(title="欢迎加入")
card.add_markdown("请查看群公告并完成本周任务认领。")
bot.send_card_to_chat(chat_id, card.get_card())
场景 7:长 Markdown 公告自动切片发送
bot.send_markdown_message_to_chat(
"oc_xxx",
md_text=huge_release_note,
title="发布说明",
prefer="card_v2",
max_message_bytes=10000
)
场景 8:按名字找目标群和目标人,再定向发送
chat_ids = bot.find_chat_ids_by_name("值班群")
if chat_ids:
bot.send_text_to_chat(chat_ids[0], "今晚注意观察监控")
open_ids = bot.find_member_open_ids_by_name(chat_ids[0], "Wayne")
if open_ids:
bot.send_text_to_user(open_ids[0], "请确认值班")
场景 8.1:先按群名查群,再发送长 Markdown 卡片
chat_ids = bot.find_chat_ids_by_name("测试3")
if chat_ids:
bot.send_markdown_message_to_chat(
chat_ids[0],
md_text="# 自动通知\n\n- 功能已发布\n- 请在群内验证",
title="系统通知"
)
场景 9:下载消息附件后再二次转发
bot.download_message_resource("om_xxx", "file", "/tmp/input.pdf", "file_xxx")
new_key = bot.upload_file("/tmp/input.pdf", file_type="pdf")
bot.send_file_to_chat("oc_other_xxx", new_key)
场景 10:读取群公告并同步成卡片消息
data = bot.get_chat_announcement("oc_xxx")
card = CardContentV2(title="当前群公告")
card.add_markdown(str(data))
bot.send_card_to_chat("oc_xxx", card.get_card())
场景 11:查消息详情 -> 转发 -> 加急 -> 置顶结论
detail = bot.get_message("om_alert_xxx")
if "严重" in detail["body"]["content"]:
bot.forward_message("om_alert_xxx", "ou_duty_xxx", receive_id_type="open_id")
bot.urgent_message("om_alert_xxx", "app", ["ou_duty_xxx"])
reply = bot.reply_message("om_alert_xxx", "text", {"text": "已转交值班并加急"})
bot.pin_message(reply["message_id"])
注意事项
reply_message的content会被自动 JSON 序列化;文本消息通常传{"text": "..."}。interactive这个飞书类型值对应的是 card 卡片;发送与更新时,传入的是卡片 JSON,不需要你手动再做json.dumps。reaction的emoji_type不是表情符号本身,而是飞书定义的名称。batch_send_message面向用户 / 部门,不面向群;它和群消息的生命周期不同。set_chat_announcement目前直接暴露飞书 patch 风格参数,适合需要精确控制公告 patch 的场景。流式卡片更新传入的是“当前完整文本”,不是本次新增片段;如果你只传 delta,卡片内容会丢前文。
卡片颜色使用的是飞书头部模板色,不是任意 RGB;完成自动变绿需要显式传
final_template="green"或手动recolor_streaming_card。