@crvouga/mockingbird-service-slack

中文文档
3.11.0发布于 2026/11/11MITTypeScriptES Module构建来源已验证近 30 天下载 1.6万

Slack来袭的webhooks,Web API,和Socket Mode控制平面的状态仿真器,每发送一个提示的发件箱.

中文使用文档
文档目录7 节
  1. 安装
  2. 使用量
  3. 路线
  4. 管理员(超过标准合同)
  5. 命名空间
  6. 故意不模拟
  7. API 密码

@crvouga/mockingbird-service-slack (英语)

本地模拟器。 真正的API合同. 部分 嘲笑鸟。 。 。 .

状态模拟器 偷懒 测试套件: 接通的webhooks, Web API 使用我们的应用程序 和 Socket 模式控制平面 Bolt 需要启动,带有 发件箱 联 合 国 一切的应用"同意"。 一个套房声称,一个警报响起 (单位:千美元)GET /__admin/outbox?webhook=… 或者说 ?channel=…没有真正的工作空间,并驱动 重试路径( 429 为) retry-after, 5xx)和终端设备(no_text, (中文(简体) ), no_service, (中文(简体) ), channel_not_found) 有命名预设.

  • 行动范围: 支助
  • Slack没有为这些方法发布维护的OpenAPI:合同(openapi.yaml)为 手写自Slack记录的线形 和我们的消费者.

安装

npm install -D @crvouga/mockingbird-service-slack

仅限无害环境管理。 节点 22或 Bun 1.2. 无土生属地. 给它服务 npx mockingbird-slack serve, (中文(简体) ), createServer 从 ./server (节点),或 createRuntime 与 任何获取服务器.

使用量

点数每 SLACK_*_WEBHOOK_URL (单位:千美元)SLACK_PIPELINE_ALERT_WEBHOOK_URL, (中文(简体) ), SLACK_ERX_ALERTS_WEBHOOK_URL, (中文(简体) ), SLACK_BILLING_ALERT_WEBHOOK_URL, (中文(简体) ), SLACK_CRITICAL_ALERT_WEBHOOK_URL, (中文(简体) ), RECONCILER_SLACK_WEBHOOK_URL,(...)时 http://127.0.0.1:8808/services/T000/B000/<anything>。任何路径都被接受,直到您注册 钩子. 网络 API 调用硬码 https://slack.com/api/…; 指向它们 http://127.0.0.1:8808/api/… (计: @slack/web-api, (中文(简体) ), slackApiUrl: "http://127.0.0.1:8808/api/") (中文(简体) ). 套接字模式中的 Bolt 使用相同 clientOptions.slackApiUrl (复制到 SocketModeReceiver加上一个 xapp- 应用标志. apps.connections.open 返回 a ws:// 網址 有关这一进程.

npx mockingbird-slack serve --port 8808
import { IncomingWebhook } from "@slack/webhook"
import { WebClient } from "@slack/web-api"
import { createServer } from "@crvouga/mockingbird-service-slack/server"

const server = await createServer()

// The app's own Slack clients. Only the URLs they are given change.
const webhook = new IncomingWebhook(`${server.url}/services/T000/B000/XXXX`)
await webhook.send({ text: "reconcile failed", blocks: [{ type: "divider" }] }) // { text: "ok" }
const slack = new WebClient("xoxb-fixture", { slackApiUrl: `${server.url}/api/` })
await slack.chat.postMessage({ channel: "#alerts", text: "deploy finished" }) // { ok: true, ts, … }

// Test controls. Make the next post fail the way Slack does under load; our clients retry at 0/2/8 s.
server.runtime.applyPreset("rate_limited", "default", { count: 1 })

const outbox = await fetch(`${server.url}/__admin/outbox?webhook=/services/T000/B000/XXXX`)
// { messages: [{ text: "reconcile failed", blocks: [...], ts: "1700000000.000001", thread_ts: null, … }] }
await server.close()

路线

