Zoom Team Chat 消息卡片结构详解:Chatbot API 富交互消息的 JSON 设计与实战
2026/9/14 19:24:35 网站建设 项目流程

Zoom Team Chat 消息卡片结构详解:Chatbot API 富交互消息的 JSON 设计与实战

【免费下载链接】knowledge-work-pluginsOpen source repository of plugins primarily intended for knowledge workers to use in Claude Cowork项目地址: https://gitcode.com/GitHub_Trending/kn/knowledge-work-plugins

导读

本文聚焦 Zoom Team Chat 集成中 Chatbot API(机器人类型)的核心能力——消息卡片(Message Card),讲解其类卡片 JSON 结构(content.headcontent.body)的完整设计、全部组件类型、交互机制与常见坑点。阅读后你将能独立构造包含标题、文本、键值字段、按钮、下拉框、表单与图片附件的富交互消息,并通过POST /v2/im/chat/messages发送给用户,再借助interactive_message_actions交互 Webhook 处理用户点击。相关权威素材见 Message Card Components Reference 与 Message Card Structure(概念文档)。

一、消息卡片的高层形态

Zoom Team Chat 的 Chatbot 消息使用一种"卡片化"的 JSON 结构(业界常称 message cards)。与 Team Chat API(用户类型,走POST /v2/chat/users/me/messages,发送纯文本message字段)不同,Chatbot API 发送的是结构化content对象,这是富交互能力的根基。

从 message-structure.md 可以看到核心骨架:

content.head → 标题 + 可选副标题 content.body → 组件数组(blocks) ├── message 文本块 ├── fields 键/值行 ├── actions 按钮块 └── attachments 图片/链接块

对应的最小 JSON 骨架如下(来自 message-cards.md):

