slack-bot

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Slack Bot

Slack Bot

Send messages and rich content to Slack channels using Incoming Webhooks or the Slack Web API. Build formatted announcements, marketing reports, metrics dashboards, and community updates with Block Kit.
使用Incoming Webhook或Slack Web API向Slack频道发送消息和富内容。 借助Block Kit创建格式化的公告、营销报告、指标仪表板和社区更新。

Prerequisites

前提条件

Requires either
SLACK_WEBHOOK_URL
or
SLACK_BOT_TOKEN
set in
.env
,
.env.local
, or
~/.claude/.env.global
.
bash
source ~/.claude/.env.global 2>/dev/null
source .env 2>/dev/null
source .env.local 2>/dev/null

if [ -n "$SLACK_WEBHOOK_URL" ]; then
  echo "SLACK_WEBHOOK_URL is set. Webhook mode available."
elif [ -n "$SLACK_BOT_TOKEN" ]; then
  echo "SLACK_BOT_TOKEN is set. Web API mode available."
else
  echo "Neither SLACK_WEBHOOK_URL nor SLACK_BOT_TOKEN is set."
  echo "See the Setup Guide below to configure Slack credentials."
fi
If neither variable is set, instruct the user to follow the Setup Guide section below.

需要在
.env
.env.local
~/.claude/.env.global
中设置
SLACK_WEBHOOK_URL
SLACK_BOT_TOKEN
其中一个。
bash
source ~/.claude/.env.global 2>/dev/null
source .env 2>/dev/null
source .env.local 2>/dev/null

if [ -n "$SLACK_WEBHOOK_URL" ]; then
  echo "SLACK_WEBHOOK_URL is set. Webhook mode available."
elif [ -n "$SLACK_BOT_TOKEN" ]; then
  echo "SLACK_BOT_TOKEN is set. Web API mode available."
else
  echo "Neither SLACK_WEBHOOK_URL nor SLACK_BOT_TOKEN is set."
  echo "See the Setup Guide below to configure Slack credentials."
fi
如果两个变量都未设置,请指导用户按照下方的设置指南进行配置。

Setup Guide

设置指南

Option A: Incoming Webhook (Simple)

选项A:Incoming Webhook(简易版)

Incoming Webhooks are the fastest way to post messages. They require no OAuth scopes and are scoped to a single channel.
  1. Go to https://api.slack.com/apps and click Create New App > From scratch.
  2. Name the app (e.g., "Marketing Bot") and select your workspace.
  3. In the left sidebar, click Incoming Webhooks and toggle it On.
  4. Click Add New Webhook to Workspace at the bottom.
  5. Select the channel to post to and click Allow.
  6. Copy the Webhook URL (starts with
    https://hooks.slack.com/services/...
    ).
  7. Add it to your environment:
bash
echo 'SLACK_WEBHOOK_URL=https://hooks.slack.com/services/T.../B.../xxxx' >> .env
Limitations: One webhook per channel. Cannot read messages, list channels, or reply to threads programmatically (you must know the
thread_ts
from a prior API response).
Incoming Webhook是发送消息最快的方式,不需要OAuth权限范围,且仅针对单个频道。
  1. 访问https://api.slack.com/apps,点击**Create New App** > From scratch
  2. 为应用命名(例如“Marketing Bot”)并选择你的工作区。
  3. 在左侧边栏中点击Incoming Webhooks,并将其切换为On
  4. 点击底部的Add New Webhook to Workspace
  5. 选择要发送消息的频道,然后点击Allow
  6. 复制Webhook URL(以
    https://hooks.slack.com/services/...
    开头)。
  7. 将其添加到你的环境变量中:
bash
echo 'SLACK_WEBHOOK_URL=https://hooks.slack.com/services/T.../B.../xxxx' >> .env
限制: 每个频道对应一个Webhook。无法以编程方式读取消息、列出频道或回复线程(你必须从之前的API响应中获取
thread_ts
)。

Option B: Bot Token (Full Featured)

选项B:Bot Token(全功能版)

Bot tokens give access to the full Slack Web API: post to any channel the bot is in, reply to threads, list channels, upload files, and more.
  1. Go to https://api.slack.com/apps and click Create New App > From scratch.
  2. Name the app and select your workspace.
  3. In the left sidebar, click OAuth & Permissions.
  4. Under Bot Token Scopes, add these scopes:
    • chat:write
      - Post messages
    • chat:write.public
      - Post to channels without joining
    • channels:read
      - List public channels
    • files:write
      - Upload files (optional, for images/reports)
    • reactions:write
      - Add emoji reactions (optional)
  5. Click Install to Workspace at the top and authorize.
  6. Copy the Bot User OAuth Token (starts with
    xoxb-
    ).
  7. Add it to your environment:
bash
echo 'SLACK_BOT_TOKEN=xoxb-your-token-here' >> .env
  1. Invite the bot to the channels it should post in: type
    /invite @YourBotName
    in each channel.
Optional: Set a default channel for convenience:
bash
echo 'SLACK_DEFAULT_CHANNEL=#marketing' >> .env

Bot Token可访问完整的Slack Web API:向机器人所在的任何频道发送消息、回复线程、列出频道、上传文件等。
  1. 访问https://api.slack.com/apps,点击**Create New App** > From scratch
  2. 为应用命名并选择你的工作区。
  3. 在左侧边栏中点击OAuth & Permissions
  4. Bot Token Scopes下添加以下权限范围:
    • chat:write
      - 发送消息
    • chat:write.public
      - 无需加入即可向频道发送消息
    • channels:read
      - 列出公开频道
    • files:write
      - 上传文件(可选,用于图片/报告)
    • reactions:write
      - 添加表情反应(可选)
  5. 点击顶部的Install to Workspace并授权。
  6. 复制Bot User OAuth Token(以
    xoxb-
    开头)。
  7. 将其添加到你的环境变量中:
bash
echo 'SLACK_BOT_TOKEN=xoxb-your-token-here' >> .env
  1. 邀请机器人加入它需要发送消息的频道:在每个频道中输入
    /invite @YourBotName
可选: 设置默认频道以方便使用:
bash
echo 'SLACK_DEFAULT_CHANNEL=#marketing' >> .env

Method 1: Incoming Webhooks

方法1:Incoming Webhooks

Send a Simple Text Message

发送简单文本消息

bash
curl -s -X POST "$SLACK_WEBHOOK_URL" \
  -H "Content-Type: application/json" \
  -d '{
    "text": "Hello from the marketing bot!"
  }'
bash
curl -s -X POST "$SLACK_WEBHOOK_URL" \
  -H "Content-Type: application/json" \
  -d '{
    "text": "Hello from the marketing bot!"
  }'

Send a Message with Username and Icon Override

发送带有用户名和图标覆盖的消息

bash
curl -s -X POST "$SLACK_WEBHOOK_URL" \
  -H "Content-Type: application/json" \
  -d '{
    "text": "New blog post published!",
    "username": "Marketing Bot",
    "icon_emoji": ":mega:"
  }'
bash
curl -s -X POST "$SLACK_WEBHOOK_URL" \
  -H "Content-Type: application/json" \
  -d '{
    "text": "New blog post published!",
    "username": "Marketing Bot",
    "icon_emoji": ":mega:"
  }'

Send a Message with Block Kit (Webhook)

使用Block Kit发送消息(Webhook版)

bash
curl -s -X POST "$SLACK_WEBHOOK_URL" \
  -H "Content-Type: application/json" \
  -d '{
    "blocks": [
      {
        "type": "header",
        "text": {
          "type": "plain_text",
          "text": "New Product Launch"
        }
      },
      {
        "type": "section",
        "text": {
          "type": "mrkdwn",
          "text": "*Product X* is now live! Check out the announcement."
        }
      },
      {
        "type": "divider"
      },
      {
        "type": "section",
        "text": {
          "type": "mrkdwn",
          "text": "Read the full announcement on our blog."
        },
        "accessory": {
          "type": "button",
          "text": {
            "type": "plain_text",
            "text": "Read More"
          },
          "url": "https://example.com/blog/launch"
        }
      }
    ]
  }'

bash
curl -s -X POST "$SLACK_WEBHOOK_URL" \
  -H "Content-Type: application/json" \
  -d '{
    "blocks": [
      {
        "type": "header",
        "text": {
          "type": "plain_text",
          "text": "New Product Launch"
        }
      },
      {
        "type": "section",
        "text": {
          "type": "mrkdwn",
          "text": "*Product X* is now live! Check out the announcement."
        }
      },
      {
        "type": "divider"
      },
      {
        "type": "section",
        "text": {
          "type": "mrkdwn",
          "text": "Read the full announcement on our blog."
        },
        "accessory": {
          "type": "button",
          "text": {
            "type": "plain_text",
            "text": "Read More"
          },
          "url": "https://example.com/blog/launch"
        }
      }
    ]
  }'

