Files
Starlight_Lancher/.agents/skills/lark-im/references/card/lark-im-card-create.md

11 KiB
Raw Blame History

发送 Interactive 卡片工作流

用户需要发送一张飞书互动卡片时,遵循本工作流。每次都必须严格按步骤执行。


入口分支:文字 / 图片 / 图片+文字组合

判断用户输入类型:

  • 纯文字诉求(无图片)→ 跳到 Step 1「文字诉求路径」。
  • 纯图片(截图 / 设计稿,无额外文字说明内容)→ 走「以图片为输入」路径,图片既是内容源也是风格源。
  • 图片 + 文字组合 → 走「以图片为输入」路径,但图片仅当样式/布局参考,内容来源以文字为准(见第 5 点)。

以图片为输入时的处理

  1. 分析图片:从图片中提取视觉风格信息——

    • 配色方案(色环定位)、间距节奏、层级关系、分组方式、组件类型
    • 图片类型(见第 2 点)
  2. 判断图片类型,决定保真策略:

    图片类型 判断依据 构造策略
    飞书卡片截图 能识别出 header / body / components 等飞书卡片结构特征 高保真复刻:将截图中每一块视觉结构映射到相近的卡片 2.0 组件;复刻后仍需过 P0P7 硬 Gate
    其它设计稿 / 海报 / 网页 UI 无飞书卡片结构特征 风格萃取 + 按原则重构:提取配色、间距、层级关系等风格 token布局按 P0P7 原则重构(不像素级仿制),产出说明偏差
  3. 确定内容来源

    • 纯图片:从图片提取内容/信息点(文字、字段、操作)作为诉求(喂给 P0
    • 图片 + 文字组合以文字/文档为内容来源,图片仅提供样式和布局参考。将文字内容按图片风格组织进卡片
  4. 冲突处理:当图片样式与 P0P7 或卡片组件能力冲突时——

    • 飞书卡片截图:在组件能力允许范围内尽量保真,冲突处微调并告知用户偏差原因
    • 其它设计稿 / 海报 / UI以 P0P7 为准,图片仅当风格参考,冲突时不硬搬
  5. 分析明确后,向用户简要说明你的类型判断结论 + 保真策略 + 内容来源方案。然后进入 Step 2 加载组件文档,进入构造。


Step 1文字诉求路径分析意图输出设计方案

目标:在动手写 JSON 之前先明确所有决策并告知用户。Step 2 的文档加载量取决于这里的组件列表,所以要尽量在这一步想清楚。

分析以下内容并向用户简要说明:

  1. 版本Card 2.0 支持的组件更丰富,推荐使用 Card 2.0;仅当用户明确要求 1.0 时才用 1.0。
  2. 组件组合:在 lark-im-card-style.md 「意图 → 组件组合」表里匹配最接近的意图行,参考推荐组件组合和该行的 header.template 颜色(部分行为"无 header")。推荐组合仅供参考,最终选型以符合用户意图为准;使用 Card 2.0 时,可同时参考 card-2.0-schema.md 中的组件概述来补充或调整组件选择。
  3. 交互类型若有是否含会回调服务端的交互组件以及是否有纯跳转open_url。回调分两类select / multi_select / input / picker / overflow 操作即默认回调;② button / checker / interactive_container 需显式配置 behaviorsform 提交统一回调。细则见 Step 5。
  4. 宽度模式compact(400px) 适合通知/祝福/轻提醒(内容精简、单焦点);default(≤600px) 适合大多数场景;fill(撑满) 适合数据看板、含 table 的宽表格。默认 default,有明确理由才偏离。

输出示例:"Card 2.0header greendefault,组件:column_set / column / markdown,无交互。"


Step 2按需加载组件文档

⚠️ 仅 Card 2.0 适用card-2.0-schema.mdcomponents/ 明细都是 2.0 结构。若 Step 1 定为 Card 1.0(含 Step 4 降级场景),这些不可参考,跳过本步,直接按 1.0 结构构造。

目标:读组件明细 + 「好看的标准」,不全量加载。

组件列表来源:文字路径 = Step 1 的设计方案;图片路径 = 入口分支图片分析阶段确定的组件列表。

  1. 阅读 card-2.0-schema.md —— 同时满足两个目的:① 了解组件概述,辅助组件选型;② 找到各组件的明细文档路由链接。仅读一次,不重复加载。
  2. 按路由逐个读取 components/<tag>.md(如 components/column_set.mdcomponents/button.md
  3. 阅读 lark-im-card-style.md 开头的「好看的标准P0P7」和「视觉规范」——这是 Step 3 构造和自检的裁判基准,构造前先内化

Step 3构造卡片 JSON

按 Step 2 中对应版本的根结构骨架构造卡片,组件选型遵循 Step 1或图片分析阶段的设计方案。

  • Card 2.0 必须有 "schema": "2.0",否则卡片不渲染
  • form 容器内按钮用 form_action_type: "submit",不写 behaviors
  • column_set 的子节点只能是 column,不能直接放其他组件
  • table 只能放 body 根节点,不能嵌套进 column_set / interactive_container 等容器
  • collapsible_panel不能包含 forminteractive_container不能包含 form/table

发送前硬 Gate按 P0P7 自检,不过不许进 Step 4

构造完成后,逐条用 lark-im-card-style.md 的「好看的标准」做结构化自检P0 + P1P3 是阻断项,任一不过必须回到本步修正后重判,不得带病发送。

阻断项(必须全过):

  • P0 符合诉求:把用户诉求拆成信息点清单,逐点在 JSON 里找到承载组件;需要的操作(按钮/表单/跳转)都齐备;无与诉求无关的填充
  • P1 层级body 内有且仅有一个最强焦点;标题用 **加粗** 与正文拉开,次要信息用 grey
  • P2 分组:同主题字段收进同一容器,不同主题分容器;没有「一路 hr 平铺」或多主题挤在同一 markdown
  • P3 复杂度适中:视觉块 25 个、主色系 ≤3且 >1 个块、至少含一个非纯文本结构元素(背景块/指标卡/图标/表格)——既不能纯文字流水账,也不能堆砌过载

基础卫生(应满足):

  • P4 对比:标题与正文在字号或粗细上至少差一档;正文不滥用 #/##/###(指标卡数值放大除外)
  • P5 对齐:不滥用散设 margin,间距优先交容器;间距取值种类 ≤4非末尾顶级容器间距一致

加分项(尽量满足):

  • P6 语义一致:同色同义(红=降/警、绿=升/成、grey=次要);主色系起始色与 header 一致、取邻近色环
  • P7 健壮:并列/指标列默认 weighted/none、慎用 stretch;必要时配 config.style.color light/dark

Step 4发送卡片

# 发送到群聊
lark-cli im +messages-send --chat-id oc_xxx --msg-type interactive --content '<card_json>'

# 发送给指定用户(私聊)
lark-cli im +messages-send --user-id ou_xxx --msg-type interactive --content '<card_json>'

发送失败时:先对照下方常见失败列表排查,若能匹配则按对应处理方式修复后重新发送;否则根据错误信息修复 JSON 后重新发送。最多尝试 3 次。若 3 次后仍失败,降级为 Card 1.0 卡片重新构造并发送。不参考之前发送 2.0 的记忆,完全根据用户意图重新构造 1.0 卡片。1.0 无本地参考文档components/、resource/ 均为 2.0)。 常见失败列表

# 错误信息 处理方式
1 there is an invalid user resource (at/person) in your card 卡片中含有 at/person 组件,但使用了无效的用户 ID。询问用户其真实的 open_id / user_id替换后重新发送。

Step 5交互回调可选

若卡片含会回调服务端的交互组件,则支持监听 card.action.trigger 回调(是否监听由实际需求决定,非必须):

需显式配置 behaviors: [{type:"callback"}] 才会回调:

  • button(带 callback behavior
  • checker —— 未配置 behaviors 时仅本地勾选生效,不触发服务端回调
  • interactive_container —— behaviors 为必填,支持 callback / open_url

选中 / 输入即默认回调,无需显式 behaviors

  • select_static / multi_select_static / select_person / multi_select_person
  • overflow / input / date_picker / picker_time / picker_datetime

form 提交统一回调(按钮用 form_action_type: "submit",无需 behaviors

  • form 内所有表单组件的值通过 action.form_value 一次性回传

open_url 跳转按钮在客户端本地跳转,不回调服务端。

如需处理回调(监听事件、读取字段、更新卡片),见 ../lark-im-card-action-reply.md


Step 6用户反馈修正按需进入

用户看到已发送卡片后提出修改意见时,遵循以下流程。不要整卡重做,外科手术式修改。

1. 定位改动范围

把用户意见逐条映射到具体组件和字段:

用户反馈类型 映射目标
文案/措辞不满意 对应 markdown.content / button.text / header.title
颜色/风格不满意 对应 background_style / font_color / header.template / config color token
布局/排列不满意 对应 column_set.flex_mode / width / weight / padding
缺少某个字段/信息 新增 div.fields 条目或 markdown
某个块太拥挤/太空 调整 padding / vertical_spacing / margin
交互行为问题 对应 behaviors / confirm / disabled

2. 最小改动原则

  • 只改被指出的组件,不动周边结构。
  • 改完后只对被修改组件所涉及的 P 项重新自检(改颜色 → 过 P6改分组 → 过 P1+P2改间距 → 过 P5

3. 重发

修正完成后,重新发送一张新卡(同 Step 4告知用户"已重新发送修正版"。

4. 执行前告知

向用户复述"我将修改 ×××",确认后再执行,不要静默改动。


执行清单

  • 入口:判断是文字诉求(→ Step 1还是图片输入→ 图片分支 → 判断类型→保真策略→组件映射)
  • Step 1分析意图输出设计方案版本 / 宽度模式 / 颜色 / 组件)
  • Step 2读 schema.md + 组件明细 + 「好看的标准 P0P7」
  • Step 3构造 JSON → 过 P0P7 硬 GateP0+P1P3 阻断),不过先修
  • Step 4发送失败按常见失败表排查重试≤3 次);仍失败则降级 Card 1.0 重构发送
  • Step 5若有交互参考 ../lark-im-card-action-reply.md
  • Step 6用户提出修改意见时定位组件→最小改动→原地更新或重发