路线行为
POST /services/{T}/{B}/{X}来来来来来来来来来来来来来来来来来来来来来去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去 贾森 {text, blocks?, attachments?, thread_ts?} (或形式) payload=<json>页:1 200 ok (文本/说明). 400 invalid_payload (不是JSON的对象), 400 no_text (无文本、块或附件), 400 invalid_blocks (结构与块 Kit 限制,也在内) attachments[].blocks;见下文, 400 too_many_attachments, (中文(简体) ), 404 no_service (未注册的钩子,一旦注册任何钩子), 404 channel_not_found, (中文(简体) ), 410 channel_is_archived。 。 。 .
POST /api/chat.postMessage{channel, text?, blocks?, attachments?, thread_ts?, unfurl_links?} → {ok, channel, ts, message}。 。 。 . channel 是一个id或 #name; 除非 strictChannels。收发箱保存 text, (中文(简体) ), blocks, (中文(简体) ), unfurl_links, (中文(简体) ), thread_ts,以及 workspace (团队编号). 错误 : channel_not_found, (中文(简体) ), no_text, (中文(简体) ), invalid_blocks, (中文(简体) ), invalid_blocks_format, (中文(简体) ), msg_too_long, (中文(简体) ), is_archived。 。 。 .
POST /api/chat.update{channel, ts, text?, blocks?} → {ok, channel, ts, text, message} 与 edited· ; message_not_found, (中文(简体) ), cant_update_message (网易新闻). 封口区块被保留.
POST /api/chat.postEphemeral{channel, user, text} → {ok, message_ts}· ; user_not_found。在收发箱中录入 ephemeral: true。 。 。 .
GET|POST /api/chat.getPermalinkchannel, (中文(简体) ), message_ts → {ok, channel, permalink} (单位:千美元)https://<domain>.slack.com/archives/C…/p…(三); message_not_found。 。 。 .
POST /api/reactions.add, (中文(简体) ), /reactions.remove, (中文(简体) ), GET|POST /api/reactions.get每个消息( E)channel, (中文(简体) ), timestamp, (中文(简体) ), name(三); already_reacted, (中文(简体) ), no_reaction, (中文(简体) ), message_not_found, (中文(简体) ), no_item_specified。 。 。 . reactions.get 答题 {ok, type: "message", channel, message} 与 reactions[{name, users, count}]。 。 。 .
GET|POST /api/auth.test{ok, url, team, user, team_id, user_id, bot_id} 从工作空间设置.
POST /api/conversations.join{ok, channel};已经是成员 warning: "already_in_channel"· ; method_not_supported_for_channel_type (非公开), is_archived。 。 。 .
GET|POST /api/users.info, (中文(简体) ), /users.lookupByEmail{ok, user} 与 profile.email编号 :real_name· ; user_not_found, (中文(简体) ), users_not_found种子: U0ADA (单位:千美元)[email protected])和那个机器人.
GET|POST /api/files.info{ok, file} 与 url_private_download 打开 files.slack.com· ; file_not_found种子: F0REPORT。 。 。 .
POST /api/views.open{trigger_id, view} → {ok, view: {id: "V…", hash, state, …}}· ; invalid_arguments。 。 。 .
POST /api/apps.connections.openAuthorization: Bearer xapp-… (只有标题) {ok, url} 地点 url 实值 ws://<this host>/link/?ticket=…&app_id=…,每张票一张WebSocket;第二次升级或关闭票被拒绝. 丢失的代号 = not_authed; 机器人符号 not_allowed_token_type; 畸形 − invalid_auth; 一个符号 revokedAppTokens → token_revoked; 一个不在此命名空间中的应用符号 appTokens (当清单是非空的) invalid_auth。 。 。 .
网络安全套 /link/?ticket=升级时,一个JSON hello (单位:千美元)type, (中文(简体) ), connection_info.app_id, (中文(简体) ), num_connections, (中文(简体) ), debug_info.approximate_connection_time) (中文(简体) ). 没有推动任何事件。 客户端乒乓球被打平;服务器每2个打平. {envelope_id} 阿克被接受而不回答. disconnect 理由 warning, (中文(简体) ), refresh_requested,以及 link_disabled 匹配 Slack 的信封( 没有重新连接 URL : @slack/[email protected] 电话 apps.connections.open - 再来一次).