Method 2: Slack Web API (Bot Token)

方法2:Slack Web API(Bot Token版)

The Web API provides full control over message delivery, threading, channel management, and more.
Web API提供对消息传递、线程、频道管理等功能的完全控制。

API Base

API基础

All requests go to
https://slack.com/api/
with the header
Authorization: Bearer {SLACK_BOT_TOKEN}
.
所有请求都发送到
https://slack.com/api/
,并携带请求头
Authorization: Bearer {SLACK_BOT_TOKEN}

Post a Message to a Channel

向频道发送消息

bash
curl -s -X POST "https://slack.com/api/chat.postMessage" \
  -H "Authorization: Bearer ${SLACK_BOT_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{
    "channel": "#marketing",
    "text": "Weekly metrics report is ready!",
    "blocks": [
      {
        "type": "header",
        "text": {
          "type": "plain_text",
          "text": "Weekly Marketing Metrics"
        }
      },
      {
        "type": "section",
        "text": {
          "type": "mrkdwn",
          "text": "Here are the numbers for this week."
        }
      }
    ]
  }'
The response includes a
ts
(timestamp) field which identifies the message. Save this value for threading replies:
bash
undefined
bash
curl -s -X POST "https://slack.com/api/chat.postMessage" \
  -H "Authorization: Bearer ${SLACK_BOT_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{
    "channel": "#marketing",
    "text": "Weekly metrics report is ready!",
    "blocks": [
      {
        "type": "header",
        "text": {
          "type": "plain_text",
          "text": "Weekly Marketing Metrics"
        }
      },
      {
        "type": "section",
        "text": {
          "type": "mrkdwn",
          "text": "Here are the numbers for this week."
        }
      }
    ]
  }'
响应中包含一个
ts
(时间戳)字段,用于标识该消息。保存此值以便后续回复线程:
bash
undefined

Post and capture the message timestamp for threading

发送消息并捕获时间戳用于线程回复

RESPONSE=$(curl -s -X POST "https://slack.com/api/chat.postMessage"
-H "Authorization: Bearer ${SLACK_BOT_TOKEN}"
-H "Content-Type: application/json"
-d '{ "channel": "#marketing", "text": "Thread parent message" }')
MESSAGE_TS=$(echo "$RESPONSE" | python3 -c "import json,sys; print(json.load(sys.stdin).get('ts',''))") echo "Message timestamp: $MESSAGE_TS"
undefined
RESPONSE=$(curl -s -X POST "https://slack.com/api/chat.postMessage"
-H "Authorization: Bearer ${SLACK_BOT_TOKEN}"
-H "Content-Type: application/json"
-d '{ "channel": "#marketing", "text": "Thread parent message" }')
MESSAGE_TS=$(echo "$RESPONSE" | python3 -c "import json,sys; print(json.load(sys.stdin).get('ts',''))") echo "Message timestamp: $MESSAGE_TS"
undefined

Reply to a Thread

回复线程

Use the
thread_ts
parameter to reply inside an existing thread:
bash
curl -s -X POST "https://slack.com/api/chat.postMessage" \
  -H "Authorization: Bearer ${SLACK_BOT_TOKEN}" \
  -H "Content-Type: application/json" \
  -d "{
    \"channel\": \"#marketing\",
    \"thread_ts\": \"${MESSAGE_TS}\",
    \"text\": \"This is a threaded reply with additional details.\"
  }"
To also broadcast the reply to the channel (so it appears in the main conversation as well), add
"reply_broadcast": true
.
使用
thread_ts
参数在现有线程中回复:
bash
curl -s -X POST "https://slack.com/api/chat.postMessage" \
  -H "Authorization: Bearer ${SLACK_BOT_TOKEN}" \
  -H "Content-Type: application/json" \
  -d "{
    \"channel\": \"#marketing\",
    \"thread_ts\": \"${MESSAGE_TS}\",
    \"text\": \"This is a threaded reply with additional details.\"
  }"
如果希望回复同时显示在主频道对话中,可以添加
"reply_broadcast": true

Update an Existing Message

更新现有消息

bash
curl -s -X POST "https://slack.com/api/chat.update" \
  -H "Authorization: Bearer ${SLACK_BOT_TOKEN}" \
  -H "Content-Type: application/json" \
  -d "{
    \"channel\": \"#marketing\",
    \"ts\": \"${MESSAGE_TS}\",
    \"text\": \"Updated message content.\",
    \"blocks\": []
  }"
bash
curl -s -X POST "https://slack.com/api/chat.update" \
  -H "Authorization: Bearer ${SLACK_BOT_TOKEN}" \
  -H "Content-Type: application/json" \
  -d "{
    \"channel\": \"#marketing\",
    \"ts\": \"${MESSAGE_TS}\",
    \"text\": \"Updated message content.\",
    \"blocks\": []
  }"

Delete a Message

删除消息

bash
curl -s -X POST "https://slack.com/api/chat.delete" \
  -H "Authorization: Bearer ${SLACK_BOT_TOKEN}" \
  -H "Content-Type: application/json" \
  -d "{
    \"channel\": \"#marketing\",
    \"ts\": \"${MESSAGE_TS}\"
  }"
bash
curl -s -X POST "https://slack.com/api/chat.delete" \
  -H "Authorization: Bearer ${SLACK_BOT_TOKEN}" \
  -H "Content-Type: application/json" \
  -d "{
    \"channel\": \"#marketing\",
    \"ts\": \"${MESSAGE_TS}\"
  }"

List Public Channels

列出公开频道

Useful for discovering which channel to post to:
bash
curl -s "https://slack.com/api/conversations.list?types=public_channel&limit=100" \
  -H "Authorization: Bearer ${SLACK_BOT_TOKEN}" | \
  python3 -c "
import json, sys
data = json.load(sys.stdin)
for ch in data.get('channels', []):
    members = ch.get('num_members', 0)
    print(f\"#{ch['name']}  |  Members: {members}  |  ID: {ch['id']}\")
"
用于发现要发送消息的频道:
bash
curl -s "https://slack.com/api/conversations.list?types=public_channel&limit=100" \
  -H "Authorization: Bearer ${SLACK_BOT_TOKEN}" | \
  python3 -c "
import json, sys
data = json.load(sys.stdin)
for ch in data.get('channels', []):
    members = ch.get('num_members', 0)
    print(f\"#{ch['name']}  |  Members: {members}  |  ID: {ch['id']}\")
"

Upload a File to a Channel

向频道上传文件

bash
curl -s -X POST "https://slack.com/api/files.uploadV2" \
  -H "Authorization: Bearer ${SLACK_BOT_TOKEN}" \
  -F "file=@report.pdf" \
  -F "filename=weekly-report.pdf" \
  -F "channel_id=C0123456789" \
  -F "initial_comment=Here is this week's marketing report."
bash
curl -s -X POST "https://slack.com/api/files.uploadV2" \
  -H "Authorization: Bearer ${SLACK_BOT_TOKEN}" \
  -F "file=@report.pdf" \
  -F "filename=weekly-report.pdf" \
  -F "channel_id=C0123456789" \
  -F "initial_comment=Here is this week's marketing report."

Add an Emoji Reaction

添加表情反应

bash
curl -s -X POST "https://slack.com/api/reactions.add" \
  -H "Authorization: Bearer ${SLACK_BOT_TOKEN}" \
  -H "Content-Type: application/json" \
  -d "{
    \"channel\": \"C0123456789\",
    \"timestamp\": \"${MESSAGE_TS}\",
    \"name\": \"white_check_mark\"
  }"

bash
curl -s -X POST "https://slack.com/api/reactions.add" \
  -H "Authorization: Bearer ${SLACK_BOT_TOKEN}" \
  -H "Content-Type: application/json" \
  -d "{
    \"channel\": \"C0123456789\",
    \"timestamp\": \"${MESSAGE_TS}\",
    \"name\": \"white_check_mark\"
  }"

Slack Block Kit Reference

Slack Block Kit参考

Block Kit is Slack's UI framework for building rich, interactive messages. Messages are composed of an array of blocks, each with a specific type and structure.
Block Kit是Slack用于构建丰富交互式消息的UI框架。消息由一组块组成,每个块都有特定的类型和结构。

