关于 slack-block-kit
slack-block-kit 是面向 Slack 界面开发者的 Block Kit 参考技能,介绍消息、模态框和 Home 标签页的 JSON 结构,涵盖布局区块与交互元素。
主要功能
- 01Block Kit 区块参考
- 02交互元素与菜单
- 03组合对象与文本
- 04消息、模态框和 Home 标签页
适用场景
- 01构建 Slack 消息布局
- 02创建模态框表单与工作流
- 03为 Home 标签页添加交互控件
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ freightcognition/ linehaulai-claude-marketplace --skill slack-block-kit安装后在 Claude Code 中输入/slack-block-kit确认已加载。
详细介绍
Slack Block Kit
使用 Block Kit 构建 Slack UI 的专家指南。
概述
Block Kit 是 Slack 的 UI 框架,用于创建丰富的交互式消息、模态框和主页标签。它采用基于 JSON 的结构,包含三个主要组件:
- 区块:布局容器(Section、Actions、Input、Header 等)
- 元素:交互式组件(按钮、选择器、日期选择器)
- 组合对象:文本、选项和确认信息
界面
Block Kit 支持三种界面:
| 界面 | 区块上限 | 用例 |
|---|---|---|
| 消息 | 50 | 通知、机器人回复、频道帖子 |
| 模态框 | 100 | 表单、确认信息、多步骤工作流 |
| 主页标签 | 100 | 应用仪表板、用户专属内容 |
快速开始
简单消息
{
"blocks": [
{
"type": "header",
"text": {
"type": "plain_text",
"text": "New Order Received"
}
},
{
"type": "section",
"fields": [
{
"type": "mrkdwn",
"text": "*Order ID:*\n#12345"
},
{
"type": "mrkdwn",
"text": "*Customer:*\nJohn Doe"
}
]
},
{
"type": "actions",
"elements": [
{
"type": "button",
"text": {
"type": "plain_text",
"text": "View Order"
},
"style": "primary",
"action_id": "view_order",
"value": "12345"
}
]
}
]
}
使用 slack-block-builder(JavaScript)
import { Message, Blocks, Elements } from 'slack-block-builder';
const orderNotification = ({ orderId, customer, channel }) => {
return Message({ channel, text: 'New Order Received' })
.blocks(
Blocks.Header({ text: 'New Order Received' }),
Blocks.Section()
.fields([
`*Order ID:*\n#${orderId}`,
`*Customer:*\n${customer}`
]),
Blocks.Actions()
.elements(
Elements.Button({ text: 'View Order', actionId: 'view_order' })
.primary()
.value(orderId)
)
)
.buildToObject();
};
区块参考
Header 区块
显示用于标题的大号文本。
{
"type": "header",
"text": {
"type": "plain_text",
"text": "Budget Performance",
"emoji": true
}
}
字段:
type(必填):始终为"header"text(必填):plain_text 对象,最多 150 个字符block_id(可选):唯一标识符,最多 255 个字符
**界面:**消息、模态框、主页标签
Section 区块
最灵活的文本和附件区块。
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*Project Update*\nThe deployment is complete."
},
"accessory": {
"type": "button",
"text": {
"type": "plain_text",
"text": "View Details"
},
"action_id": "view_details"
}
}
带字段(双列布局):
{
"type": "section",
"fields": [
{
"type": "mrkdwn",
"text": "*Status:*\nApproved"
},
{
"type": "mrkdwn",
"text": "*Created:*\nDec 15, 2025"
},
{
"type": "mrkdwn",
"text": "*Priority:*\nHigh"
},
{
"type": "mrkdwn",
"text": "*Assignee:*\n<@U123ABC>"
}
]
}
字段:
type(必填):始终为"section"text(可选):文本对象(mrkdwn 或 plain_text),最多 3000 个字符fields(可选):文本对象数组(最多 10 个),每个最多 2000 个字符accessory(可选):一个交互式元素block_id(可选):唯一标识符expand(可选):布尔值,默认展开文本
**界面:**消息、模态框、主页标签
Actions 区块
包含多个交互式元素。
{
"type": "actions",
"block_id": "approval_actions",
"elements": [
{
"type": "button",
"text": {
"type": "plain_text",
"text": "Approve"
},
"style": "primary",
"action_id": "approve_request",
"value": "approved"
},
{
"type": "button",
"text": {
"type": "plain_text",
"text": "Reject"
},
"style": "danger",
"action_id": "reject_request",
"value": "rejected"
}
]
}
字段:
type(必填):始终为"actions"elements(必填):交互式元素数组(最多 25 个)block_id(可选):唯一标识符
**界面:**消息、模态框、主页标签
Input 区块
收集用户输入(主要用于模态框和主页标签)。
{
"type": "input",
"block_id": "description_input",
"label": {
"type": "plain_text",
"text": "Description"
},
"element": {
"type": "plain_text_input",
"action_id": "description_value",
"multiline": true,
"placeholder": {
"type": "plain_text",
"text": "Enter a description..."
}
},
"optional": true,
"hint": {
"type": "plain_text",
"text": "Provide additional context"
}
}
字段:
type(必填):始终为"input"element(必填):输入元素(文本输入框、选择器、日期选择器等)label(必填):plain_text 对象,最多 2000 个字符block_id(可选):唯一标识符hint(可选):plain_text 对象,最多 2000 个字符optional(可选):布尔值,默认为 falsedispatch_action(可选):布尔值,在更改时分发 block_actions
**界面:**模态框、消息、主页标签
Context 区块
显示辅助性上下文信息。
{
"type": "context",
"elements": [
{
"type": "image",
"image_url": "https://example.com/avatar.png",
"alt_text": "User avatar"
},
{
"type": "mrkdwn",
"text": "Posted by <@U123ABC> on Dec 15, 2025"
}
]
}
字段:
type(必填):始终为"context"elements(必填):图像/文本元素数组(最多 10 个)block_id(可选):唯一标识符
**界面:**消息、模态框、主页标签
Divider 区块
用于分隔区块的视觉分隔线。
{
"type": "divider"
}
**界面:**消息、模态框、主页标签
Image 区块
显示图像。
{
"type": "image",
"image_url": "https://example.com/chart.png",
"alt_text": "Sales chart",
"title": {
"type": "plain_text",
"text": "Q4 Sales Performance"
}
}
字段:
type(必填):始终为"image"image_url(必填*):公开 URL,最多 3000 个字符slack_file(必填*):image_url的替代项alt_text(必填):描述,最多 2000 个字符title(可选):plain_text 对象,最多 2000 个字符block_id(可选):唯一标识符
*必须提供 image_url 或 slack_file 其中之一
**界面:**消息、模态框、主页标签
Markdown 区块
显示格式化的 markdown(仅限消息)。
{
"type": "markdown",
"text": "**Important:** This is *formatted* text with `code`."
}
**界面:**仅限消息
Rich Text 区块
结构化文本表示。
{
"type": "rich_text",
"elements": [
{
"type": "rich_text_section",
"elements": [
{
"type": "text",
"text": "Hello ",
"style": {
"bold": true
}
},
{
"type": "user",
"user_id": "U123ABC"
}
]
}
]
}
**界面:**消息、模态框、主页标签
Video 区块
嵌入视频播放器。
{
"type": "video",
"title": {
"type": "plain_text",
"text": "Product Demo"
},
"video_url": "https://example.com/video.mp4",
"thumbnail_url": "https://example.com/thumb.png",
"alt_text": "Product demonstration video"
}
**界面:**消息、模态框、主页标签
元素参考
按钮元素
用于执行操作的交互式按钮。
{
"type": "button",
"text": {
"type": "plain_text",
"text": "Click Me",
"emoji": true
},
"action_id": "button_click",
"value": "button_value",
"style": "primary"
}
字段:
type(必填):始终为"button"text(必填):plain_text 对象,最多 75 个字符action_id(可选):交互标识符,最多 255 个字符value(可选):负载值,最多 2000 个字符style(可选):"primary"(绿色)或"danger"(红色)url(可选):要打开的 URL,最多 3000 个字符confirm(可选):确认对话框accessibility_label(可选):屏幕阅读器文本,最多 75 个字符
适用于: Section(附件)、Actions
静态选择菜单
包含预定义选项的下拉菜单。
{
"type": "static_select",
"action_id": "priority_select",
"placeholder": {
"type": "plain_text",
"text": "Select priority"
},
"options": [
{
"text": {
"type": "plain_text",
"text": "High"
},
"value": "high"
},
{
"text": {
"type": "plain_text",
"text": "Medium"
},
"value": "medium"
},
{
"text": {
"type": "plain_text",
"text": "Low"
},
"value": "low"
}
],
"initial_option": {
"text": {
"type": "plain_text",
"text": "Medium"
},
"value": "medium"
}
}
字段:
type(必填):"static_select"action_id(可选):交互标识符options(必填*):选项对象数组(最多 100 个)option_groups(必填*):分组的选项(最多 100 组)initial_option(可选):预选选项placeholder(可选):占位文本,最多 150 个字符confirm(可选):确认对话框focus_on_load(可选):在模态框中自动聚焦
*options 或 option_groups 中必须提供一个
外部选择菜单
动态加载选项的下拉菜单。
{
"type": "external_select",
"action_id": "customer_select",
"placeholder": {
"type": "plain_text",
"text": "Search customers..."
},
"min_query_length": 2
}
字段:
type(必填):"external_select"action_id(可选):交互标识符min_query_length(可选):发起查询前所需的最少字符数(默认为 3)initial_option(可选):预选选项placeholder(可选):占位文本
用户选择菜单
选择工作区用户。
{
"type": "users_select",
"action_id": "assignee_select",
"placeholder": {
"type": "plain_text",
"text": "Select assignee"
},
"initial_user": "U123ABC"
}
频道选择菜单
选择公开频道。
{
"type": "channels_select",
"action_id": "channel_select",
"placeholder": {
"type": "plain_text",
"text": "Select channel"
},
"initial_channel": "C123ABC"
}
对话选择菜单
选择任意对话(频道、私信、群组)。
{
"type": "conversations_select",
"action_id": "conversation_select",
"placeholder": {
"type": "plain_text",
"text": "Select conversation"
},
"default_to_current_conversation": true
}
多选菜单
所有选择菜单都有多选变体:
multi_static_selectmulti_external_selectmulti_users_selectmulti_channels_selectmulti_conversations_select
{
"type": "multi_users_select",
"action_id": "team_select",
"placeholder": {
"type": "plain_text",
"text": "Select team members"
},
"max_selected_items": 5
}
日期选择器
选择日期。
{
"type": "datepicker",
"action_id": "due_date",
"placeholder": {
"type": "plain_text",
"text": "Select due date"
},
"initial_date": "2025-12-31"
}
时间选择器
选择时间。
{
"type": "timepicker",
"action_id": "meeting_time",
"placeholder": {
"type": "plain_text",
"text": "Select time"
},
"initial_time": "14:30"
}
日期时间选择器
同时选择日期和时间。
{
"type": "datetimepicker",
"action_id": "event_datetime",
"initial_date_time": 1734307200
}
复选框
从选项中多选。
{
"type": "checkboxes",
"action_id": "features_select",
"options": [
{
"text": {
"type": "plain_text",
"text": "Email notifications"
},
"value": "email",
"description": {
"type": "mrkdwn",
"text": "*Receive daily summary*"
}
},
{
"text": {
"type": "plain_text",
"text": "Slack notifications"
},
"value": "slack"
}
],
"initial_options": [
{
"text": {
"type": "plain_text",
"text": "Email notifications"
},
"value": "email"
}
]
}
单选按钮
从选项中单选。
{
"type": "radio_buttons",
"action_id": "urgency_select",
"options": [
{
"text": {
"type": "plain_text",
"text": "Urgent"
},
"value": "urgent"
},
{
"text": {
"type": "plain_text",
"text": "Standard"
},
"value": "standard"
}
],
"initial_option": {
"text": {
"type": "plain_text",
"text": "Standard"
},
"value": "standard"
}
}
纯文本输入框
单行或多行文本输入框。
{
"type": "plain_text_input",
"action_id": "comment_input",
"placeholder": {
"type": "plain_text",
"text": "Enter your comment..."
},
"multiline": true,
"min_length": 10,
"max_length": 500
}
数字输入框
带验证的数字输入框。
{
"type": "number_input",
"action_id": "quantity_input",
"is_decimal_allowed": false,
"min_value": "1",
"max_value": "100",
"placeholder": {
"type": "plain_text",
"text": "Enter quantity"
}
}
URL 输入框
带验证的 URL 输入框。
{
"type": "url_text_input",
"action_id": "website_input",
"placeholder": {
"type": "plain_text",
"text": "https://example.com"
}
}
电子邮件输入框
带验证的电子邮件输入框。
{
"type": "email_text_input",
"action_id": "email_input",
"placeholder": {
"type": "plain_text",
"text": "[email protected]"
}
}
富文本输入框
格式化文本输入框。
{
"type": "rich_text_input",
"action_id": "content_input",
"placeholder": {
"type": "plain_text",
"text": "Write your content..."
}
}
文件输入框
文件上传(仅限模态框)。
{
"type": "file_input",
"action_id": "attachment_input",
"filetypes": ["pdf", "png", "jpg"],
"max_files": 3
}
溢出菜单
用于次要操作的紧凑菜单。
{
"type": "overflow",
"action_id": "more_actions",
"options": [
{
"text": {
"type": "plain_text",
"text": "Edit"
},
"value": "edit"
},
{
"text": {
"type": "plain_text",
"text": "Delete"
},
"value": "delete"
}
]
}
组合对象
文本对象
在整个 Block Kit 中用于文本内容。
纯文本:
{
"type": "plain_text",
"text": "Hello, world!",
"emoji": true
}
Markdown(mrkdwn):
{
"type": "mrkdwn",
"text": "*Bold* _italic_ ~strike~ `code` <https://example.com|link>"
}
确认对话框
在执行破坏性操作前进行确认。
{
"title": {
"type": "plain_text",
"text": "Confirm Delete"
},
"text": {
"type": "mrkdwn",
"text": "Are you sure you want to delete this item? This cannot be undone."
},
"confirm": {
"type": "plain_text",
"text": "Delete"
},
"deny": {
"type": "plain_text",
"text": "Cancel"
},
"style": "danger"
}
选项对象
用于选择菜单、复选框和单选按钮。
{
"text": {
"type": "plain_text",
"text": "Option Label"
},
"value": "option_value",
"description": {
"type": "plain_text",
"text": "Optional description"
},
"url": "https://example.com"
}
选项组
用于选择菜单的分组选项。
{
"label": {
"type": "plain_text",
"text": "Group Label"
},
"options": [
{
"text": {
"type": "plain_text",
"text": "Option 1"
},
"value": "option_1"
}
]
}
模态框参考
打开模态框
{
"type": "modal",
"callback_id": "feedback_modal",
"title": {
"type": "plain_text",
"text": "Submit Feedback"
},
"submit": {
"type": "plain_text",
"text": "Submit"
},
"close": {
"type": "plain_text",
"text": "Cancel"
},
"blocks": [
{
"type": "input",
"block_id": "feedback_type",
"label": {
"type": "plain_text",
"text": "Feedback Type"
},
"element": {
"type": "static_select",
"action_id": "type_select",
"options": [
{
"text": {
"type": "plain_text",
"text": "Bug Report"
},
"value": "bug"
},
{
"text": {
"type": "plain_text",
"text": "Feature Request"
},
"value": "feature"
}
]
}
},
{
"type": "input",
"block_id": "feedback_content",
"label": {
"type": "plain_text",
"text": "Description"
},
"element": {
"type": "plain_text_input",
"action_id": "content_input",
"multiline": true
}
}
]
}
模态框字段
type(必填):始终为"modal"title(必填):plain_text,最多 24 个字符blocks(必填):区块数组(最多 100 个)callback_id(可选):view_submission 的标识符submit(可选):提交按钮文本,最多 24 个字符close(可选):关闭按钮文本,最多 24 个字符private_metadata(可选):传递给提交事件的字符串,最多 3000 个字符clear_on_close(可选):关闭时清除所有视图notify_on_close(可选):发送 view_closed 事件external_id(可选):自定义标识符submit_disabled(可选):初始时禁用提交按钮
slack-block-builder 库
安装
npm install slack-block-builder
导入
import {
Message,
Modal,
HomeTab,
Blocks,
Elements,
Bits,
Md
} from 'slack-block-builder';
构建消息
const message = Message({ channel: 'C123ABC', text: 'Fallback text' })
.blocks(
Blocks.Header({ text: 'Welcome!' }),
Blocks.Section({ text: 'Hello, *world*!' }),
Blocks.Divider(),
Blocks.Actions()
.elements(
Elements.Button({ text: 'Click Me', actionId: 'click' })
.primary()
)
)
.buildToObject();
构建模态框
const modal = Modal({ title: 'My Form', callbackId: 'form_submit' })
.submit('Save')
.close('Cancel')
.blocks(
Blocks.Input({ label: 'Name', blockId: 'name_block' })
.element(
Elements.TextInput({ actionId: 'name_input' })
.placeholder('Enter your name')
),
Blocks.Input({ label: 'Priority', blockId: 'priority_block' })
.element(
Elements.StaticSelect({ actionId: 'priority_select' })
.options(
Bits.Option({ text: 'High', value: 'high' }),
Bits.Option({ text: 'Medium', value: 'medium' }),
Bits.Option({ text: 'Low', value: 'low' })
)
)
)
.buildToObject();
Markdown 辅助函数
import { Md } from 'slack-block-builder';
Md.bold('text') // *text*
Md.italic('text') // _text_
Md.strike('text') // ~text~
Md.code('text') // `text`
Md.codeBlock('text') // ```text```
Md.link('url', 'text') // <url|text>
Md.user('U123') // <@U123>
Md.channel('C123') // <#C123>
Md.emoji('smile') // :smile:
Md.listBullet(['a', 'b']) // • a\n• b
构建方法
// Returns JavaScript object
modal.buildToObject();
// Returns JSON string
modal.buildToJSON();
// Returns only blocks array
modal.getBlocks();
最佳实践
命名约定
action_id:{verb}_{noun}- 例如,submit_form、select_priorityblock_id:{noun}_block- 例如,name_block、options_blockcallback_id:{feature}_{action}- 例如,feedback_submit
性能
- 将消息控制在 50 个 block 以内
- 将模态框控制在 100 个 block 以内
- 对于较大的选项列表(>100 项),使用 external_select
- 尽量减少高流量消息中的图片使用
无障碍访问
- 始终为图片提供
alt_text - 为带图标的按钮使用
accessibility_label - 确保颜色对比度充足
- 提供清晰、准确的标签
移动端注意事项
- 使用较短的文本(按钮约在 30 个字符处截断)
- 限制 Section block 中的字段数量(最多 2–3 个)
- 在移动端 Slack 客户端中进行测试
- 避免复杂的嵌套布局
常见模式
带操作的通知
Message({ channel, text: 'New request' })
.blocks(
Blocks.Header({ text: 'New Request' }),
Blocks.Section()
.fields([
`*From:*\n${requester}`,
`*Priority:*\n${priority}`
]),
Blocks.Context()
.elements([`Submitted ${timestamp}`]),
Blocks.Divider(),
Blocks.Actions()
.elements(
Elements.Button({ text: 'Approve', actionId: 'approve' }).primary(),
Elements.Button({ text: 'Reject', actionId: 'reject' }).danger()
)
)
.buildToObject();
带验证的表单模态框
Modal({ title: 'Create Task', callbackId: 'task_create' })
.submit('Create')
.close('Cancel')
.blocks(
Blocks.Input({ label: 'Task Name', blockId: 'name' })
.element(Elements.TextInput({ actionId: 'name_input' })),
Blocks.Input({ label: 'Assignee', blockId: 'assignee' })
.element(Elements.UsersSelect({ actionId: 'assignee_select' })),
Blocks.Input({ label: 'Due Date', blockId: 'due_date' })
.element(Elements.DatePicker({ actionId: 'date_select' }))
.optional(true)
)
.buildToObject();
主页标签页仪表板
HomeTab()
.blocks(
Blocks.Header({ text: `Welcome, ${userName}!` }),
Blocks.Section({ text: 'Here are your pending tasks:' }),
Blocks.Divider(),
...tasks.map(task =>
Blocks.Section({ text: `• ${task.title}` })
.accessory(
Elements.Button({ text: 'Complete', actionId: `complete_${task.id}` })
)
),
Blocks.Divider(),
Blocks.Actions()
.elements(
Elements.Button({ text: 'New Task', actionId: 'new_task' }).primary()
)
)
.buildToObject();
故障排除
常见错误
| 错误 | 原因 | 解决方案 |
|---|---|---|
invalid_blocks | JSON 格式错误 | 在 Block Kit Builder 中验证 |
too_many_blocks | 超出限制 | 将数量减少到 50(消息)或 100(模态框) |
invalid_element | block 中的元素不正确 | 检查元素兼容性 |
missing_text | 缺少必填文本 | 在 Section 中添加文本或字段 |
验证提示
- 使用 Block Kit Builder 测试 JSON
- 检查元素与 block 的兼容性
- 确认必填字段均已提供
- 在移动端进行测试,检查显示问题
资源
参考文档
如需全面的指南,请参阅 references/ 目录:
- blocks.md - 所有 block 类型的详细文档
- interactive-components.md - 交互元素完整指南
- layout-patterns.md - 组合与嵌套的最佳实践
- surfaces.md - 深入介绍消息、模态框和主页标签页