Web API 机构可以是 JSON 或形式编码(结构为 JSON- 以形式字段编码), 如 Slack 接受两者;读取方法也采用查询参数。 认证是 Authorization: Bearer xox… (或 a 个) token 表单字段: 缺少 {} not_authed除了一个 xoxb-编号 :xoxp-编号 :xoxa- 符号(或 一个在外面 settings.tokens页:1 invalid_auth。逻辑错误为 HTTP 200 {ok: false, error}· ; a JSON员额无 charset 成功与斯莱克 missing_charset 警告 警告他们.

管理员(超过标准合同)

路线效果
GET /__admin/outbox?webhook=<path>&channel=<id|#name>&thread_ts=&source=webhook|api&since=&limit=每一个消息,最古老的第一: text, (中文(简体) ), blocks, (中文(简体) ), attachments, (中文(简体) ), thread_ts, (中文(简体) ), ts, (中文(简体) ), channel, (中文(简体) ), webhook, (中文(简体) ), method, (中文(简体) ), ephemeral, (中文(简体) ), edited, (中文(简体) ), reactions, (中文(简体) ), unfurl_links, (中文(简体) ), workspace。 。 。 . webhook 带 /services/T/B/X, (中文(简体) ), T/B/X 或一个完整的URL. GET /__admin/outbox/:id 读取一个.
POST /__admin/hooks{path, channel?} 或者说 {hooks: [...]}: 注册webhooks(并把它们引导到一个频道). 一旦任何钩子存在,未知钩子就会回答 404 no_service。 。 。 . GET 清单, DELETE [?path=] 移除.
POST /__admin/channels, (中文(简体) ), /users, (中文(简体) ), /files种子工作空间记录{id?, name, is_private?, is_archived?, is_member?}, (中文(简体) ), {id, name?, real_name?, email?}, (中文(简体) ), {id, name?, mimetype?, size?}) (中文(简体) ). GET /__admin/channels, (中文(简体) ), /users, (中文(简体) ), /views 列出它们.
PUT /__admin/settings{teamId?, teamName?, teamDomain?, botUserId?, botId?, appId?, tokens?, appTokens?, revokedAppTokens?, socketLifetimeMs?, strictChannels?} 呼叫的命名空间. socketLifetimeMs 关闭打开的 Socket 模式连接 reason: "warning"。 。 。 .
GET /__admin/socket/connections打开并关闭调用命名空间的 Socket 模式套接字 : namespace, (中文(简体) ), appId, (中文(简体) ), ticket, (中文(简体) ), connectedAt, (中文(简体) ), state, (中文(简体) ), reconnectCount永远不给任何标志.
POST /__admin/socket/disconnect{reason?: "warning"|"refresh_requested"|"link_disabled", code?: 1000}。发送Slack的 disconnect 信封,然后关闭. code: 1006 放弃 TCP 连接.

错误预设( E)POST /__admin/faults {"preset": "<name>", "count"?: n, "params"?: {...}}:

预设效果
rate_limited网络呼号 429 rate_limited,网络 API 429 {ok: false, error: "ratelimited"},两者 retry-after (单位:千美元)params.retryAfter,默认值 1 s).
5xx500 internal_error 各地(params.status: 503 给 service_unavailable) (中文(简体) ).
service_unavailable503 service_unavailable 到处都是.
channel_not_found网络呼号 404 channel_not_found; Web API 频道方法 {ok: false, error: "channel_not_found"}。 。 。 .
no_service网络呼号 404 no_service (被吊销的钩子).
invalid_auth网络 API {ok: false, error: "invalid_auth"} (被撤销的令牌).
connections_open_invalid_authapps.connections.open 答题 {ok:false, error:"invalid_auth"} 和薄荷没有票.
connections_open_429apps.connections.open 答题 429 {ok:false, error:"ratelimited"} 与 retry-after (单位:千美元)params.retryAfter,默认值 1.
connections_open_5xxapps.connections.open 答题 500 internal_error (单位:千美元)params.status: 503 给 service_unavailable) (中文(简体) ).
socket_close_after_hello下一个套接字模式套接字发送 hello,然后是正常的关闭.
socket_abnormal_close下一个套接字模式套接字发送 hello,然后放弃连接(代码1006).
socket_hello_latency延迟 hello 以 params.latencyMs 毫秒长. HTTP 响应本身没有被延迟.

命名空间

x-mockingbird-namespace页:1 /__admin/ns/<name> 在 Webhook URL 或 API 基础上,或由 证书 : PUT /__admin/credentials {"credentials": {"xoxb-worker-a": "a", "T000/B000/XXXX": "b"}} 绘制一个bot 令牌或 webhook 的 T/B/X 用于命名空间的路径.