Block Types

块类型

Block TypePurposeSupports mrkdwn
header
Large bold title textNo (plain_text only)
section
Primary content block with text and optional accessoryYes
divider
Horizontal line separatorN/A
image
Full-width image with alt textN/A
context
Small, muted text and images (for metadata, timestamps)Yes
actions
Row of interactive elements (buttons, selects, date pickers)N/A
rich_text
Advanced formatted text (lists, quotes, code blocks)N/A
块类型用途支持mrkdwn
header
大粗体标题文本否(仅支持plain_text)
section
包含文本和可选附件的主要内容块
divider
水平分隔线不适用
image
带替代文本的全宽图片不适用
context
小型灰色文本和图片(用于元数据、时间戳)
actions
一行交互式元素(按钮、选择器、日期选择器)不适用
rich_text
高级格式化文本(列表、引用、代码块)不适用

Header Block

标题块

json
{
  "type": "header",
  "text": {
    "type": "plain_text",
    "text": "Weekly Marketing Report",
    "emoji": true
  }
}
json
{
  "type": "header",
  "text": {
    "type": "plain_text",
    "text": "Weekly Marketing Report",
    "emoji": true
  }
}

Section Block

内容块

Plain text section:
json
{
  "type": "section",
  "text": {
    "type": "mrkdwn",
    "text": "*Traffic is up 23%* this week compared to last week.\nOrganic search drove most of the growth."
  }
}
Section with fields (two-column layout):
json
{
  "type": "section",
  "fields": [
    {
      "type": "mrkdwn",
      "text": "*Visitors*\n12,450"
    },
    {
      "type": "mrkdwn",
      "text": "*Signups*\n342"
    },
    {
      "type": "mrkdwn",
      "text": "*MRR*\n$28,500"
    },
    {
      "type": "mrkdwn",
      "text": "*Churn*\n1.2%"
    }
  ]
}
Section with a button accessory:
json
{
  "type": "section",
  "text": {
    "type": "mrkdwn",
    "text": "New blog post: *How We Grew 10x in 6 Months*"
  },
  "accessory": {
    "type": "button",
    "text": {
      "type": "plain_text",
      "text": "Read Post"
    },
    "url": "https://example.com/blog/growth-story",
    "action_id": "read_blog_post"
  }
}
Section with an image accessory:
json
{
  "type": "section",
  "text": {
    "type": "mrkdwn",
    "text": "*New Feature: Dark Mode*\nOur most requested feature is finally here."
  },
  "accessory": {
    "type": "image",
    "image_url": "https://example.com/images/dark-mode-preview.png",
    "alt_text": "Dark mode preview"
  }
}
纯文本内容块:
json
{
  "type": "section",
  "text": {
    "type": "mrkdwn",
    "text": "*Traffic is up 23%* this week compared to last week.\nOrganic search drove most of the growth."
  }
}
带字段的内容块(两列布局):
json
{
  "type": "section",
  "fields": [
    {
      "type": "mrkdwn",
      "text": "*Visitors*\n12,450"
    },
    {
      "type": "mrkdwn",
      "text": "*Signups*\n342"
    },
    {
      "type": "mrkdwn",
      "text": "*MRR*\n$28,500"
    },
    {
      "type": "mrkdwn",
      "text": "*Churn*\n1.2%"
    }
  ]
}
带按钮附件的内容块:
json
{
  "type": "section",
  "text": {
    "type": "mrkdwn",
    "text": "New blog post: *How We Grew 10x in 6 Months*"
  },
  "accessory": {
    "type": "button",
    "text": {
      "type": "plain_text",
      "text": "Read Post"
    },
    "url": "https://example.com/blog/growth-story",
    "action_id": "read_blog_post"
  }
}
带图片附件的内容块:
json
{
  "type": "section",
  "text": {
    "type": "mrkdwn",
    "text": "*New Feature: Dark Mode*\nOur most requested feature is finally here."
  },
  "accessory": {
    "type": "image",
    "image_url": "https://example.com/images/dark-mode-preview.png",
    "alt_text": "Dark mode preview"
  }
}

Divider Block

分隔线块

json
{
  "type": "divider"
}
json
{
  "type": "divider"
}

Image Block

图片块

json
{
  "type": "image",
  "image_url": "https://example.com/images/chart.png",
  "alt_text": "Weekly traffic chart",
  "title": {
    "type": "plain_text",
    "text": "Traffic Overview"
  }
}
json
{
  "type": "image",
  "image_url": "https://example.com/images/chart.png",
  "alt_text": "Weekly traffic chart",
  "title": {
    "type": "plain_text",
    "text": "Traffic Overview"
  }
}

Context Block

上下文块

json
{
  "type": "context",
  "elements": [
    {
      "type": "mrkdwn",
      "text": "Posted by *Marketing Team* | Feb 10, 2026"
    },
    {
      "type": "image",
      "image_url": "https://example.com/logo-small.png",
      "alt_text": "Company logo"
    }
  ]
}
json
{
  "type": "context",
  "elements": [
    {
      "type": "mrkdwn",
      "text": "Posted by *Marketing Team* | Feb 10, 2026"
    },
    {
      "type": "image",
      "image_url": "https://example.com/logo-small.png",
      "alt_text": "Company logo"
    }
  ]
}

Actions Block (Buttons)

操作块(按钮)

json
{
  "type": "actions",
  "elements": [
    {
      "type": "button",
      "text": {
        "type": "plain_text",
        "text": "Approve"
      },
      "style": "primary",
      "action_id": "approve_action",
      "value": "approved"
    },
    {
      "type": "button",
      "text": {
        "type": "plain_text",
        "text": "Reject"
      },
      "style": "danger",
      "action_id": "reject_action",
      "value": "rejected"
    },
    {
      "type": "button",
      "text": {
        "type": "plain_text",
        "text": "View Details"
      },
      "url": "https://example.com/details",
      "action_id": "view_details"
    }
  ]
}
Button styles:
"primary"
(green),
"danger"
(red), or omit for default (gray).
Note on interactivity: Buttons with
action_id
(no
url
) require a Request URL configured in your Slack App settings under Interactivity & Shortcuts to receive the button click payload. Buttons with a
url
field open the link directly and do not require a backend.
json
{
  "type": "actions",
  "elements": [
    {
      "type": "button",
      "text": {
        "type": "plain_text",
        "text": "Approve"
      },
      "style": "primary",
      "action_id": "approve_action",
      "value": "approved"
    },
    {
      "type": "button",
      "text": {
        "type": "plain_text",
        "text": "Reject"
      },
      "style": "danger",
      "action_id": "reject_action",
      "value": "rejected"
    },
    {
      "type": "button",
      "text": {
        "type": "plain_text",
        "text": "View Details"
      },
      "url": "https://example.com/details",
      "action_id": "view_details"
    }
  ]
}
按钮样式:
"primary"
(绿色)、
"danger"
(红色),或省略使用默认样式(灰色)。
交互性说明: 带有
action_id
(无
url
)的按钮需要在Slack应用设置的Interactivity & Shortcuts中配置请求URL,以接收按钮点击负载。带有
url
字段的按钮会直接打开链接,不需要后端支持。

Block Kit Limits

Block Kit限制

LimitValue
Blocks per message50
Characters per text block3,000
Characters per header150
Fields per section10
Elements per actions block25
Elements per context block10
限制数值
每条消息的块数量50
每个文本块的字符数3,000
每个标题的字符数150
每个内容块的字段数量10
每个操作块的元素数量25
每个上下文块的元素数量10

Block Kit Builder

Block Kit构建器

Use the visual builder to design and preview messages before coding them: https://app.slack.com/block-kit-builder

使用可视化构建器在编写代码前设计和预览消息: https://app.slack.com/block-kit-builder

Slack mrkdwn Formatting Guide

Slack mrkdwn格式指南

Slack uses its own markdown variant called mrkdwn. It differs from standard Markdown in several ways.
FormattingSyntaxExample
Bold
*text*
bold text
Italic
_text_
italic text
Strikethrough
~text~
strikethrough
Code (inline)
`text`
inline code
Code block
```text```
Multi-line code block
Blockquote
>text
Quoted text
Link
<https://url|display text>
Clickable link
User mention
<@U0123456>
@username
Channel mention
<#C0123456>
#channel
Emoji
:emoji_name:
:rocket:
Bulleted listStart line with
- 
or
* 
Bullet point
Numbered listStart line with
1. 
Numbered item
Line break
\n
in JSON string
New line
Important differences from standard Markdown:
  • Bold uses single asterisks
    *bold*
    , not double
    **bold**
    .
  • Italic uses underscores
    _italic_
    , not single asterisks.
  • Links use
    <url|text>
    format with a pipe, not
    [text](url)
    .
  • Headers do not exist in mrkdwn. Use the
    header
    block type instead.
  • Images cannot be inlined in mrkdwn. Use the
    image
    block or
    accessory
    instead.

