这是「飞书对接」小专题的第2篇,共5篇,从《MCP实战手记(十一):MCP接飞书,从机器人到事件订阅的三层深度接入》延伸(对应正文第2层自建应用卡片消息)。
第1层群机器人只能POST一段文本,店长看到的是一行字。但零售场景里,店长要的是"一张能看的卡":销售数字、库存水位、补货按钮。文本到富卡片,是飞书对接从"能通知"到"能用"的跨越。卡片怎么搭、按钮回调怎么接、以及生产最容易翻车的出站频控,一次性讲清。
卡片1.0还是2.0?
飞书卡片有两套协议,字段结构不同:
- 卡片1.0:顶层
config+header+elements,文本用text.tag = lark_md。兼容最广,本文实测跑通用这套。 - 卡片2.0:
schema: "2.0"+body.elements,文本用text.tag = markdown。新项目可用,迁移时注意字段差异。
本篇示例用1.0,先把链路跑通最重要。
一张门店数据卡怎么搭
把@Tool查回来的结果渲染成 interactive card,店长一眼看到重点,还能直接点按钮:
{"config":{"wide_screen_mode":true},"header":{"title":{"tag":"plain_text","content":"门店助手·查询成功"},"template":"green"},"elements":[{"tag":"div","text":{"tag":"lark_md","content":"**指令**:查库存ST001\n\nSKU-1001库存23(安全线50)"}},{"tag":"action","actions":[{"tag":"button","text":{"tag":"plain_text","content":"补货"},"value":{"sku":"SKU-1001"}}]}]}wide_screen_mode宽屏更适配桌面飞书;template: green是卡片头配色;action里的button带value,点下去会把sku回传回去。
按钮回调怎么接
店长点"补货",飞书会发一个卡片回调事件(action 触发),服务端要处理它。两层都要配:
- 应用后台登记"卡片回调"地址(和事件订阅同一个长连接/回调通道)。
- handler 里读
action.value,按sku调补货工具,再回一张新卡。
// 卡片action回调(节选自 dispatch)if("补货".equals(action.getActionTag())){Stringsku=action.getValue().get("sku");// 取回按钮带的 skuRestockResultr=storeService.suggestRestock(storeCode,sku);apiClient.im().message().reply(buildCard("补货建议",r));// 回一张新卡}关键点:按钮的value是状态通道,别在卡片里塞大段业务数据——只带最小标识(sku/storeCode),真查还在服务端做。
出站频控 + 退避重试(生产必加)
飞书消息发送不是无限发,有频控+失败重试语义。裸发容易踩RateLimitException。技术4.4要求生产加退避重试:
// 退避重试(飞书频控 + 瞬时失败):指数退避 + 随机抖动intattempt=0;while(attempt<3){try{apiClient.im().message().send(req);break;}catch(RateLimitExceptione){longbase=(1L<<attempt)*500;// 0.5s / 1s / 2slongjitter=ThreadLocalRandom.current().nextLong(0,500);// 抖动,错开重试Thread.sleep(base+jitter);attempt++;}}指数退避+抖动是标配:第1次等0.5s、第2次1s、第3次2s,避免重试把飞书打得更限流。
三个坑
坑一:卡片回调地址没配。按钮点了没反应,多半是应用后台"卡片回调"地址没登记,或和事件订阅通道没打通。
坑二:文本 tag 写错。1.0用lark_md、2.0用markdown,写反了飞书直接按纯文本渲染,markdown 符号全暴露。
坑三:卡片太长被截断。门店数据一多就堆,宽屏模式也救不了超长内容。卡片是"摘要视图",细节走链接或二次查询,别把整张报表塞进去。
小结
文本能通知,卡片才"能用"。把@Tool结果渲染成富卡片+按钮回调,店长从"看一行字"变成"看卡+点按钮办事"。生产别忘了出站频控与退避重试——否则大促一波推送就能把你限流到掉消息。
同专题推荐
本文是「飞书对接」小专题的第2篇,共5篇:
- 飞书长连接事件订阅实战:个人本机 5 分钟跑通,生产要补两块
- 飞书卡片消息构建实战:从文本到可交互富卡片(← 当前这篇)
- 飞书用户身份与多租户数据隔离:店长只看自己门店(链接待补)
- 飞书事件安全:签名校验与消息加解密(链接待补)
- 钉钉接入实战与平台横向差距(链接待补)
相关阅读
- 《MCP实战手记(十一):MCP接飞书,从机器人到事件订阅的三层深度接入》
- 《MCP实战手记系列(九):生产化 MCP Server 的 6 层安全防护》(身份透传底座)
- 《MCP实战手记系列(八):无状态之后的生产落地清单》(Server 无状态可水平扩展)
- 《MCP实战手记系列(十):MCP Server 高可用实战》(6工具复用 StoreService)
- 配套代码:https://gitee.com/ethanliang2016/mcp-in-action(模块
11-feishu,tagv11)