{ "content": { "head": { // 可选头部 "text": "Title", "sub_head": { "text": "Subtitle" } }, "body": [ // 组件数组 { "type": "message", "text": "Content" }, { "type": "actions", "items": [...] } // ... 更多组件 ] } }

要点:

  • head是可选头部,text为主标题,sub_head.text为副标题;
  • body是组件数组,每个元素通过type字段声明类型,可自由组合、有序排列;
  • headbody可同时省略其一,但实际使用中至少应包含body,否则卡片没有可展示内容。

二、组件目录(Components Catalog)

2.1 文本类组件

message—— 纯文本内容:

{ "type": "message", "text": "Hello, this is plain text" }

header—— 带可选样式的标题文本:

{ "type": "header", "text": "Main Heading", "style": { "bold": true, "italic": false } }

styled_text—— 支持 Markdown 风格样式的文本(**Bold**加粗、*italic*斜体、`code`行内代码):

{ "type": "styled_text", "text": "**Bold** *italic* `code`" }

2.2 交互类组件

actions(按钮)—— 可点击按钮,点击后触发交互 Webhook:

{ "type": "actions", "items": [ { "text": "Approve", "value": "approve", "style": "Primary" // Primary, Danger, Default }, { "text": "Reject", "value": "reject", "style": "Danger" } ] }

按钮样式(style)三选一:

  • Primary—— 蓝色按钮
  • Danger—— 红色按钮
  • Default—— 灰色按钮

dropdown—— 带选项的选择菜单:

{ "type": "dropdown", "select_items": [ { "text": "Option 1", "value": "opt1" }, { "text": "Option 2", "value": "opt2" } ] }

form_field—— 文本输入框:

{ "type": "form_field", "editable": true, "text": "Enter your name" }

2.3 布局类组件

section—— 组件分组,支持可选的彩色侧边栏(sidebar):

{ "type": "section", "sidebar_color": "#3b82f6", // Hex 颜色 "sections": [ { "type": "message", "text": "Grouped content" } ] }

推荐语义化配色:

  • Success(成功):#10b981(绿色)
  • Error(错误):#ef4444(红色)
  • Warning(警告):#f59e0b(橙色)
  • Info(信息):#3b82f6(蓝色)

fields—— 以列展示的键值对:

{ "type": "fields", "items": [ { "key": "Status", "value": "Active" }, { "key": "Priority", "value": "High" }, { "key": "Assignee", "value": "John Doe" } ] }

divider—— 水平分隔线:

{ "type": "divider" }

2.4 媒体类组件

attachments—— 带可选链接的图片:

{ "type": "attachments", "img_url": "https://example.com/image.jpg", "resource_url": "https://example.com/full-page", "information": { "title": { "text": "Image Title" }, "description": { "text": "Click to view" } } }

三、完整实战示例

3.1 构建通知(Build Notification)

{ "content": { "head": { "text": "Build #123 Complete", "sub_head": { "text": "main branch" } }, "body": [ { "type": "section", "sidebar_color": "#10b981", "sections": [ { "type": "message", "text": "✅ Build completed successfully" } ] }, { "type": "fields", "items": [ { "key": "Branch", "value": "main" }, { "key": "Commit", "value": "abc123" }, { "key": "Duration", "value": "2m 34s" } ] }, { "type": "actions", "items": [ { "text": "View Logs", "value": "view_logs", "style": "Primary" }, { "text": "Deploy", "value": "deploy", "style": "Default" } ] } ] } }

3.2 审批请求(Approval Request)

{ "content": { "head": { "text": "Expense Approval Required" }, "body": [ { "type": "message", "text": "John Doe submitted an expense report" }, { "type": "fields", "items": [ { "key": "Amount", "value": "$500.00" }, { "key": "Category", "value": "Travel" }, { "key": "Date", "value": "Feb 9, 2026" } ] }, { "type": "divider" }, { "type": "actions", "items": [ { "text": "Approve", "value": "approve_500", "style": "Primary" }, { "text": "Reject", "value": "reject_500", "style": "Danger" }, { "text": "View Details", "value": "details_500", "style": "Default" } ] } ] } }

3.3 错误通知(Error Notification)

{ "content": { "head": { "text": "⚠️ Service Alert" }, "body": [ { "type": "section", "sidebar_color": "#ef4444", "sections": [ { "type": "message", "text": "Database connection failed" } ] }, { "type": "fields", "items": [ { "key": "Service", "value": "api-prod" }, { "key": "Error", "value": "Connection timeout" }, { "key": "Time", "value": "2026-02-09 18:30:00 UTC" } ] }, { "type": "actions", "items": [ { "text": "View Logs", "value": "logs", "style": "Primary" }, { "text": "Acknowledge", "value": "ack", "style": "Default" } ] } ] } }

四、如何发送卡片消息:Chatbot API 调用

卡片 JSON 只是content字段,发送时需封装进 Chatbot API 请求体中。在 SKILL.md 与 chatbot-setup.md 中给出了完整调用范式:

const response = await fetch('https://api.zoom.us/v2/im/chat/messages', { method: 'POST', headers: { 'Authorization': `Bearer ${accessToken}`, // client_credentials 换取 'Content-Type': 'application/json' }, body: JSON.stringify({ robot_jid: process.env.ZOOM_BOT_JID, // Marketplace → Features → Chatbot → Bot Credentials to_jid: payload.toJid, // 来自 Webhook payload account_id: payload.accountId, // 来自 Webhook payload content: { head: { text: 'Build Notification', sub_head: { text: 'CI/CD Pipeline' } }, body: [ { type: 'message', text: 'Deployment successful!' }, { type: 'fields', items: [ { key: 'Branch', value: 'main' }, { key: 'Commit', value: 'abc123' } ] }, { type: 'actions', items: [ { text: 'View Logs', value: 'view_logs', style: 'Primary' }, { text: 'Dismiss', value: 'dismiss', style: 'Default' } ] } ] } }) });

字段说明:

  • robot_jid:机器人 JID,格式如v1abc123xyz@xmpp.zoom.us,在 Zoom Marketplace 的 Bot Credentials 中获取;
  • to_jid/account_id:来自bot_notificationWebhook payload,用于定位接收者;
  • content:即上文讲解的完整卡片对象;
  • 令牌获取:使用client_credentials授权模式(POST https://zoom.us/oauth/tokengrant_type=client_credentials,Basic Auth 携带CLIENT_ID:CLIENT_SECRET),对应 scope 为imchat:bot(自动添加)。

注意两种 API 不可混用:Team Chat API 走POST /v2/chat/users/me/messages发送的是用户身份的纯文本,不支持富卡片;只有 Chatbot API(/v2/im/chat/messages)支持按钮、表单、下拉框、图片等富交互组件。若选错类型,认证方式、scope、端点全家不匹配。参见 api-selection.md。

五、交互闭环:按钮点击与 value 路由

消息卡片的价值在于交互。在 message-structure.md 中明确强调:按钮必须携带一个可用于路由的value——当你收到交互 Webhook 时,正是靠它来区分用户点了哪个按钮。

交互流程(来自 button-actions.md):

  1. 你发送一张包含actions.items[]的卡片,每个按钮带唯一value
  2. 用户点击后,Zoom 向你的 Bot Endpoint URL 发送interactive_message_actionsWebhook;
  3. 你的 handler 依据actionItem.value路由处理。

路由建议使用稳定、语义化的 action ID,例如approve_requestreject_requestopen_ticket:123,避免使用易变的展示文本做路由键。

服务端处理示例(来自 SKILL.md):

case 'interactive_message_actions': { const { actionItem, toJid, accountId } = payload; if (actionItem.value === 'approve') { await sendChatbotMessage(toJid, accountId, { body: [{ type: 'message', text: '✅ Approved!' }] }); } }

在完整实现中(见 chatbot-setup.md 的utils/chatbot.js),还可以封装sendMessageWithButtons()帮助函数,把按钮数组批量映射为actions.items,并默认style: 'Default',从而保证每张卡片都能被统一、安全地构造。

六、组件限制(Limitations)

构造卡片前请务必对照容量上限,避免发送被拒或渲染异常:

组件限制
消息文本4,096 字符
按钮文本40 字符
字段键/值各 256 字符
下拉框选项100 个
每条消息按钮5 个

在 chatbot-setup.md 的utils/validation.js中还提供了一种防御性写法:发送前对文本执行trim()、移除控制字符(/[\x00-\x1F\x7F]/g)并substring(0, 4096)截断,从源头规避长度超限问题。

七、最佳实践

7.1 按钮文案设计

推荐:使用清晰、面向动作的标签

  • "Approve Request"
  • "View Details"
  • "Cancel Order"

避免:语义模糊的标签

  • "OK"
  • "Click Here"
  • "Button"

7.2 配色语义化

推荐:使用语义色

  • 绿色(#10b981)表示成功
  • 红色(#ef4444)表示错误/破坏性操作
  • 蓝色(#3b82f6)表示信息
  • 橙色(#f59e0b)表示警告

避免:无意义的随意配色。

7.3 字段格式

推荐:键保持简洁、值提供信息量:

{ "key": "Status", "value": "Active" }

避免:键过长:

{ "key": "The current status of the request", "value": "Active" }

八、常见坑与排障(Common Pitfalls)

message-structure.md 与 message-issues.md 共同总结了高频问题:

  1. 按钮缺少value或 value 不可路由:交互 Webhook 到来时无法确定用户意图,导致点击无响应。务必为每个按钮设置稳定唯一的value
  2. "Zoom 没有渲染我的卡片"往往是 JSON 形状非法:发送前先校验 payload。做法是先对照已知可用的示例精简到最小卡片,再逐步增量添加组件,定位出错的组件。
  3. 消息发不出去:确认使用的 API 与令牌匹配——Team Chat API 用用户 OAuth 令牌,Chatbot API 用机器人令牌并携带robot_jid;确认ZOOM_BOT_JIDZOOM_ACCOUNT_ID正确。
  4. 收到endpoint.url_validation却校验失败:确保你的端点按规范返回plainToken+encryptedToken(用ZOOM_VERIFICATION_TOKEN做 HMAC-SHA256 加密)。
  5. Webhook 签名校验:所有交互请求都应校验x-zm-signature头(v0:${timestamp}:${JSON.stringify(body)}的 HMAC-SHA256 摘要),防止伪造请求。

九、测试卡片与后续进阶

  • 在线预览:可借助 Zoom 官方的 Team Chat App Card Builder(appssdk.zoom.us/cardbuilder)预览卡片设计、测试布局、生成 JSON——发送前先用它验证结构是最稳妥的实践。
  • 最小冒烟测试:参照 get-started.md 的第 4 步,先用body: [{ type: 'message', text: '...' }]发送一条纯文本机器人消息,确认链路打通后再叠加按钮、表单等高级组件。
  • 继续深入:处理按钮点击的完整工程见 button-actions.md;理解bot_notificationinteractive_message_actionschat_message.submit等全部事件见 webhook-events.md;从零搭建带 Webhook、签名校验与命令路由的完整机器人见 chatbot-setup.md。

十、组件速查表

组件用途关键字段
header标题与副标题textstyle
message纯文本text
fields键值对items[].key/value
actions按钮items[].text/value/style
section彩色侧边栏分组sidebar_colorsections
attachments图片与链接img_urlresource_url
divider水平分隔线
form_field文本输入editabletext
dropdown选择菜单select_items[]
date_picker日期选择

掌握"head + body 组件数组"这一核心形态,配合完整的组件目录、交互 Webhook 路由与容量限制,即可在 Zoom Team Chat 中构建出 CI/CD 通知、审批流、服务告警、LLM 对话助手等各类富交互机器人体验。

【免费下载链接】knowledge-work-pluginsOpen source repository of plugins primarily intended for knowledge workers to use in Claude Cowork项目地址: https://gitcode.com/GitHub_Trending/kn/knowledge-work-plugins

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询