[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M70FWPR01A601Q9PV03GABJ1":3,"skill-same:01M70FWPR01A601Q9PV03GABJ1":78},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":31,"publishedAt":52,"linkOnly":53,"markdownContent":54,"markdownBody":55,"frontMatter":56,"refName":57,"commitSha":58,"skillDirectory":59,"forksCount":60,"repositoryHtmlUrl":61,"repositoryHomepageUrl":6,"ownerHtmlUrl":62,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":63,"install":64,"resources":77},"01M70FWPR01A601Q9PV03GABJ1","slack-cli-api-reference",null,"Slack Web API curl 命令参考——发\u002F更\u002F删消息、thread reply、reactions.add、文件上传 v2、读 thread、频道\u002F用户查询、Block Kit 选型、token 提取、URL→ts 转换、常见坑全集。Use when 查 API 命令语法\u002F参数、排查 `invalid_blocks`\u002F`not_in_channel`\u002F`missing_scope`\u002F消息只剩首行\u002Fattachment 静默丢失、或需要 `reactions.add`\u002F`files.getUploadURLExternal`\u002F`chat.getPermalink` 的具体 curl 示例。","KarryViber\u002FOrb","KarryViber","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F223777671?v=4","01M70FTGZ485AP97T3CJCYW1Z2","Karryz","01M70FTGZRWF3FEQBYZ3JWTSPR",66,"MIT","https:\u002F\u002Fgithub.com\u002FKarryViber\u002FOrb\u002Fblob\u002Fmain\u002Fprofiles\u002F.claude\u002Fskills\u002Fslack-cli-api-reference\u002FSKILL.md",[18,23,26],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000005","邮件与沟通","SCENARIO","使用场景",{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000010","后端与接口",{"categoryNo":27,"categoryName":28,"taxonomyType":29,"taxonomyTypeDesc":30},"01JBSEEDCAT000000000000030","开发工程师","PROFESSION","适用职业",[32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51],"slack cli api reference","api","cli","slack","reference","slack cli","reactions","web","curl","chat","URL","when","thread","use","files","文件","kit","missing","scope","invalid","2026-11-10 10:12:30",false,"---\nname: slack-cli-api-reference\ndescription: Slack Web API curl 命令参考——发\u002F更\u002F删消息、thread reply、reactions.add、文件上传 v2、读 thread、频道\u002F用户查询、Block Kit 选型、token 提取、URL→ts 转换、常见坑全集。Use when 查 API 命令语法\u002F参数、排查 `invalid_blocks`\u002F`not_in_channel`\u002F`missing_scope`\u002F消息只剩首行\u002Fattachment 静默丢失、或需要 `reactions.add`\u002F`files.getUploadURLExternal`\u002F`chat.getPermalink` 的具体 curl 示例。\n---\n\n# Slack Web API curl 参考手册\n\n## When to Use\n\n- 查具体 curl 命令参数（channel、ts、blocks 字段格式）\n- Slack URL → timestamp 转换\n- 排查 `invalid_blocks` \u002F `not_in_channel` \u002F `missing_scope` \u002F 消息只剩首行\n- 需要 `reactions.add` \u002F 文件上传 \u002F `chat.getPermalink` 的完整示例\n\n## Token 提取（必用）\n\n```bash\nSLACK_BOT_TOKEN=$(grep -E '^SLACK_BOT_TOKEN=' ~\u002FOrb\u002F.env | head -1 | cut -d= -f2- | tr -d \"'\" '\"')\n```\n\n**禁止** `source ~\u002FOrb\u002F.env`——第 26 行 `SLACK_HOME_CHANNEL_NAME=Karry Slack DM` 未加引号，bash 会把 `Slack DM` 当命令执行 → `bash: Slack: command not found`。\n\n必需 Bot Scopes：`channels:history` · `channels:read` · `groups:history` · `chat:write` · `chat:write.public` · `users:read` · `files:write` · `reactions:write`\n\n---\n\n## 发送消息\n\n### 发文本 \u002F Thread Reply\n\n始终用 `Content-Type: application\u002Fjson`——form-encoded 传 `attachments[].blocks` 会被 Slack **静默丢弃**。\n\n```bash\ncurl -s https:\u002F\u002Fslack.com\u002Fapi\u002Fchat.postMessage \\\n  -H \"Authorization: Bearer $SLACK_BOT_TOKEN\" \\\n  -H \"Content-Type: application\u002Fjson; charset=utf-8\" \\\n  --data-raw '{\n    \"channel\": \"C01ABC123\",\n    \"thread_ts\": \"1775307969.013919\",\n    \"text\": \"fallback 摘要（不要传空格）\",\n    \"blocks\": [{\"type\":\"section\",\"text\":{\"type\":\"mrkdwn\",\"text\":\"*详情*\"}}],\n    \"unfurl_links\": false,\n    \"unfurl_media\": false\n  }'\n```\n\n`thread_ts` 省略 = 发主消息，带上 = 发 thread reply。\n\n### 更新消息\n\n```bash\ncurl -s https:\u002F\u002Fslack.com\u002Fapi\u002Fchat.update \\\n  -H \"Authorization: Bearer $SLACK_BOT_TOKEN\" \\\n  -H \"Content-Type: application\u002Fjson; charset=utf-8\" \\\n  --data-raw '{\"channel\":\"C01ABC123\",\"ts\":\"1775308000.100001\",\"text\":\"更新内容\",\"blocks\":[...]}'\n```\n\n### 删除消息\n\n```bash\ncurl -s https:\u002F\u002Fslack.com\u002Fapi\u002Fchat.delete \\\n  -d \"channel=C01ABC123\" -d \"ts=1775308000.100001\" \\\n  -H \"Authorization: Bearer $SLACK_BOT_TOKEN\"\n```\n\n### 定时发送\n\n```bash\nPOST_AT=$(( $(date +%s) + 1800 ))   # 30 分钟后\ncurl -s https:\u002F\u002Fslack.com\u002Fapi\u002Fchat.scheduleMessage \\\n  -d \"channel=C01ABC123\" -d \"text=定时消息\" -d \"post_at=$POST_AT\" \\\n  -H \"Authorization: Bearer $SLACK_BOT_TOKEN\"\n# 查待发队列：chat.scheduledMessages.list\n# 取消：chat.deleteScheduledMessage -d \"scheduled_message_id=Q12345\"\n```\n\n### 取消息永久链接（ts → URL）\n\n```bash\ncurl -s https:\u002F\u002Fslack.com\u002Fapi\u002Fchat.getPermalink \\\n  -d \"channel=C01ABC123\" \\\n  -d \"message_ts=1775308000.100001\" \\\n  -H \"Authorization: Bearer $SLACK_BOT_TOKEN\"\n# 返回 {\"ok\":true,\"permalink\":\"https:\u002F\u002Fworkspace.slack.com\u002Farchives\u002FC01ABC\u002Fp...\"}\n```\n\n---\n\n## 添加 Reaction\n\n```bash\ncurl -s https:\u002F\u002Fslack.com\u002Fapi\u002Freactions.add \\\n  -d \"channel=C01ABC123\" \\\n  -d \"timestamp=1775308000.100001\" \\\n  -d \"name=white_check_mark\" \\\n  -H \"Authorization: Bearer $SLACK_BOT_TOKEN\"\n```\n\n`name` = 不带冒号的 emoji slug，如 `thumbsup` \u002F `white_check_mark` \u002F `x` \u002F `eyes`。需要 `reactions:write` scope。\n\n---\n\n## 文件上传（v2 API）\n\n旧 `files.upload` 已废弃。三步走：\n\n**Step 1：申请上传 URL**\n\n```bash\ncurl -s https:\u002F\u002Fslack.com\u002Fapi\u002Ffiles.getUploadURLExternal \\\n  -d \"filename=report.pdf\" \\\n  -d \"length=$(wc -c \u003C \u002Fpath\u002Fto\u002Ffile.pdf)\" \\\n  -H \"Authorization: Bearer $SLACK_BOT_TOKEN\"\n# 返回 upload_url + file_id\n```\n\n**Step 2：上传文件内容**\n\n```bash\ncurl -s -X POST \"$UPLOAD_URL\" \\\n  -H \"Content-Type: application\u002Foctet-stream\" \\\n  --data-binary @\u002Fpath\u002Fto\u002Ffile.pdf\n```\n\n**Step 3：完成上传，关联到频道\u002Fthread**\n\n```bash\ncurl -s https:\u002F\u002Fslack.com\u002Fapi\u002Ffiles.completeUploadExternal \\\n  -H \"Authorization: Bearer $SLACK_BOT_TOKEN\" \\\n  -H \"Content-Type: application\u002Fjson; charset=utf-8\" \\\n  --data-raw '{\n    \"files\": [{\"id\":\"F08ABC123\",\"title\":\"报告\"}],\n    \"channel_id\": \"C01ABC123\",\n    \"thread_ts\": \"1775307969.013919\",\n    \"initial_comment\": \"附件请查收\"\n  }'\n```\n\n需要 `files:write` scope。\n\n---\n\n## 读取消息 \u002F Thread\n\n### Slack URL → Timestamp 转换\n\n```\nURL：https:\u002F\u002Fworkspace.slack.com\u002Farchives\u002FC01ABC\u002Fp1775307969013919\n去掉 p，倒数第 6 位插小数点 → 1775307969.013919\n```\n\n```bash\nmsg_id=\"1775307969013919\"\nts=\"${msg_id:0:$((${#msg_id}-6))}.${msg_id: -6}\"\n```\n\n```python\nimport re\ndef slack_url_to_ts(url):\n    m = re.search(r'\u002Fp(\\d+)', url)\n    s = m.group(1)\n    return f\"{s[:-6]}.{s[-6:]}\"\n```\n\n### 读 Thread\n\n```bash\ncurl -s https:\u002F\u002Fslack.com\u002Fapi\u002Fconversations.replies \\\n  -d \"channel=C01ABC123\" \\\n  -d \"ts=1775307969.013919\" \\\n  -d \"limit=50\" \\\n  -H \"Authorization: Bearer $SLACK_BOT_TOKEN\" | python3 -m json.tool\n```\n\n### 读频道历史（带时间过滤）\n\n```bash\ncurl -s https:\u002F\u002Fslack.com\u002Fapi\u002Fconversations.history \\\n  -d \"channel=C01ABC123\" \\\n  -d \"oldest=$(TZ=Asia\u002FTokyo date -v-1d +%s)\" \\\n  -d \"limit=100\" \\\n  -H \"Authorization: Bearer $SLACK_BOT_TOKEN\"\n```\n\n**超 100 条需分页**：返回中有 `response_metadata.next_cursor`，再传 `-d \"cursor=\u003Cvalue>\"` 继续拉取，直到 `has_more: false`。\n\n---\n\n## 用户 \u002F 频道查询\n\n```bash\n# token 状态自检\ncurl -s https:\u002F\u002Fslack.com\u002Fapi\u002Fauth.test -H \"Authorization: Bearer $SLACK_BOT_TOKEN\" | python3 -m json.tool\n\n# 用户信息\ncurl -s https:\u002F\u002Fslack.com\u002Fapi\u002Fusers.info -d \"user=U01ABC123\" -H \"Authorization: Bearer $SLACK_BOT_TOKEN\"\n\n# 频道信息\ncurl -s https:\u002F\u002Fslack.com\u002Fapi\u002Fconversations.info -d \"channel=C01ABC123\" -H \"Authorization: Bearer $SLACK_BOT_TOKEN\"\n\n# 列全量频道（带分页，需多次 cursor）\ncurl -s https:\u002F\u002Fslack.com\u002Fapi\u002Fconversations.list \\\n  -d \"limit=200\" -d \"types=public_channel,private_channel\" \\\n  -H \"Authorization: Bearer $SLACK_BOT_TOKEN\"\n```\n\n---\n\n## Block Kit 选型原则\n\n| 场景 | 用什么 | 原因 |\n|---|---|---|\n| 信息类（反思\u002F日报\u002F巡检\u002Fdigest） | top-level `blocks` | 展示稳定，无\"空壳\"风险 |\n| 需要状态色条（告警\u002F优先级） | `attachments[].blocks` + `color` | 唯一适合用颜色条的场景 |\n| 正文 > 50 blocks | 拆成多条 thread reply | Slack 单消息 50 blocks 硬上限 |\n\n段落结构靠 `header \u002F section \u002F divider \u002F context`，不靠颜色。\n\n---\n\n## 用户反馈\"只看到首行\"时的恢复动作\n\n1. 先 `conversations.replies` 回读，确认 Slack 落地了几条、每条 `text`\u002F`blocks` 实际内容\n2. 若截断：立即拆成 2-3 条短 thread reply 补发，标注 `补发 1\u002F2` \u002F `补发 2\u002F2`\n3. 补发后再回读验证 `blocks` 字段是否存在，不要只看 `ok:true`\n\n---\n\n## Gotchas\n\n- **`source ~\u002FOrb\u002F.env` 炸 bash**：用 grep + cut 单独提取变量，见上方 Token 提取\n- **form-encoded + `attachments[].blocks` 静默丢失**：改 `Content-Type: application\u002Fjson` + top-level `blocks`\n- **attachment-only reply 显示空壳**：`text` 传空格 + 内容全在 `attachments[].blocks` → 某些 Slack 视图渲染为空；改为 top-level `blocks` + 真实 `text` fallback\n- **blocks > 50 → 降级为首行**：adapter 若有 `if blocks.length > 50: 只发 text fallback` 的逻辑会静默丢 blocks；改为拆多条\n- **button `value` 超长 → `invalid_blocks`**：超 ~2000 chars 报错；改为 `value=\"file:\u003Cid>.json\"`，payload 存本地文件\n- **`invalid_arguments`**：别用 JSON body 调用不支持 JSON body 的接口；用 `-d \"param=value\"` form 格式\n- **`ok:true` 不代表内容到位**：发完必须 `conversations.replies` 回读验证 `blocks`\u002F`text` 是否真有内容\n- **`reactions.add` 缺 scope**：返回 `missing_scope reactions:write`，需在 Slack App 配置里加\n- **文件上传旧 API 废弃**：`files.upload` 已弃用；用 `getUploadURLExternal` → upload → `completeUploadExternal` 三步走\n- **`reply_broadcast`**：默认不传；只有需要 reply 同时广播到频道时间线时才传 `true`\n","# Slack Web API curl 参考手册\n\n## When to Use\n\n- 查具体 curl 命令参数（channel、ts、blocks 字段格式）\n- Slack URL → timestamp 转换\n- 排查 `invalid_blocks` \u002F `not_in_channel` \u002F `missing_scope` \u002F 消息只剩首行\n- 需要 `reactions.add` \u002F 文件上传 \u002F `chat.getPermalink` 的完整示例\n\n## Token 提取（必用）\n\n```bash\nSLACK_BOT_TOKEN=$(grep -E '^SLACK_BOT_TOKEN=' ~\u002FOrb\u002F.env | head -1 | cut -d= -f2- | tr -d \"'\" '\"')\n```\n\n**禁止** `source ~\u002FOrb\u002F.env`——第 26 行 `SLACK_HOME_CHANNEL_NAME=Karry Slack DM` 未加引号，bash 会把 `Slack DM` 当命令执行 → `bash: Slack: command not found`。\n\n必需 Bot Scopes：`channels:history` · `channels:read` · `groups:history` · `chat:write` · `chat:write.public` · `users:read` · `files:write` · `reactions:write`\n\n---\n\n## 发送消息\n\n### 发文本 \u002F Thread Reply\n\n始终用 `Content-Type: application\u002Fjson`——form-encoded 传 `attachments[].blocks` 会被 Slack **静默丢弃**。\n\n```bash\ncurl -s https:\u002F\u002Fslack.com\u002Fapi\u002Fchat.postMessage \\\n  -H \"Authorization: Bearer $SLACK_BOT_TOKEN\" \\\n  -H \"Content-Type: application\u002Fjson; charset=utf-8\" \\\n  --data-raw '{\n    \"channel\": \"C01ABC123\",\n    \"thread_ts\": \"1775307969.013919\",\n    \"text\": \"fallback 摘要（不要传空格）\",\n    \"blocks\": [{\"type\":\"section\",\"text\":{\"type\":\"mrkdwn\",\"text\":\"*详情*\"}}],\n    \"unfurl_links\": false,\n    \"unfurl_media\": false\n  }'\n```\n\n`thread_ts` 省略 = 发主消息，带上 = 发 thread reply。\n\n### 更新消息\n\n```bash\ncurl -s https:\u002F\u002Fslack.com\u002Fapi\u002Fchat.update \\\n  -H \"Authorization: Bearer $SLACK_BOT_TOKEN\" \\\n  -H \"Content-Type: application\u002Fjson; charset=utf-8\" \\\n  --data-raw '{\"channel\":\"C01ABC123\",\"ts\":\"1775308000.100001\",\"text\":\"更新内容\",\"blocks\":[...]}'\n```\n\n### 删除消息\n\n```bash\ncurl -s https:\u002F\u002Fslack.com\u002Fapi\u002Fchat.delete \\\n  -d \"channel=C01ABC123\" -d \"ts=1775308000.100001\" \\\n  -H \"Authorization: Bearer $SLACK_BOT_TOKEN\"\n```\n\n### 定时发送\n\n```bash\nPOST_AT=$(( $(date +%s) + 1800 ))   # 30 分钟后\ncurl -s https:\u002F\u002Fslack.com\u002Fapi\u002Fchat.scheduleMessage \\\n  -d \"channel=C01ABC123\" -d \"text=定时消息\" -d \"post_at=$POST_AT\" \\\n  -H \"Authorization: Bearer $SLACK_BOT_TOKEN\"\n# 查待发队列：chat.scheduledMessages.list\n# 取消：chat.deleteScheduledMessage -d \"scheduled_message_id=Q12345\"\n```\n\n### 取消息永久链接（ts → URL）\n\n```bash\ncurl -s https:\u002F\u002Fslack.com\u002Fapi\u002Fchat.getPermalink \\\n  -d \"channel=C01ABC123\" \\\n  -d \"message_ts=1775308000.100001\" \\\n  -H \"Authorization: Bearer $SLACK_BOT_TOKEN\"\n# 返回 {\"ok\":true,\"permalink\":\"https:\u002F\u002Fworkspace.slack.com\u002Farchives\u002FC01ABC\u002Fp...\"}\n```\n\n---\n\n## 添加 Reaction\n\n```bash\ncurl -s https:\u002F\u002Fslack.com\u002Fapi\u002Freactions.add \\\n  -d \"channel=C01ABC123\" \\\n  -d \"timestamp=1775308000.100001\" \\\n  -d \"name=white_check_mark\" \\\n  -H \"Authorization: Bearer $SLACK_BOT_TOKEN\"\n```\n\n`name` = 不带冒号的 emoji slug，如 `thumbsup` \u002F `white_check_mark` \u002F `x` \u002F `eyes`。需要 `reactions:write` scope。\n\n---\n\n## 文件上传（v2 API）\n\n旧 `files.upload` 已废弃。三步走：\n\n**Step 1：申请上传 URL**\n\n```bash\ncurl -s https:\u002F\u002Fslack.com\u002Fapi\u002Ffiles.getUploadURLExternal \\\n  -d \"filename=report.pdf\" \\\n  -d \"length=$(wc -c \u003C \u002Fpath\u002Fto\u002Ffile.pdf)\" \\\n  -H \"Authorization: Bearer $SLACK_BOT_TOKEN\"\n# 返回 upload_url + file_id\n```\n\n**Step 2：上传文件内容**\n\n```bash\ncurl -s -X POST \"$UPLOAD_URL\" \\\n  -H \"Content-Type: application\u002Foctet-stream\" \\\n  --data-binary @\u002Fpath\u002Fto\u002Ffile.pdf\n```\n\n**Step 3：完成上传，关联到频道\u002Fthread**\n\n```bash\ncurl -s https:\u002F\u002Fslack.com\u002Fapi\u002Ffiles.completeUploadExternal \\\n  -H \"Authorization: Bearer $SLACK_BOT_TOKEN\" \\\n  -H \"Content-Type: application\u002Fjson; charset=utf-8\" \\\n  --data-raw '{\n    \"files\": [{\"id\":\"F08ABC123\",\"title\":\"报告\"}],\n    \"channel_id\": \"C01ABC123\",\n    \"thread_ts\": \"1775307969.013919\",\n    \"initial_comment\": \"附件请查收\"\n  }'\n```\n\n需要 `files:write` scope。\n\n---\n\n## 读取消息 \u002F Thread\n\n### Slack URL → Timestamp 转换\n\n```\nURL：https:\u002F\u002Fworkspace.slack.com\u002Farchives\u002FC01ABC\u002Fp1775307969013919\n去掉 p，倒数第 6 位插小数点 → 1775307969.013919\n```\n\n```bash\nmsg_id=\"1775307969013919\"\nts=\"${msg_id:0:$((${#msg_id}-6))}.${msg_id: -6}\"\n```\n\n```python\nimport re\ndef slack_url_to_ts(url):\n    m = re.search(r'\u002Fp(\\d+)', url)\n    s = m.group(1)\n    return f\"{s[:-6]}.{s[-6:]}\"\n```\n\n### 读 Thread\n\n```bash\ncurl -s https:\u002F\u002Fslack.com\u002Fapi\u002Fconversations.replies \\\n  -d \"channel=C01ABC123\" \\\n  -d \"ts=1775307969.013919\" \\\n  -d \"limit=50\" \\\n  -H \"Authorization: Bearer $SLACK_BOT_TOKEN\" | python3 -m json.tool\n```\n\n### 读频道历史（带时间过滤）\n\n```bash\ncurl -s https:\u002F\u002Fslack.com\u002Fapi\u002Fconversations.history \\\n  -d \"channel=C01ABC123\" \\\n  -d \"oldest=$(TZ=Asia\u002FTokyo date -v-1d +%s)\" \\\n  -d \"limit=100\" \\\n  -H \"Authorization: Bearer $SLACK_BOT_TOKEN\"\n```\n\n**超 100 条需分页**：返回中有 `response_metadata.next_cursor`，再传 `-d \"cursor=\u003Cvalue>\"` 继续拉取，直到 `has_more: false`。\n\n---\n\n## 用户 \u002F 频道查询\n\n```bash\n# token 状态自检\ncurl -s https:\u002F\u002Fslack.com\u002Fapi\u002Fauth.test -H \"Authorization: Bearer $SLACK_BOT_TOKEN\" | python3 -m json.tool\n\n# 用户信息\ncurl -s https:\u002F\u002Fslack.com\u002Fapi\u002Fusers.info -d \"user=U01ABC123\" -H \"Authorization: Bearer $SLACK_BOT_TOKEN\"\n\n# 频道信息\ncurl -s https:\u002F\u002Fslack.com\u002Fapi\u002Fconversations.info -d \"channel=C01ABC123\" -H \"Authorization: Bearer $SLACK_BOT_TOKEN\"\n\n# 列全量频道（带分页，需多次 cursor）\ncurl -s https:\u002F\u002Fslack.com\u002Fapi\u002Fconversations.list \\\n  -d \"limit=200\" -d \"types=public_channel,private_channel\" \\\n  -H \"Authorization: Bearer $SLACK_BOT_TOKEN\"\n```\n\n---\n\n## Block Kit 选型原则\n\n| 场景 | 用什么 | 原因 |\n|---|---|---|\n| 信息类（反思\u002F日报\u002F巡检\u002Fdigest） | top-level `blocks` | 展示稳定，无\"空壳\"风险 |\n| 需要状态色条（告警\u002F优先级） | `attachments[].blocks` + `color` | 唯一适合用颜色条的场景 |\n| 正文 > 50 blocks | 拆成多条 thread reply | Slack 单消息 50 blocks 硬上限 |\n\n段落结构靠 `header \u002F section \u002F divider \u002F context`，不靠颜色。\n\n---\n\n## 用户反馈\"只看到首行\"时的恢复动作\n\n1. 先 `conversations.replies` 回读，确认 Slack 落地了几条、每条 `text`\u002F`blocks` 实际内容\n2. 若截断：立即拆成 2-3 条短 thread reply 补发，标注 `补发 1\u002F2` \u002F `补发 2\u002F2`\n3. 补发后再回读验证 `blocks` 字段是否存在，不要只看 `ok:true`\n\n---\n\n## Gotchas\n\n- **`source ~\u002FOrb\u002F.env` 炸 bash**：用 grep + cut 单独提取变量，见上方 Token 提取\n- **form-encoded + `attachments[].blocks` 静默丢失**：改 `Content-Type: application\u002Fjson` + top-level `blocks`\n- **attachment-only reply 显示空壳**：`text` 传空格 + 内容全在 `attachments[].blocks` → 某些 Slack 视图渲染为空；改为 top-level `blocks` + 真实 `text` fallback\n- **blocks > 50 → 降级为首行**：adapter 若有 `if blocks.length > 50: 只发 text fallback` 的逻辑会静默丢 blocks；改为拆多条\n- **button `value` 超长 → `invalid_blocks`**：超 ~2000 chars 报错；改为 `value=\"file:\u003Cid>.json\"`，payload 存本地文件\n- **`invalid_arguments`**：别用 JSON body 调用不支持 JSON body 的接口；用 `-d \"param=value\"` form 格式\n- **`ok:true` 不代表内容到位**：发完必须 `conversations.replies` 回读验证 `blocks`\u002F`text` 是否真有内容\n- **`reactions.add` 缺 scope**：返回 `missing_scope reactions:write`，需在 Slack App 配置里加\n- **文件上传旧 API 废弃**：`files.upload` 已弃用；用 `getUploadURLExternal` → upload → `completeUploadExternal` 三步走\n- **`reply_broadcast`**：默认不传；只有需要 reply 同时广播到频道时间线时才传 `true`\n",{"name":5,"description":7},"main","cb33813b8990e4602b7c2d501659f77ebba5999f","profiles\u002F.claude\u002Fskills\u002Fslack-cli-api-reference",8,"https:\u002F\u002Fgithub.com\u002FKarryViber\u002FOrb","https:\u002F\u002Fgithub.com\u002FKarryViber","2026-05-14 18:44:03",{"source":8,"skillName":5,"commands":65,"prompt":75,"zipAvailable":76},[66,69,72],{"tool":67,"command":68},"npx","npx skills add KarryViber\u002FOrb --skill slack-cli-api-reference",{"tool":70,"command":71},"bunx","bunx skills add KarryViber\u002FOrb --skill slack-cli-api-reference",{"tool":73,"command":74},"pnpm","pnpm dlx skills add KarryViber\u002FOrb --skill slack-cli-api-reference","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002FKarryViber\u002FOrb\u002Fblob\u002Fmain\u002Fprofiles\u002F.claude\u002Fskills\u002Fslack-cli-api-reference\u002FSKILL.md",true,[],[79,110,124,139,158,170],{"skillNo":80,"name":81,"nameZh":6,"description":82,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":83,"licenseFileUrl":84,"sourceHtmlUrl":85,"categories":86,"keywords":93,"publishedAt":52},"01M70G0637CFCHAY3DYTMYS07K","webapp-testing","Toolkit for interacting with and testing local web applications using Playwright. Supports verifying frontend functionality, debugging UI behavior, capturing browser screenshots, and viewing browser logs.","Apache-2.0","https:\u002F\u002Fgithub.com\u002FKarryViber\u002FOrb\u002Fblob\u002Fmain\u002Fprofiles\u002F.claude\u002Fskills\u002Fwebapp-testing\u002FLICENSE.txt","https:\u002F\u002Fgithub.com\u002FKarryViber\u002FOrb\u002Fblob\u002Fmain\u002Fprofiles\u002F.claude\u002Fskills\u002Fwebapp-testing\u002FSKILL.md",[87,90],{"categoryNo":88,"categoryName":89,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000008","测试与质量",{"categoryNo":91,"categoryName":92,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000009","前端开发",[94,95,96,97,98,99,100,39,101,102,103,104,105,106,107,108,109],"webapp","testing","webapp testing","playwright","screenshots","ui","behavior","for","with","browser","logs","toolkit","debugging","frontend","local","applications",{"skillNo":111,"name":112,"nameZh":6,"description":113,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":114,"categories":115,"keywords":116,"publishedAt":52},"01M70FZXCJ5AHJ3JW2Q12F04TA","vendor-doc-actionability","对外合作文档（交付文档 \u002F POC 文档 \u002F Solution Doc \u002F 提案书）必须为每个「需对方执行」的动作写清具体操作入口（URL \u002F 工单系统 \u002F 脚本路径 \u002F 联系人 + 联系方式 \u002F 步骤编号）。Use when 给客户、vendor、合作方写交付文档、POC 文档、Solution Doc、提案书；或检视已有对外文档是否抽象到无法执行。","https:\u002F\u002Fgithub.com\u002FKarryViber\u002FOrb\u002Fblob\u002Fmain\u002Fprofiles\u002F.claude\u002Fskills\u002Fvendor-doc-actionability\u002FSKILL.md",[],[117,118,119,120,121,45,122,43,42,123],"vendor","doc","vendor doc actionability","poc","文档","提案","user",{"skillNo":125,"name":126,"nameZh":6,"description":127,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":128,"categories":129,"keywords":132,"publishedAt":52},"01M70FZARY5P7VRJKVFATTCVX9","vendor-api-param-validation","第三方 API \u002F SDK 集成开工前，强制先列参数 checklist 并对照官方文档逐项验证（名称 \u002F 类型 \u002F 必填 \u002F 默认 \u002F 上限），通过后再编码——不是「写完再调通」。Use when 新接 vendor API\u002FSDK（Slack \u002F LongPort \u002F freee \u002F LLM API 等）、既有集成追加新 endpoint 或新字段、用户说「调通某接口」「接入 X」「集成 X」。","https:\u002F\u002Fgithub.com\u002FKarryViber\u002FOrb\u002Fblob\u002Fmain\u002Fprofiles\u002F.claude\u002Fskills\u002Fvendor-api-param-validation\u002FSKILL.md",[130,131],{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},{"categoryNo":27,"categoryName":28,"taxonomyType":29,"taxonomyTypeDesc":30},[133,134,117,33,35,135,136,121,137,45,43,123,138],"vendor api param validation","validation","sdk","llm api","checklist","endpoint",{"skillNo":140,"name":141,"nameZh":6,"description":142,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":143,"categories":144,"keywords":146,"publishedAt":52},"01M70FYW81TRN7VAS8WTN08STH","truth-ladder","状态放行三层阶梯（attempted \u002F observed \u002F confirmed）—— 汇报任务、API、命令、消息或外部动作状态时强制分层，避免把\"动作已发起\"误写成\"结果已达成\"。Use when 准备写「任务已完成」「API 返回成功」「exit code 0」「用户已收到」「ok:true」类状态汇报；或在 cron 报告 \u002F Slack 回报 \u002F project status \u002F receipt 中表达完成度时。","https:\u002F\u002Fgithub.com\u002FKarryViber\u002FOrb\u002Fblob\u002Fmain\u002Fprofiles\u002F.claude\u002Fskills\u002Ftruth-ladder\u002FSKILL.md",[145],{"categoryNo":27,"categoryName":28,"taxonomyType":29,"taxonomyTypeDesc":30},[147,148,149,33,150,43,45,151,152,153,154,155,156,35,157],"ladder","truth ladder","ok","code","exit","true","status","报告","cron","project","project status",{"skillNo":159,"name":160,"nameZh":6,"description":161,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":162,"categories":163,"keywords":164,"publishedAt":52},"01M70FYTESF5WQYBVRX8BXYJQF","thread-object-realignment","长 thread 切题后的对象重定协议——thread 历史 ≥5 条且检测到切题信号时，回复前必做「用户最后显式问题对象 vs 待发回复对象」一致性校验，不一致则改写或反问。Use when Slack thread 历史 ≥5 条且当前用户消息出现切题信号（主题词突变、问句指向新实体、时间线跳跃、出现「另外」「话说」「回到 X」「换个话题」等切题语，或 ≥3 turn 后用户显式问题对象与最近 assistant 回复对象不同）。","https:\u002F\u002Fgithub.com\u002FKarryViber\u002FOrb\u002Fblob\u002Fmain\u002Fprofiles\u002F.claude\u002Fskills\u002Fthread-object-realignment\u002FSKILL.md",[],[165,44,166,35,167,123,168,43,169,45],"object","thread object realignment","校验","slack thread","assistant",{"skillNo":171,"name":172,"nameZh":6,"description":173,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":83,"licenseFileUrl":174,"sourceHtmlUrl":175,"categories":176,"keywords":180,"publishedAt":52},"01M70FYFC1Y2J16FJFEFQ5WYRE","theme-factory","Toolkit for styling artifacts with a theme. These artifacts can be slides, docs, reportings, HTML landing pages, etc. There are 10 pre-set themes with colors\u002Ffonts that you can apply to any artifact that has been creating, or can generate a new theme on-the-fly.","https:\u002F\u002Fgithub.com\u002FKarryViber\u002FOrb\u002Fblob\u002Fmain\u002Fprofiles\u002F.claude\u002Fskills\u002Ftheme-factory\u002FLICENSE.txt","https:\u002F\u002Fgithub.com\u002FKarryViber\u002FOrb\u002Fblob\u002Fmain\u002Fprofiles\u002F.claude\u002Fskills\u002Ftheme-factory\u002FSKILL.md",[177],{"categoryNo":178,"categoryName":179,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000015","视觉设计",[181,182,183,184,185,186,187,188,102,189,190,105,191,192,193,194,195,101,196,197],"theme factory","factory","theme","apply","styling","fly","generate","artifact","fonts","can","artifacts","you","themes","pages","landing","slides","SET"]