Slack使用自己的markdown变体mrkdwn,与标准Markdown有一些区别。
格式语法示例
粗体
*text*
bold text
斜体
_text_
italic text
删除线
~text~
strikethrough
行内代码
`text`
inline code
代码块
```text```
多行代码块
引用
>text
引用文本
链接
<https://url|display text>
可点击链接
提及用户
<@U0123456>
@username
提及频道
<#C0123456>
#channel
表情
:emoji_name:
:rocket:
项目符号列表行首使用
- 
* 
项目符号
编号列表行首使用
1. 
编号项
换行JSON字符串中使用
\n
新行
与标准Markdown的主要区别:
  • 粗体使用单个星号
    *bold*
    ,而非双个
    **bold**
  • 斜体使用下划线
    _italic_
    ,而非单个星号。
  • 链接使用
    <url|text>
    格式,带有管道符,而非
    [text](url)
  • mrkdwn中没有标题,使用
    header
    块类型替代。
  • mrkdwn中无法嵌入图片,使用
    image
    块或
    accessory
    替代。

Message Templates

消息模板

Template 1: Product Announcement

模板1:产品公告

bash
curl -s -X POST "$SLACK_WEBHOOK_URL" \
  -H "Content-Type: application/json" \
  -d '{
    "blocks": [
      {
        "type": "header",
        "text": {
          "type": "plain_text",
          "text": ":rocket: New Feature: [Feature Name]",
          "emoji": true
        }
      },
      {
        "type": "section",
        "text": {
          "type": "mrkdwn",
          "text": "We just shipped *[Feature Name]* — here is what it does and why it matters.\n\n:point_right: *What it does:* [One-sentence description]\n:point_right: *Why it matters:* [Key benefit for users]\n:point_right: *How to try it:* [Quick instructions or link]"
        }
      },
      {
        "type": "image",
        "image_url": "https://example.com/feature-screenshot.png",
        "alt_text": "Feature screenshot"
      },
      {
        "type": "divider"
      },
      {
        "type": "actions",
        "elements": [
          {
            "type": "button",
            "text": {
              "type": "plain_text",
              "text": ":newspaper: Read Announcement",
              "emoji": true
            },
            "url": "https://example.com/blog/feature-launch",
            "action_id": "read_announcement"
          },
          {
            "type": "button",
            "text": {
              "type": "plain_text",
              "text": ":play_or_pause_button: Watch Demo",
              "emoji": true
            },
            "url": "https://example.com/demo",
            "action_id": "watch_demo"
          }
        ]
      },
      {
        "type": "context",
        "elements": [
          {
            "type": "mrkdwn",
            "text": "Posted by *Product Team* | :speech_balloon: Reply in thread with questions"
          }
        ]
      }
    ]
  }'
bash
curl -s -X POST "$SLACK_WEBHOOK_URL" \
  -H "Content-Type: application/json" \
  -d '{
    "blocks": [
      {
        "type": "header",
        "text": {
          "type": "plain_text",
          "text": ":rocket: New Feature: [Feature Name]",
          "emoji": true
        }
      },
      {
        "type": "section",
        "text": {
          "type": "mrkdwn",
          "text": "We just shipped *[Feature Name]* — here is what it does and why it matters.\n\n:point_right: *What it does:* [One-sentence description]\n:point_right: *Why it matters:* [Key benefit for users]\n:point_right: *How to try it:* [Quick instructions or link]"
        }
      },
      {
        "type": "image",
        "image_url": "https://example.com/feature-screenshot.png",
        "alt_text": "Feature screenshot"
      },
      {
        "type": "divider"
      },
      {
        "type": "actions",
        "elements": [
          {
            "type": "button",
            "text": {
              "type": "plain_text",
              "text": ":newspaper: Read Announcement",
              "emoji": true
            },
            "url": "https://example.com/blog/feature-launch",
            "action_id": "read_announcement"
          },
          {
            "type": "button",
            "text": {
              "type": "plain_text",
              "text": ":play_or_pause_button: Watch Demo",
              "emoji": true
            },
            "url": "https://example.com/demo",
            "action_id": "watch_demo"
          }
        ]
      },
      {
        "type": "context",
        "elements": [
          {
            "type": "mrkdwn",
            "text": "Posted by *Product Team* | :speech_balloon: Reply in thread with questions"
          }
        ]
      }
    ]
  }'

Template 2: Weekly Metrics Report

模板2:每周指标报告

bash
curl -s -X POST "$SLACK_WEBHOOK_URL" \
  -H "Content-Type: application/json" \
  -d '{
    "blocks": [
      {
        "type": "header",
        "text": {
          "type": "plain_text",
          "text": ":bar_chart: Weekly Marketing Metrics — Feb 3-9, 2026",
          "emoji": true
        }
      },
      {
        "type": "section",
        "text": {
          "type": "mrkdwn",
          "text": "Here is this week'\''s performance snapshot."
        }
      },
      {
        "type": "divider"
      },
      {
        "type": "section",
        "text": {
          "type": "mrkdwn",
          "text": ":globe_with_meridians: *Website Traffic*"
        },
        "fields": [
          {
            "type": "mrkdwn",
            "text": "*Sessions*\n45,230 (:arrow_up: 12%)"
          },
          {
            "type": "mrkdwn",
            "text": "*Unique Visitors*\n31,870 (:arrow_up: 8%)"
          },
          {
            "type": "mrkdwn",
            "text": "*Bounce Rate*\n42.3% (:arrow_down: 2.1%)"
          },
          {
            "type": "mrkdwn",
            "text": "*Avg. Session Duration*\n3m 42s (:arrow_up: 15s)"
          }
        ]
      },
      {
        "type": "section",
        "text": {
          "type": "mrkdwn",
          "text": ":money_with_wings: *Conversion Metrics*"
        },
        "fields": [
          {
            "type": "mrkdwn",
            "text": "*Signups*\n487 (:arrow_up: 18%)"
          },
          {
            "type": "mrkdwn",
            "text": "*Trial-to-Paid*\n12.4% (:arrow_up: 1.2%)"
          },
          {
            "type": "mrkdwn",
            "text": "*MRR*\n$52,300 (:arrow_up: $3,200)"
          },
          {
            "type": "mrkdwn",
            "text": "*Churn*\n1.8% (:arrow_down: 0.3%)"
          }
        ]
      },
      {
        "type": "section",
        "text": {
          "type": "mrkdwn",
          "text": ":email: *Email Performance*"
        },
        "fields": [
          {
            "type": "mrkdwn",
            "text": "*Emails Sent*\n12,400"
          },
          {
            "type": "mrkdwn",
            "text": "*Open Rate*\n34.2%"
          },
          {
            "type": "mrkdwn",
            "text": "*Click Rate*\n4.8%"
          },
          {
            "type": "mrkdwn",
            "text": "*Unsubscribes*\n23"
          }
        ]
      },
      {
        "type": "divider"
      },
      {
        "type": "section",
        "text": {
          "type": "mrkdwn",
          "text": "*:bulb: Key Takeaways*\n- Organic traffic up 15% after publishing 3 new blog posts\n- Email welcome sequence A/B test: Variant B outperformed by 22%\n- Trial signup spike on Thursday correlated with Product Hunt feature"
        }
      },
      {
        "type": "actions",
        "elements": [
          {
            "type": "button",
            "text": {
              "type": "plain_text",
              "text": "Full Dashboard",
              "emoji": true
            },
            "url": "https://analytics.example.com/dashboard",
            "action_id": "view_dashboard"
          }
        ]
      },
      {
        "type": "context",
        "elements": [
          {
            "type": "mrkdwn",
            "text": "Auto-generated by Marketing Bot | Data from Google Analytics + Stripe"
          }
        ]
      }
    ]
  }'