故意不模拟

  • 入境事件 API和交互提供. 套接字模式的连接寿命周期是 模拟(apps.connections.open, (中文(简体) ), hello乒乓球 乒乓球, disconnect所以博尔特可以启动和 关闭; 模拟器不会在连接上推动事件 。 A 类 disconnect 信封没有 重新连接 URL, 匹配 Slack 的文件形状和 @slack/[email protected],哪个 电话 apps.connections.open 再来一次.
  • 文件上传和下载 : files.info 答案种子元数据 files.slack.com URL( URL) 未送达.
  • 实际按方法计算的费率限制等级:429次只来自 rate_limited 预设.
  • 公布的会员规则not_in_channel, (中文(简体) ), chat:write.public 范围,以及 触发编号过期 views.open。 。 。 .
  • 信件格式化( mrkdwn 解析、 链接解析、 提及解析): 文本和块是 储存的逐字记录.
  • 块 Kit 的限制是 a 最好猜,不是甲骨文验证 (从每个区块的页面) docs.slack.dev; 每项规则的确切状态和消息Slack返回从未被观察到 现场直播). blocks 和每个 attachments[].blocks 以 invalid_blocks (网页: 400 invalid_blocks· ; chat.postMessage, (中文(简体) ), chat.update, (中文(简体) ), chat.postEphemeral数字 : 200 {ok: false, error: "invalid_blocks", response_metadata: {messages}},消息是模拟者自己的措辞) 当: 有超过50个块( 在每个阵列中; Slack 是否应用了 50 个内部附件 ) 未经证实) type 不是块 Kit 类型; a section text 超过3000 字符或该字符 fields 每个超过10件或2000个字符;a header text 没有 plain_text 或超过150个字符; context 超过10个 elements 或者说 actions 25岁以上;a block_id 超过 255 个字符;文本对象为空。 完全限值被接受 并且已逐字存储,被否决的消息则不保存任何信息(更新后留下原件) 然无所动. 必要领域规则(a) section 没有 text 也没有 fields,一个 image 无 alt_text),内部元素级验证 actions 编号 : context 编号 : input 编号 : rich_text, (中文(简体) ), 其它附件字段没有建模.

API 密码

导出仁爱说明
SlackAPI类进程模拟器 : fetch(request), (中文(简体) ), reset(), (中文(简体) ), messages(), (中文(简体) ), state选项: sqlite, (中文(简体) ), now, (中文(简体) ), namespace, (中文(简体) ), settings。 。 。 .
createRuntime函数全面服务合同的仿真器(保健、管理、发包箱、命名空间、证书、预设)。 选项 : settings, (中文(简体) ), clock, (中文(简体) ), seed, (中文(简体) ), adminKey, (中文(简体) ), onLog, (中文(简体) ), sqlite。 。 。 .
SLACK_PRESETS对象每个命名的断层预设.
SLACK_NAMESPACE字符串服务名称, "slack"。 。 。 .
slackCredential函数无记名符号,或者网钩 T/B/X 路径(如何将证书映射到命名空间).
DEFAULT_SETTINGS, (中文(简体) ), DEFAULT_CHANNELS, (中文(简体) ), DEFAULT_USERS, (中文(简体) ), DEFAULT_FILES数值种子工作空间.
document, (中文(简体) ), operationIds, (中文(简体) ), supportedOperationIds数值销售商为OpenAPI合同及其业务代号.
createServer, (中文(简体) ), serveTarget, (中文(简体) ), DEFAULT_PORT (单位:千美元)./server(中文(简体) )节点服务过来 node:http; 数据 serve CLI目标; 第8808口.

部分 嘲笑鸟。 。 。 .

版本与发布记录

@crvouga/mockingbird-service-slack 共发布 39 个版本,首次发布于 2026/09/23;过去 12 个月发布了 39 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
3.11.0latest2026/11/11今天
3.10.62026/11/038 天前
3.10.52026/11/038 天前
3.10.42026/11/038 天前
3.10.32026/11/038 天前
3.10.22026/11/038 天前

关于 @crvouga/mockingbird-service-slack 的常见问题

@crvouga/mockingbird-service-slack 是什么?

Slack来袭的webhooks,Web API,和Socket Mode控制平面的状态仿真器,每发送一个提示的发件箱.

如何安装 @crvouga/mockingbird-service-slack?

在项目目录运行 npm install @crvouga/mockingbird-service-slack,或使用 pnpm add / yarn add / bun add。它还提供命令行工具 mockingbird-slack,可以用 npx mockingbird-slack 直接运行。

@crvouga/mockingbird-service-slack 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@crvouga/mockingbird-service-slack 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@crvouga/mockingbird-service-slack 可以商用吗?

@crvouga/mockingbird-service-slack 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@crvouga/mockingbird-service-slack 的下载量有多少?

根据 npm 官方下载统计,@crvouga/mockingbird-service-slack 在 2026/10/11 – 2026/11/09 这 30 天内被下载 15,543 次,日均约 518 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@crvouga/mockingbird-service-slack 还在维护吗?

最新版本 3.11.0 发布于 2026/11/11(今天);至今共发布 39 个版本,其中过去 12 个月发布了 39 个;首次发布于 2026/09/23。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。