with one click
slack
// Read Slack threads or channel history and post concise bot replies through slack-post-message when the user asks to answer in Slack or when a Slack event payload provides channel and thread context.
// Read Slack threads or channel history and post concise bot replies through slack-post-message when the user asks to answer in Slack or when a Slack event payload provides channel and thread context.
[HINT] Download the complete skill directory including SKILL.md and all related files
| name | slack |
| description | Read Slack threads or channel history and post concise bot replies through slack-post-message when the user asks to answer in Slack or when a Slack event payload provides channel and thread context. |
Use this skill when:
channel and thread_ts contextGeneral reply policy lives in build.md. This skill only covers how to read
and write Slack through the proxy.
Talk to Slack through real upstream URLs:
https://slack.com/api/...https://files.slack.com/files-pri/...Authentication is injected automatically, do not pass Authorization header.
The default tool for Slack reads is curl. For message writes, use slack-post-message.
For file uploads, prefer slack-upload over manually calling Slack's
multi-step upload endpoints.
/tmp is the default location for all temporary Slack artifacts, including:
Do not save these files in /workspace/repos or /workspace/worktrees unless
the user explicitly asks to keep a persistent copy.
Decision rule:
/tmp with mktempmktemp -d and write the named file inside itDo not use fixed paths like /tmp/report.txt or relative paths like
./report.txt for temporary Slack artifacts.
The proxy injects Slack auth only for the narrow endpoint set used by this
skill: reactions.add, conversations.replies,
conversations.history, files.info, Slack's external upload endpoints, and
supported files.slack.com file URLs. Do not call Slack update/delete methods
or reaction update/remove methods through this path.
Prefer explicit Slack context from the task:
channelthread_tsIf thread_ts is present, reply in-thread. Do not create a new top-level
message when a thread reply is possible.
For a thread reply, read the thread first unless the task already contains the full context you need.
curl -sS --get https://slack.com/api/conversations.replies \
--data-urlencode 'channel=C123' \
--data-urlencode 'ts=1710000000.001' \
--data-urlencode 'limit=50'
Use channel history only when there is no thread or when the user explicitly needs broader channel context.
curl -sS --get https://slack.com/api/conversations.history \
--data-urlencode 'channel=C123' \
--data-urlencode 'limit=20'
If the thread references a Slack file and the file contents are needed, inspect the file first and then download from its private Slack URL when necessary.
curl -sS --get https://slack.com/api/files.info \
--data-urlencode 'file=F123'
When the response includes url_private or url_private_download, fetch that
URL directly. Auth is injected for the supported files.slack.com paths.
Always download temporary Slack files to a unique temp path under /tmp.
DOWNLOAD_DIR="$(mktemp -d /tmp/slack-download.XXXXXX)"
DOWNLOAD_FILE="$DOWNLOAD_DIR/example.bin"
curl -sS -o "$DOWNLOAD_FILE" \
'https://files.slack.com/files-pri/T123-F123/download/example'
For a short single-line reply, pipe text into slack-post-message:
echo 'Root cause looks like a missing env var in the worker deploy. I confirmed the crash started after the 14:10 rollout. Next step: redeploy with FOO_API_KEY restored.' | \
slack-post-message --channel C123 --thread-ts 1710000000.001
Always pass --channel <id>. Message text must come from stdin.
If you need blocks, pass --blocks-file <path> to a JSON file that contains a
top-level blocks array while still supplying stdin text as the fallback body.
For any multiline reply, use a heredoc or pipe. This is the default when the message has paragraph breaks, bullets, code spans, or uncertain shell quoting.
slack-post-message --channel C123 --thread-ts 1710000000.001 <<'EOF'
Good news: the AI did not crash.
The suite still has 0 test cases, so create_manual_ai_session had nothing to run.
EOF
Use reactions.add only when the user explicitly asks for an emoji reaction or
when a workflow instruction calls for one, such as marking a Slack message done.
curl -sS -X POST https://slack.com/api/reactions.add \
-H 'content-type: application/x-www-form-urlencoded' \
--data-urlencode 'channel=C123' \
--data-urlencode 'timestamp=1710000000.001' \
--data-urlencode 'name=done'
Use the helper instead of re-creating Slack's external upload flow inline. Generate the file in a unique temp path first unless the user explicitly asks to keep it. If the filename matters, use a unique temp directory and a named file inside it.
UPLOAD_DIR="$(mktemp -d /tmp/slack-upload.XXXXXX)"
REPORT_FILE="$UPLOAD_DIR/report.txt"
cat <<'EOF' >"$REPORT_FILE"
Summary:
- deploy is healthy
- backlog drain is complete
EOF
slack-upload "$REPORT_FILE" \
--channel C123 \
--thread-ts 1710000000.001 \
--comment 'Attached the report.'
Slack Web API responses are JSON with an ok field.
ok: true means the call succeededok: false means inspect the error field and surface the problem clearlyCommon failures to report as-is:
channel_not_foundnot_in_channelmissing_scoperatelimitedC... and F..., not channel names.thread_ts should be the parent message timestamp for the thread.reactions.add is the only reaction mutation supported through the proxy; do
not call reaction update/remove methods.slack-post-message.\n inside single-quoted text=... arguments.mktemp under /tmp; use
mktemp -d when you need a stable filename inside a unique temp directory.slack-upload for uploads; it wraps files.getUploadURLExternal,
the raw files.slack.com/upload/v1/... upload, and
files.completeUploadExternal./tmp is the default location for temporary Slack artifacts. Treat
/workspace/worktrees as persistent storage and use it only when
persistence is explicitly requested.files.info gives metadata first; the actual file bytes come from
url_private or url_private_download.