bash
curl -s -X POST "$SLACK_WEBHOOK_URL" \
  -H "Content-Type: application/json" \
  -d '{
    "blocks": [
      {
        "type": "header",
        "text": {
          "type": "plain_text",
          "text": ":bar_chart: Weekly Marketing Metrics — Feb 3-9, 2026",
          "emoji": true
        }
      },
      {
        "type": "section",
        "text": {
          "type": "mrkdwn",
          "text": "Here is this week'\''s performance snapshot."
        }
      },
      {
        "type": "divider"
      },
      {
        "type": "section",
        "text": {
          "type": "mrkdwn",
          "text": ":globe_with_meridians: *Website Traffic*"
        },
        "fields": [
          {
            "type": "mrkdwn",
            "text": "*Sessions*\n45,230 (:arrow_up: 12%)"
          },
          {
            "type": "mrkdwn",
            "text": "*Unique Visitors*\n31,870 (:arrow_up: 8%)"
          },
          {
            "type": "mrkdwn",
            "text": "*Bounce Rate*\n42.3% (:arrow_down: 2.1%)"
          },
          {
            "type": "mrkdwn",
            "text": "*Avg. Session Duration*\n3m 42s (:arrow_up: 15s)"
          }
        ]
      },
      {
        "type": "section",
        "text": {
          "type": "mrkdwn",
          "text": ":money_with_wings: *Conversion Metrics*"
        },
        "fields": [
          {
            "type": "mrkdwn",
            "text": "*Signups*\n487 (:arrow_up: 18%)"
          },
          {
            "type": "mrkdwn",
            "text": "*Trial-to-Paid*\n12.4% (:arrow_up: 1.2%)"
          },
          {
            "type": "mrkdwn",
            "text": "*MRR*\n$52,300 (:arrow_up: $3,200)"
          },
          {
            "type": "mrkdwn",
            "text": "*Churn*\n1.8% (:arrow_down: 0.3%)"
          }
        ]
      },
      {
        "type": "section",
        "text": {
          "type": "mrkdwn",
          "text": ":email: *Email Performance*"
        },
        "fields": [
          {
            "type": "mrkdwn",
            "text": "*Emails Sent*\n12,400"
          },
          {
            "type": "mrkdwn",
            "text": "*Open Rate*\n34.2%"
          },
          {
            "type": "mrkdwn",
            "text": "*Click Rate*\n4.8%"
          },
          {
            "type": "mrkdwn",
            "text": "*Unsubscribes*\n23"
          }
        ]
      },
      {
        "type": "divider"
      },
      {
        "type": "section",
        "text": {
          "type": "mrkdwn",
          "text": "*:bulb: Key Takeaways*\n- Organic traffic up 15% after publishing 3 new blog posts\n- Email welcome sequence A/B test: Variant B outperformed by 22%\n- Trial signup spike on Thursday correlated with Product Hunt feature"
        }
      },
      {
        "type": "actions",
        "elements": [
          {
            "type": "button",
            "text": {
              "type": "plain_text",
              "text": "Full Dashboard",
              "emoji": true
            },
            "url": "https://analytics.example.com/dashboard",
            "action_id": "view_dashboard"
          }
        ]
      },
      {
        "type": "context",
        "elements": [
          {
            "type": "mrkdwn",
            "text": "Auto-generated by Marketing Bot | Data from Google Analytics + Stripe"
          }
        ]
      }
    ]
  }'

Template 3: Blog Post Share

模板3:博客文章分享

bash
curl -s -X POST "$SLACK_WEBHOOK_URL" \
  -H "Content-Type: application/json" \
  -d '{
    "blocks": [
      {
        "type": "header",
        "text": {
          "type": "plain_text",
          "text": ":pencil: New Blog Post Published",
          "emoji": true
        }
      },
      {
        "type": "section",
        "text": {
          "type": "mrkdwn",
          "text": "*<https://example.com/blog/post-slug|Blog Post Title Here>*\n\nA brief summary of what the post covers — keep it to 2-3 sentences that capture the key value and make people want to click through."
        },
        "accessory": {
          "type": "image",
          "image_url": "https://example.com/blog/post-og-image.png",
          "alt_text": "Blog post cover image"
        }
      },
      {
        "type": "context",
        "elements": [
          {
            "type": "mrkdwn",
            "text": ":bust_in_silhouette: Author: *Jane Smith* | :clock1: 6 min read | :label: SEO, Growth"
          }
        ]
      },
      {
        "type": "divider"
      },
      {
        "type": "section",
        "text": {
          "type": "mrkdwn",
          "text": ":mega: *Help us amplify!* Share this post on your socials. Here are ready-to-use snippets:\n\n*Twitter/X:* _Just published: [title]. [Key insight from the post]. Link in reply._\n\n*LinkedIn:* _We just published a deep dive on [topic]. Here is the #1 takeaway: [insight]._"
        }
      },
      {
        "type": "actions",
        "elements": [
          {
            "type": "button",
            "text": {
              "type": "plain_text",
              "text": "Read the Post",
              "emoji": true
            },
            "style": "primary",
            "url": "https://example.com/blog/post-slug",
            "action_id": "read_post"
          },
          {
            "type": "button",
            "text": {
              "type": "plain_text",
              "text": "Share on Twitter",
              "emoji": true
            },
            "url": "https://twitter.com/intent/tweet?text=Check%20out%20this%20post&url=https://example.com/blog/post-slug",
            "action_id": "share_twitter"
          },
          {
            "type": "button",
            "text": {
              "type": "plain_text",
              "text": "Share on LinkedIn",
              "emoji": true
            },
            "url": "https://www.linkedin.com/sharing/share-offsite/?url=https://example.com/blog/post-slug",
            "action_id": "share_linkedin"
          }
        ]
      }
    ]
  }'
bash
curl -s -X POST "$SLACK_WEBHOOK_URL" \
  -H "Content-Type: application/json" \
  -d '{
    "blocks": [
      {
        "type": "header",
        "text": {
          "type": "plain_text",
          "text": ":pencil: New Blog Post Published",
          "emoji": true
        }
      },
      {
        "type": "section",
        "text": {
          "type": "mrkdwn",
          "text": "*<https://example.com/blog/post-slug|Blog Post Title Here>*\n\nA brief summary of what the post covers — keep it to 2-3 sentences that capture the key value and make people want to click through."
        },
        "accessory": {
          "type": "image",
          "image_url": "https://example.com/blog/post-og-image.png",
          "alt_text": "Blog post cover image"
        }
      },
      {
        "type": "context",
        "elements": [
          {
            "type": "mrkdwn",
            "text": ":bust_in_silhouette: Author: *Jane Smith* | :clock1: 6 min read | :label: SEO, Growth"
          }
        ]
      },
      {
        "type": "divider"
      },
      {
        "type": "section",
        "text": {
          "type": "mrkdwn",
          "text": ":mega: *Help us amplify!* Share this post on your socials. Here are ready-to-use snippets:\n\n*Twitter/X:* _Just published: [title]. [Key insight from the post]. Link in reply._\n\n*LinkedIn:* _We just published a deep dive on [topic]. Here is the #1 takeaway: [insight]._"
        }
      },
      {
        "type": "actions",
        "elements": [
          {
            "type": "button",
            "text": {
              "type": "plain_text",
              "text": "Read the Post",
              "emoji": true
            },
            "style": "primary",
            "url": "https://example.com/blog/post-slug",
            "action_id": "read_post"
          },
          {
            "type": "button",
            "text": {
              "type": "plain_text",
              "text": "Share on Twitter",
              "emoji": true
            },
            "url": "https://twitter.com/intent/tweet?text=Check%20out%20this%20post&url=https://example.com/blog/post-slug",
            "action_id": "share_twitter"
          },
          {
            "type": "button",
            "text": {
              "type": "plain_text",
              "text": "Share on LinkedIn",
              "emoji": true
            },
            "url": "https://www.linkedin.com/sharing/share-offsite/?url=https://example.com/blog/post-slug",
            "action_id": "share_linkedin"
          }
        ]
      }
    ]
  }'

Template 4: Team Update / Standup

模板4:团队更新/站会

bash
curl -s -X POST "$SLACK_WEBHOOK_URL" \
  -H "Content-Type: application/json" \
  -d '{
    "blocks": [
      {
        "type": "header",
        "text": {
          "type": "plain_text",
          "text": ":clipboard: Marketing Team Update — Monday, Feb 10",
          "emoji": true
        }
      },
      {
        "type": "section",
        "text": {
          "type": "mrkdwn",
          "text": "*:white_check_mark: Completed Last Week*\n- Launched email welcome sequence v2\n- Published 3 blog posts (SEO, product, case study)\n- Set up Google Ads remarketing campaign\n- Shipped landing page A/B test (Variant B live)"
        }
      },
      {
        "type": "section",
        "text": {
          "type": "mrkdwn",
          "text": "*:construction: In Progress*\n- Content calendar for March (70% done)\n- Competitor analysis report (due Wednesday)\n- Social media campaign for Product Hunt launch"
        }
      },
      {
        "type": "section",
        "text": {
          "type": "mrkdwn",
          "text": "*:dart: This Week'\''s Priorities*\n1. Finalize Product Hunt launch assets\n2. Send weekly newsletter (Thursday 9am)\n3. Review and approve Q1 ad spend budget\n4. Onboard new content writer"
        }
      },
      {
        "type": "section",
        "text": {
          "type": "mrkdwn",
          "text": "*:warning: Blockers*\n- Waiting on design team for Product Hunt gallery images\n- Need legal review on new case study before publishing"
        }
      },
      {
        "type": "divider"
      },
      {
        "type": "context",
        "elements": [
          {
            "type": "mrkdwn",
            "text": ":speech_balloon: Reply in thread with your own updates or questions"
          }
        ]
      }
    ]
  }'
bash
curl -s -X POST "$SLACK_WEBHOOK_URL" \
  -H "Content-Type: application/json" \
  -d '{
    "blocks": [
      {
        "type": "header",
        "text": {
          "type": "plain_text",
          "text": ":clipboard: Marketing Team Update — Monday, Feb 10",
          "emoji": true
        }
      },
      {
        "type": "section",
        "text": {
          "type": "mrkdwn",
          "text": "*:white_check_mark: Completed Last Week*\n- Launched email welcome sequence v2\n- Published 3 blog posts (SEO, product, case study)\n- Set up Google Ads remarketing campaign\n- Shipped landing page A/B test (Variant B live)"
        }
      },
      {
        "type": "section",
        "text": {
          "type": "mrkdwn",
          "text": "*:construction: In Progress*\n- Content calendar for March (70% done)\n- Competitor analysis report (due Wednesday)\n- Social media campaign for Product Hunt launch"
        }
      },
      {
        "type": "section",
        "text": {
          "type": "mrkdwn",
          "text": "*:dart: This Week'\''s Priorities*\n1. Finalize Product Hunt launch assets\n2. Send weekly newsletter (Thursday 9am)\n3. Review and approve Q1 ad spend budget\n4. Onboard new content writer"
        }
      },
      {
        "type": "section",
        "text": {
          "type": "mrkdwn",
          "text": "*:warning: Blockers*\n- Waiting on design team for Product Hunt gallery images\n- Need legal review on new case study before publishing"
        }
      },
      {
        "type": "divider"
      },
      {
        "type": "context",
        "elements": [
          {
            "type": "mrkdwn",
            "text": ":speech_balloon: Reply in thread with your own updates or questions"
          }
        ]
      }
    ]
  }'

Template 5: Incident / Urgent Notification

模板5:事件/紧急通知

bash
curl -s -X POST "$SLACK_WEBHOOK_URL" \
  -H "Content-Type: application/json" \
  -d '{
    "blocks": [
      {
        "type": "header",
        "text": {
          "type": "plain_text",
          "text": ":rotating_light: Marketing Alert",
          "emoji": true
        }
      },
      {
        "type": "section",
        "text": {
          "type": "mrkdwn",
          "text": "*Issue:* [Brief description of the problem]\n*Impact:* [Who/what is affected]\n*Status:* :red_circle: Active\n*Owner:* <@U0123456>"
        }
      },
      {
        "type": "section",
        "text": {
          "type": "mrkdwn",
          "text": "*Details:*\n[Longer explanation. What happened, when it started, what we know so far.]"
        }
      },
      {
        "type": "section",
        "text": {
          "type": "mrkdwn",
          "text": "*Next Steps:*\n1. [Action item 1]\n2. [Action item 2]\n3. [Action item 3]"
        }
      },
      {
        "type": "actions",
        "elements": [
          {
            "type": "button",
            "text": {
              "type": "plain_text",
              "text": "Status Page"
            },
            "url": "https://status.example.com",
            "action_id": "status_page"
          }
        ]
      }
    ]
  }'

bash
curl -s -X POST "$SLACK_WEBHOOK_URL" \
  -H "Content-Type: application/json" \
  -d '{
    "blocks": [
      {
        "type": "header",
        "text": {
          "type": "plain_text",
          "text": ":rotating_light: Marketing Alert",
          "emoji": true
        }
      },
      {
        "type": "section",
        "text": {
          "type": "mrkdwn",
          "text": "*Issue:* [Brief description of the problem]\n*Impact:* [Who/what is affected]\n*Status:* :red_circle: Active\n*Owner:* <@U0123456>"
        }
      },
      {
        "type": "section",
        "text": {
          "type": "mrkdwn",
          "text": "*Details:*\n[Longer explanation. What happened, when it started, what we know so far.]"
        }
      },
      {
        "type": "section",
        "text": {
          "type": "mrkdwn",
          "text": "*Next Steps:*\n1. [Action item 1]\n2. [Action item 2]\n3. [Action item 3]"
        }
      },
      {
        "type": "actions",
        "elements": [
          {
            "type": "button",
            "text": {
              "type": "plain_text",
              "text": "Status Page"
            },
            "url": "https://status.example.com",
            "action_id": "status_page"
          }
        ]
      }
    ]
  }'

Workflows

工作流

Workflow 1: Post a Marketing Announcement

工作流1:发布营销公告

When the user asks to post an announcement, product update, or news to Slack:
  1. Gather details - Ask for the announcement title, body, link, image URL, and target channel.
  2. Choose a template - Select from the templates above or build a custom Block Kit payload.
  3. Build the payload - Construct the JSON with proper mrkdwn formatting.
  4. Preview - Show the user the full JSON payload and describe how it will render.
  5. Confirm - Ask the user to approve before sending.
  6. Send - Execute the curl command.
  7. Report - Show the API response. For Web API, capture the
    ts
    for threading.
当用户要求在Slack上发布公告、产品更新或新闻时:
  1. 收集详情 - 询问公告标题、正文、链接、图片URL和目标频道。
  2. 选择模板 - 从上述模板中选择或构建自定义Block Kit负载。
  3. 构建负载 - 使用正确的mrkdwn格式构造JSON。
  4. 预览 - 向用户展示完整的JSON负载,并描述其呈现效果。
  5. 确认 - 在发送前请求用户批准。
  6. 发送 - 执行curl命令。
  7. 报告 - 展示API响应。对于Web API,捕获
    ts
    用于线程回复。

Workflow 2: Post Weekly Metrics

工作流2:发布每周指标

When the user asks to send a metrics report or dashboard to Slack:
  1. Collect metrics - Ask for the numbers or help pull them from analytics tools.
  2. Format with fields - Use section blocks with
    fields
    for the two-column metric layout.
  3. Add context - Include week-over-week comparisons with arrow emoji.
  4. Add takeaways - Summarize 2-3 key insights in a section block.
  5. Include a dashboard link - Add a button to the full analytics dashboard.
  6. Send and thread - Post the main report, then thread detailed breakdowns as replies.
当用户要求在Slack上发送指标报告或仪表板时:
  1. 收集指标 - 询问具体数值或协助从分析工具中获取。
  2. 使用字段格式化 - 使用带有
    fields
    的内容块实现两列指标布局。
  3. 添加上下文 - 包含周环比数据,并使用箭头表情。
  4. 添加关键结论 - 在内容块中总结2-3个关键见解。
  5. 添加仪表板链接 - 添加指向完整分析仪表板的按钮。
  6. 发送并回复线程 - 发布主报告,然后在线程中回复详细的细分内容。

Workflow 3: Share a Blog Post

工作流3:分享博客文章

When a new blog post needs to be distributed to the team:
  1. Get the URL - Ask for the blog post URL, or fetch the latest from the blog.
  2. Extract metadata - Use WebFetch to pull the title, description, author, and OG image.
  3. Build the share message - Use Template 3 with social amplification snippets.
  4. Add share buttons - Include Twitter and LinkedIn intent URLs pre-populated with the post.
  5. Post to the channel - Send to the team marketing channel.
当需要向团队分发新博客文章时:
  1. 获取URL - 询问博客文章URL,或从博客中获取最新文章。
  2. 提取元数据 - 使用WebFetch获取标题、描述、作者和OG图片。
  3. 构建分享消息 - 使用模板3,并添加社交推广片段。
  4. 添加分享按钮 - 包含预填充文章信息的Twitter和LinkedIn意图URL。
  5. 发布到频道 - 发送到团队营销频道。

Workflow 4: Community Engagement

工作流4:社区互动

For managing Slack community channels (public communities, customer channels):
  1. Welcome messages - Post a welcome message with rules and resources when new members join.
  2. Scheduled updates - Post weekly roundups of popular discussions or new resources.
  3. Event announcements - Share upcoming webinars, AMAs, or meetups with RSVP buttons.
  4. Polls and feedback - Use actions blocks with buttons to collect quick feedback.
  5. Thread management - Reply to existing threads with updates or answers.

用于管理Slack社区频道(公共社区、客户频道):
  1. 欢迎消息 - 当新成员加入时,发布包含规则和资源的欢迎消息。
  2. 定时更新 - 每周发布热门讨论或新资源的汇总。
  3. 活动公告 - 分享即将到来的网络研讨会、AMA或线下聚会,并附带RSVP按钮。
  4. 投票和反馈 - 使用操作块和按钮收集快速反馈。
  5. 线程管理 - 在现有线程中回复更新或解答问题。

Sending Messages with Dynamic Content

发送动态内容消息

Build Payloads with Shell Variables

使用Shell变量构建负载

bash
TITLE="Product X v2.0 Released"
DESCRIPTION="Version 2.0 includes dark mode, API improvements, and 3x faster performance."
LINK="https://example.com/changelog/v2"
IMAGE_URL="https://example.com/images/v2-banner.png"
CHANNEL="#announcements"

curl -s -X POST "https://slack.com/api/chat.postMessage" \
  -H "Authorization: Bearer ${SLACK_BOT_TOKEN}" \
  -H "Content-Type: application/json" \
  -d "$(python3 -c "
import json
payload = {
    'channel': '${CHANNEL}',
    'text': '${TITLE}',
    'blocks': [
        {
            'type': 'header',
            'text': {'type': 'plain_text', 'text': '${TITLE}', 'emoji': True}
        },
        {
            'type': 'section',
            'text': {'type': 'mrkdwn', 'text': '${DESCRIPTION}'}
        },
        {
            'type': 'image',
            'image_url': '${IMAGE_URL}',
            'alt_text': '${TITLE}'
        },
        {
            'type': 'actions',
            'elements': [{
                'type': 'button',
                'text': {'type': 'plain_text', 'text': 'Learn More'},
                'url': '${LINK}',
                'style': 'primary',
                'action_id': 'learn_more'
            }]
        }
    ]
}
print(json.dumps(payload))
")"
bash
TITLE="Product X v2.0 Released"
DESCRIPTION="Version 2.0 includes dark mode, API improvements, and 3x faster performance."
LINK="https://example.com/changelog/v2"
IMAGE_URL="https://example.com/images/v2-banner.png"
CHANNEL="#announcements"

curl -s -X POST "https://slack.com/api/chat.postMessage" \
  -H "Authorization: Bearer ${SLACK_BOT_TOKEN}" \
  -H "Content-Type: application/json" \
  -d "$(python3 -c "
import json
payload = {
    'channel': '${CHANNEL}',
    'text': '${TITLE}',
    'blocks': [
        {
            'type': 'header',
            'text': {'type': 'plain_text', 'text': '${TITLE}', 'emoji': True}
        },
        {
            'type': 'section',
            'text': {'type': 'mrkdwn', 'text': '${DESCRIPTION}'}
        },
        {
            'type': 'image',
            'image_url': '${IMAGE_URL}',
            'alt_text': '${TITLE}'
        },
        {
            'type': 'actions',
            'elements': [{
                'type': 'button',
                'text': {'type': 'plain_text', 'text': 'Learn More'},
                'url': '${LINK}',
                'style': 'primary',
                'action_id': 'learn_more'
            }]
        }
    ]
}
print(json.dumps(payload))
")"

Build Payloads from a JSON File

从JSON文件构建负载

For complex messages, write the payload to a file first:
bash
undefined
对于复杂消息,先将负载写入文件:
bash
undefined

Write the payload

写入负载

cat > /tmp/slack-message.json << 'PAYLOAD' { "channel": "#marketing", "text": "Fallback text for notifications", "blocks": [ { "type": "header", "text": { "type": "plain_text", "text": "Message Title" } }, { "type": "section", "text": { "type": "mrkdwn", "text": "Message body with bold and italic formatting." } } ] } PAYLOAD
cat > /tmp/slack-message.json << 'PAYLOAD' { "channel": "#marketing", "text": "Fallback text for notifications", "blocks": [ { "type": "header", "text": { "type": "plain_text", "text": "Message Title" } }, { "type": "section", "text": { "type": "mrkdwn", "text": "Message body with bold and italic formatting." } } ] } PAYLOAD

Send it

发送消息

curl -s -X POST "https://slack.com/api/chat.postMessage"
-H "Authorization: Bearer ${SLACK_BOT_TOKEN}"
-H "Content-Type: application/json"
-d @/tmp/slack-message.json

---
curl -s -X POST "https://slack.com/api/chat.postMessage"
-H "Authorization: Bearer ${SLACK_BOT_TOKEN}"
-H "Content-Type: application/json"
-d @/tmp/slack-message.json

---

Scheduled Messages

定时消息

Post a message at a specific future time using
chat.scheduleMessage
:
bash
undefined
使用
chat.scheduleMessage
在特定未来时间发送消息:
bash
undefined

Schedule a message for a specific Unix timestamp

为特定Unix时间戳安排消息

Use: date -d "2026-02-12 09:00:00" +%s (Linux) or date -j -f "%Y-%m-%d %H:%M:%S" "2026-02-12 09:00:00" +%s (macOS)

使用:date -d "2026-02-12 09:00:00" +%s(Linux)或date -j -f "%Y-%m-%d %H:%M:%S" "2026-02-12 09:00:00" +%s(macOS)

SEND_AT=$(date -j -f "%Y-%m-%d %H:%M:%S" "2026-02-12 09:00:00" +%s 2>/dev/null || date -d "2026-02-12 09:00:00" +%s)
curl -s -X POST "https://slack.com/api/chat.scheduleMessage"
-H "Authorization: Bearer ${SLACK_BOT_TOKEN}"
-H "Content-Type: application/json"
-d "{ "channel": "#marketing", "post_at": ${SEND_AT}, "text": "Good morning team! Here is today's marketing agenda.", "blocks": [] }"

List scheduled messages:

```bash
curl -s "https://slack.com/api/chat.scheduledMessages.list" \
  -H "Authorization: Bearer ${SLACK_BOT_TOKEN}" | \
  python3 -c "
import json, sys, datetime
data = json.load(sys.stdin)
for msg in data.get('scheduled_messages', []):
    ts = datetime.datetime.fromtimestamp(msg['post_at']).strftime('%Y-%m-%d %H:%M')
    print(f\"ID: {msg['id']}  |  Channel: {msg['channel_id']}  |  Scheduled: {ts}\")
"
Delete a scheduled message:
bash
curl -s -X POST "https://slack.com/api/chat.deleteScheduledMessage" \
  -H "Authorization: Bearer ${SLACK_BOT_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{
    "channel": "C0123456789",
    "scheduled_message_id": "Q0123456789"
  }'

SEND_AT=$(date -j -f "%Y-%m-%d %H:%M:%S" "2026-02-12 09:00:00" +%s 2>/dev/null || date -d "2026-02-12 09:00:00" +%s)
curl -s -X POST "https://slack.com/api/chat.scheduleMessage"
-H "Authorization: Bearer ${SLACK_BOT_TOKEN}"
-H "Content-Type: application/json"
-d "{ "channel": "#marketing", "post_at": ${SEND_AT}, "text": "Good morning team! Here is today's marketing agenda.", "blocks": [] }"

列出定时消息:

```bash
curl -s "https://slack.com/api/chat.scheduledMessages.list" \
  -H "Authorization: Bearer ${SLACK_BOT_TOKEN}" | \
  python3 -c "
import json, sys, datetime
data = json.load(sys.stdin)
for msg in data.get('scheduled_messages', []):
    ts = datetime.datetime.fromtimestamp(msg['post_at']).strftime('%Y-%m-%d %H:%M')
    print(f\"ID: {msg['id']}  |  Channel: {msg['channel_id']}  |  Scheduled: {ts}\")
"
删除定时消息:
bash
curl -s -X POST "https://slack.com/api/chat.deleteScheduledMessage" \
  -H "Authorization: Bearer ${SLACK_BOT_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{
    "channel": "C0123456789",
    "scheduled_message_id": "Q0123456789"
  }'

Multi-Channel Posting

多频道发布

Post the same message to multiple channels:
bash
CHANNELS=("#marketing" "#general" "#product")
MESSAGE='{"text":"Big announcement coming tomorrow!","blocks":[{"type":"section","text":{"type":"mrkdwn","text":":mega: *Big announcement coming tomorrow!* Stay tuned."}}]}'

for CHANNEL in "${CHANNELS[@]}"; do
  echo "Posting to ${CHANNEL}..."
  echo "$MESSAGE" | python3 -c "
import json, sys
msg = json.load(sys.stdin)
msg['channel'] = '${CHANNEL}'
print(json.dumps(msg))
" | curl -s -X POST "https://slack.com/api/chat.postMessage" \
    -H "Authorization: Bearer ${SLACK_BOT_TOKEN}" \
    -H "Content-Type: application/json" \
    -d @- | python3 -c "
import json, sys
r = json.load(sys.stdin)
if r.get('ok'):
    print(f'  Sent. ts={r[\"ts\"]}')
else:
    print(f'  Error: {r.get(\"error\", \"unknown\")}')
"
done

向多个频道发送相同消息:
bash
CHANNELS=("#marketing" "#general" "#product")
MESSAGE='{"text":"Big announcement coming tomorrow!","blocks":[{"type":"section","text":{"type":"mrkdwn","text":":mega: *Big announcement coming tomorrow!* Stay tuned."}}]}'

for CHANNEL in "${CHANNELS[@]}"; do
  echo "Posting to ${CHANNEL}..."
  echo "$MESSAGE" | python3 -c "
import json, sys
msg = json.load(sys.stdin)
msg['channel'] = '${CHANNEL}'
print(json.dumps(msg))
" | curl -s -X POST "https://slack.com/api/chat.postMessage" \
    -H "Authorization: Bearer ${SLACK_BOT_TOKEN}" \
    -H "Content-Type: application/json" \
    -d @- | python3 -c "
import json, sys
r = json.load(sys.stdin)
if r.get('ok'):
    print(f'  Sent. ts={r[\"ts\"]}')
else:
    print(f'  Error: {r.get(\"error\", \"unknown\")}')
"
done

Error Handling

错误处理

Common API Errors

常见API错误

ErrorCauseFix
invalid_auth
Bad or expired tokenRegenerate the bot token in Slack App settings
channel_not_found
Bot not in channel or wrong channel nameInvite bot with
/invite @BotName
or use channel ID
not_in_channel
Bot needs to join the channel firstInvite the bot or use
chat:write.public
scope
too_many_attachments
Over 50 blocksSplit the message into multiple posts or thread replies
msg_too_long
Text exceeds 40,000 charactersShorten the message or split into parts
rate_limited
Too many requestsWait the number of seconds in the
Retry-After
header
missing_scope
Token lacks required permissionAdd the scope in OAuth & Permissions and reinstall the app
错误原因解决方法
invalid_auth
令牌错误或过期在Slack应用设置中重新生成Bot令牌
channel_not_found
机器人未加入频道或频道名称错误使用
/invite @BotName
邀请机器人或使用频道ID
not_in_channel
机器人需要先加入频道邀请机器人或使用
chat:write.public
权限范围
too_many_attachments
超过50个块将消息拆分为多个帖子或线程回复
msg_too_long
文本超过40,000字符缩短消息或拆分为多个部分
rate_limited
请求过于频繁等待
Retry-After
头中指定的秒数
missing_scope
令牌缺少必要的权限在OAuth & Permissions中添加权限范围并重新安装应用

Validate a Response

验证响应

bash
RESPONSE=$(curl -s -X POST "https://slack.com/api/chat.postMessage" \
  -H "Authorization: Bearer ${SLACK_BOT_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{"channel":"#marketing","text":"Test message"}')

python3 -c "
import json, sys
r = json.loads('${RESPONSE}'.replace(\"'\", \"\"))
if r.get('ok'):
    print(f'Message sent successfully. ts={r[\"ts\"]} channel={r[\"channel\"]}')
else:
    print(f'Error: {r.get(\"error\", \"unknown\")}')
    if r.get('response_metadata', {}).get('messages'):
        for m in r['response_metadata']['messages']:
            print(f'  Detail: {m}')
" 2>/dev/null || echo "$RESPONSE"
A more robust approach using a temp file:
bash
RESPONSE_FILE=$(mktemp)
curl -s -X POST "https://slack.com/api/chat.postMessage" \
  -H "Authorization: Bearer ${SLACK_BOT_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{"channel":"#marketing","text":"Test message"}' \
  -o "$RESPONSE_FILE"

python3 -c "
import json
with open('${RESPONSE_FILE}') as f:
    r = json.load(f)
if r.get('ok'):
    print(f'Sent. ts={r[\"ts\"]}')
else:
    print(f'Error: {r.get(\"error\")}')
"
rm -f "$RESPONSE_FILE"

bash
RESPONSE=$(curl -s -X POST "https://slack.com/api/chat.postMessage" \
  -H "Authorization: Bearer ${SLACK_BOT_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{"channel":"#marketing","text":"Test message"}')

python3 -c "
import json, sys
r = json.loads('${RESPONSE}'.replace(\"'\", \"\"))
if r.get('ok'):
    print(f'Message sent successfully. ts={r[\"ts\"]} channel={r[\"channel\"]}')
else:
    print(f'Error: {r.get(\"error\", \"unknown\")}')
    if r.get('response_metadata', {}).get('messages'):
        for m in r['response_metadata']['messages']:
            print(f'  Detail: {m}')
" 2>/dev/null || echo "$RESPONSE"
使用临时文件的更可靠方法:
bash
RESPONSE_FILE=$(mktemp)
curl -s -X POST "https://slack.com/api/chat.postMessage" \
  -H "Authorization: Bearer ${SLACK_BOT_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{"channel":"#marketing","text":"Test message"}' \
  -o "$RESPONSE_FILE"

python3 -c "
import json
with open('${RESPONSE_FILE}') as f:
    r = json.load(f)
if r.get('ok'):
    print(f'Sent. ts={r[\"ts\"]}')
else:
    print(f'Error: {r.get(\"error\")}')
"
rm -f "$RESPONSE_FILE"

Tips

提示

  • Always include a
    text
    field alongside
    blocks
    — it serves as the fallback for notifications, accessibility readers, and clients that do not support Block Kit.
  • Use the Block Kit Builder at https://app.slack.com/block-kit-builder to visually design and preview messages before building the curl commands.
  • For production workflows, use
    chat.postMessage
    (Web API) over webhooks. It returns a message
    ts
    you can use for threading, updating, and deleting.
  • Thread long reports. Post a summary as the parent message and details as threaded replies to keep channels clean.
  • Use
    :emoji:
    codes in
    plain_text
    fields with
    "emoji": true
    to render emoji in headers and button labels.
  • Escape special characters in mrkdwn:
    &
    becomes
    &amp;
    ,
    <
    becomes
    &lt;
    ,
    >
    becomes
    &gt;
    .
  • Rate limits: Slack allows roughly 1 message per second per channel. For bulk posting, add a 1-second delay between requests.
  • When posting metrics, use section
    fields
    for the two-column layout rather than trying to format tables in mrkdwn (Slack does not support tables).
  • Always show the user the full message payload and ask for confirmation before posting.
  • 始终在
    blocks
    旁边包含
    text
    字段——它作为通知、辅助功能阅读器和不支持Block Kit的客户端的回退内容。
  • 在构建curl命令之前,使用Block Kit构建器(https://app.slack.com/block-kit-builder)可视化设计和预览消息。
  • 对于生产工作流,优先使用Web API的
    chat.postMessage
    而非Webhook,它会返回消息
    ts
    ,可用于线程回复、更新和删除。
  • 对长报告使用线程回复。发布摘要作为父消息,详细内容作为线程回复,以保持频道整洁。
  • plain_text
    字段中使用
    :emoji:
    代码并设置
    "emoji": true
    ,以在标题和按钮标签中渲染表情。
  • 转义mrkdwn中的特殊字符:
    &
    变为
    &amp;
    <
    变为
    &lt;
    >
    变为
    &gt;
  • 速率限制:Slack允许每个频道大约每秒1条消息。对于批量发布,在请求之间添加1秒延迟。
  • 发布指标时,使用内容块的
    fields
    实现两列布局,而不是尝试在mrkdwn中格式化表格(Slack不支持表格)。
  • 在发布前始终向用户展示完整的消息负载并请求确认。