mcpField
D
deploy-slack-app

deploy-slack-app

github.com/slackapi云与 DevOps161114 次安装2 天前更新
代码仓库

关于 deploy-slack-app

deploy-slack-app 是面向已在本地运行的 Slack 应用的部署技能,帮助开发者将其作为独立应用部署到 Railway 或 Heroku,并持续运行。它通过 Slack CLI 部署钩子传递应用令牌,并保留本地开发应用。

主要功能

  1. 01通过 Slack CLI 部署钩子运行脚本
  2. 02支持 Railway 和 Heroku 部署
  3. 03部署前检查 Socket Mode 和运行环境
  4. 04分别保留本地与部署版 Slack 应用
  5. 05提供部署后服务和 Slack 行为验证步骤

适用场景

  1. 01将已在本地验证的 Slack 应用部署为持续运行的服务
  2. 02为 Socket Mode 应用配置 Railway 或 Heroku
  3. 03在部署后确认应用可在 Slack 中响应

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/slackapi/slack-skills-plugin --skill deploy-slack-app

安装后在 Claude Code 中输入/deploy-slack-app确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
deploy-heroku.sh
deploy-railway.sh
heroku.md
railway.md

详细介绍

部署 Slack 应用

将一个已能在本地正常运行的 Slack 应用部署到托管服务商,作为一个独立的 Slack 应用运行,拥有自己的应用 ID,并且无需依赖开发者的机器即可持续运行。本地开发应用保持不变;步骤 5:部署会说明两个应用如何共存。这是 slack:test-slack-app 技能确认应用能够响应之后的下一步。

实现机制是 Slack CLI 的 deploy hook。在项目的 .slack/hooks.json 中添加 deploy 键,即可用你选择的脚本替代 Slack 自带的托管部署;CLI 会在创建并安装部署后的应用后运行该脚本。这个执行顺序正是这种方法值得采用的关键:脚本运行时,应用的 bot 令牌和应用级令牌已经在其环境中,因此这里无需提示输入或存储任何密钥。

支持以下两家服务商,均以长期运行的工作进程形式运行应用:

服务商进程类型部署来源密钥当前价格
Railway服务,无需绑定端口工作目录通过标准输入传递https://railway.com/pricing
Herokuworker dyno已提交代码的 git push作为参数传递https://www.heroku.com/pricing

Railway 是更好的默认选择,原因见步骤 2a:选择服务商。


步骤 1:检查前提条件

1a. 检测 Slack CLI

使用 slack:slack-cli 技能(步骤 1:检测 Slack CLI)检查是否已安装公开版 Slack CLI,并确定其命令名称。指纹检查、别名回退和安装说明都在该技能中;不要重复说明。下文统一将解析出的命令称为 SLACK_CMD。

这点比看起来更重要。有些机器的路径中存在一个无关的内部工具,也名为 slack;运行它会导致部署进行到较后阶段时才出现令人困惑的故障。

1b. 确认应用使用 Socket Mode

读取应用的清单,而不是询问。 项目已经声明了所用模式,因此此处提问是多余的。检查 manifest.json 中的 settings.socket_mode_enabled。如果 .slack/config.json 将清单来源设为 remote,则本地没有清单文件,请改用 SLACK_CMD manifest info 读取。

  • **已启用 Socket Mode:**继续。应用会向 Slack 发起出站 websocket 连接,无需公开 URL,也不会绑定 HTTP 端口。
  • **已禁用 Socket Mode,或应用使用 Request URL:**请在此处停止。 此技能目前不支持 Request URL 应用,因为托管的 Request URL 应用还需要在部署后获取一个公开地址,并将其写回应用清单。请明确告知开发者这是目前的缺口,以及当前支持的做法是将应用转换为 Socket Mode。较新版本的 Slack Skills Plugin 可能已提供相关支持,因此请开发者更新插件后重试。如果开发者已使用最新版本,请引导其前往 https://github.com/slackapi/slack-skills-plugin/issues/172 添加表情回应或评论。

如果清单内容不明确,请读取应用的入口文件。使用 socketMode: true 和 appToken 构建的 Bolt for JavaScript 应用,或通过 SocketModeHandler 启动的 Bolt for Python 应用,均属于 Socket Mode 应用。

1c. 确认运行环境受支持

此流程已在 macOS 和 Linux 上验证。部署 hook 是 shell 脚本,因此 Windows 开发者需要使用目前尚不存在的 PowerShell 等效脚本。在 Windows 上,请直接说明这一点,不要让部署运行到一半才失败。目前可使用 WSL 作为替代方案。较新版本的 Slack Skills Plugin 可能已提供相关支持,因此请开发者更新插件后重试。如果开发者已使用最新版本,请引导其前往 https://github.com/slackapi/slack-skills-plugin/issues/171 添加表情回应或评论。


步骤 2:选择提供商和团队

向开发者询问两个项目本身无法确定的问题:要部署到哪个提供商,以及要部署到哪个 Slack 团队。

2a. 选择提供商

询问要使用哪个提供商,因为成本是开发者无法从项目中推断出来的。把上表中的两个定价链接都提供给开发者,以便他们查看当前条款。**不要获取这些页面,也不要引用价格、套餐名称或试用条款。**提供商经常会调整这些内容,而且这项技能可能在编写很久之后才会安装。

价格列表会变化,但以下情况不会变化,值得说明:

  • Railway 是默认推荐选项。它接受通过标准输入传递的密钥,因此令牌不会出现在进程参数中。它会部署工作目录,因此重新部署无需提交,也不需要 Procfile。
  • Heroku 适合已经拥有账号的开发者,或团队标准指定使用 Heroku 的情况。它从 git 构建,因此只会部署已提交的代码。有些账号(包括由企业管理的账号)无法拥有个人应用,必须在 Heroku 团队中创建应用。个人应用和团队应用可能使用不同的套餐和计费方式,因此应询问要使用哪个团队,不要自行选择:共享团队使用共享预算。

明确说明:这两个提供商都会让应用持续运行,这是 Socket Mode 应用的要求。始终在线托管最终是一项付费服务,因此任何试用期结束后都要预期会产生费用。

开发者选定提供商后,阅读该提供商的参考文件并按其说明操作:references/railway.md 或 references/heroku.md。每个文件都包含安装和身份验证命令、提供商对项目的具体要求,以及其部署脚本读取的环境变量。步骤 4:接入部署钩子会逐项处理这些内容。

2b. 选择团队

运行 SLACK_CMD auth list。如果只列出一个团队,就使用该团队。如果列出多个团队,则向开发者展示每个团队的名称和 ID,并询问要部署到哪个团队。

**绝不要自行选择团队。**不要假定要使用独立工作区或 Enterprise 组织,也不要复用 .slack/apps.dev.json 中的团队,因为它通常是开发者的沙盒环境。猜错会把应用安装到开发者无意选择的团队中,而之后部署到正确团队时会创建第二个 Slack 应用。


步骤 3:先在本地确认应用可运行

**不要部署尚未确认能正常运行的应用。**在提供商的日志中,故障部署和故障应用看起来完全相同,之后再区分两者的成本远高于事先检查。

使用 slack:test-slack-app 技能,通过 SLACK_CMD run 运行应用,并测试至少一个实际功能界面,以便在部署后有一个已知正常的行为可供复查。记下使用了哪个功能界面:步骤 6:验证部署会使用同一个界面进行检查。


步骤 4:接入部署钩子

需要设置三项内容。写入前先检查每项是否已存在,因为重新部署应用是最常见的情况,而覆盖开发者编辑过的脚本后无法恢复。

4a. 准备提供商

先按照所选提供商的参考文件完成准备,再编写任何内容,因为部署脚本只会检查这些项目,然后就会停止;它无法替你修复问题。

  • **安装并验证提供商的 CLI。**运行其 whoami 检查。登录会打开浏览器,因此如果检查失败,应让开发者在自己的终端中运行登录命令,而不是由你代为运行。
  • 与开发者确定名称和归属。对于 Heroku:确定一个有辨识度的应用名称,以及应用是否属于某个团队(heroku teams)。对于 Railway:如果账号下有多个工作区,则确定要使用哪个工作区。这些信息将成为步骤 5:部署中部署命令的环境变量。
  • **满足提供商的项目要求。**对于 Heroku,编写 Procfile 并提交。对于 Railway,确认它会检测到的启动命令。
4b. 编写部署脚本

将提供商的部署脚本复制到项目的 .slack/ 目录,并保留原文件名,然后将其设为可执行文件:

  • Railway:将 references/deploy-railway.sh 复制到 .slack/deploy-railway.sh
  • Heroku:将 references/deploy-heroku.sh 复制到 .slack/deploy-heroku.sh

例如,运行 chmod +x .slack/deploy-railway.sh。

每个脚本都是独立的。它会验证两个令牌是否已传入,从 .slack/apps.json 读取已部署应用的 ID 并用于日志行,然后依次运行提供商的预检、配置资源、配置和部署步骤。除此之外,不需要复制其他内容。CLI 会从项目根目录运行钩子,因此即使脚本位于 .slack/ 中,其相对路径也会以项目根目录为基准解析。

如果脚本已存在,请告知开发者该文件已存在,并在覆盖前征求同意。开发者可能调整过脚本。

4c. 注册钩子

在现有的 .slack/hooks.json 中的 hooks 对象内添加一个 deploy 键,指向提供商的脚本。Railway 的配置如下:

"deploy": "./.slack/deploy-railway.sh"

Heroku 的值为 ./.slack/deploy-heroku.sh。保持 get-hooks 条目原样不变。 它的值在 Bolt for JavaScript 和 Bolt for Python 项目中有所不同,因此不要从其他地方复制。

如果已经存在 deploy 键,不要再添加第二个。 重复的键会导致 JSON 无效,CLI 会拒绝该项目,而不是进行部署。如果现有键已指向所选提供商的脚本,则保持不变。如果它指向其他位置,例如另一家提供商的脚本,请告知开发者并在更改前征求同意。


步骤 5:部署

在项目根目录运行 SLACK_CMD deploy,并留意输出。CLI 会创建已部署的应用、安装该应用,然后运行钩子脚本,因此输出的前半部分是应用安装过程,后半部分是提供商的构建过程。

在交互式终端之外运行时,有四个标志很重要,大多数 Agent 会话都属于这种情况。CLI 会提出四个问题,每个问题都必须回答;如果未回答,操作就会失败:非交互式 shell 会显示 The input device is not a TTY or does not support interactivity,且不会部署任何内容。

  • --skip-update 可阻止 CLI 暂停并提示升级。
  • --team <team ID> 用于选择工作区或组织。使用开发者在 步骤 2b:选择团队 中选定的团队。
  • --app deployed 用于选择已部署的应用环境,并在首次部署时创建该应用。如果不使用此标志,CLI 会要求开发者在现有应用和新应用之间进行选择。这是最容易遗漏的标志,因为它所回答的提示只会在从未部署过的项目上出现。
  • --org-workspace-grant all 用于回答组织安装应用时的工作区授权提示。

因此,完整命令为 SLACK_CMD deploy --skip-update --team <team ID> --app deployed --org-workspace-grant all。

将 步骤 4a:准备提供商 中确定的任何提供商变量放在命令前面。钩子会继承 CLI 的环境变量,因此可以通过这种方式将变量传递给脚本:

HEROKU_TEAM=<team> HEROKU_APP_NAME=<name> SLACK_CMD deploy --skip-update --team <team ID> --app deployed --org-workspace-grant all

已部署的应用与 SLACK_CMD run 使用的应用并非同一个应用。 CLI 会将已部署的应用写入 .slack/apps.json,将本地开发应用写入 .slack/apps.dev.json,并按团队记录。两个应用会彼此独立地正常工作,这是预期设计,并非需要修正的问题。

首次部署后提交 .slack/apps.json。 该文件包含应用 ID 和团队 ID,不包含机密信息;项目的 .slack/.gitignore 特意将其保留为受版本控制的文件。提交此文件可确保后续每次部署都指向同一个应用。在 Heroku 上,这也能避免部署脚本在每次重新部署时警告存在未提交的更改。

还需要提醒开发者一个后果:这两个应用会在同一个工作区中声明相同的斜杠命令。在已部署的应用运行时执行 SLACK_CMD run,会导致无法确定哪个应用会响应斜杠命令。检查已部署的应用时,请停止本地进程;步骤 6:验证部署 中也会执行此操作。


步骤 6:验证部署

检查以下三项。前两项通过时,应用仍可能在 Slack 中毫无响应。

6a. 服务正在运行

使用提供商参考文件中的状态和日志命令。查看应用自身的启动日志,以及 Socket Mode WebSocket 是否已连接。构建成功后进程又退出的情况,在这里会一目了然,因此请查看日志,而不要只相信构建结果。

6b. 本地没有运行任何进程时,应用仍能在 Slack 中响应

先停止本地进程。 只有这样才能证明正在执行任务的是已部署的应用,而不是开发者的笔记本电脑。测试 步骤 3:先在本地确认其正常工作 中提到的交互方式,并确认 Slack 中出现响应,且提供商日志中出现相应请求。

6c. 两个应用彼此不同

向开发者展示 .slack/apps.json 中的应用 ID 和 .slack/apps.dev.json 中的应用 ID,并确认二者不同。然后确认 SLACK_CMD run 仍会运行开发应用。


步骤 7:重新部署

发布更改时,使用相同的 SLACK_CMD deploy 命令和 步骤 5:部署 中的相同标志。步骤 4:设置部署钩子 中的配置都已就绪,因此跳过该步骤,直接部署,并预期使用同一个应用,而不是新建一个应用。

部署脚本会处理以下两项提供商差异:

  • Railway 每次都会上传工作目录并重新构建,因此不需要提交。
  • Heroku 基于 git push 构建,因此未提交的更改不会部署。没有新提交的推送不会构建任何内容,因此脚本会改为重启 dyno,以应用已更改的令牌。重新部署前请先提交代码更改。

如果重新部署创建了第二个 Slack 应用,说明 .slack/apps.json 中已部署应用的条目丢失了。再次部署前,请确认 .slack/apps.json 中有一个对应 --team ID 的条目,而不是之后再删除应用。


步骤 8:拆除部署

开发者不再需要已部署的应用时(例如试用完该技能后),请执行此操作。这会删除主机上的副本和已部署的 Slack 应用,但会保留开发应用。

删除任何内容前,请逐一列出所有资源,并先询问一次。 这些删除操作不可撤销。说明要删除的提供商项目或应用,以及 .slack/apps.json 中的 Slack 应用 ID,然后等待对方确认。

  1. 先删除提供商上的副本,以免有任何内容继续使用即将失效的令牌连接 Slack。命令位于提供商参考文件的“Tearing down”部分。
  2. 使用 SLACK_CMD app delete --team <team ID> --app deployed --force 删除已部署的 Slack 应用。 从 .slack/apps.json 中读取团队 ID。--force 会跳过确认提示,否则在非交互式 shell 中会失败。如果这是唯一已部署的应用,CLI 也会删除 .slack/apps.json,因此请提交这项删除更改。
  3. 保留开发应用,除非开发者也要求删除它。SLACK_CMD run 使用的就是这个应用,而且开发者通常会继续使用它。如果开发者提出要求,请使用带有 --app local 的同一命令删除它。

保留 .slack/hooks.json 和部署脚本,以便之后使用 SLACK_CMD deploy 从头重新完成所有设置。


注意事项

无服务器提供商无法托管 Socket Mode 应用。 Socket Mode 应用是一个常驻进程,会保持一个出站 websocket 连接处于打开状态。Vercel、AWS Lambda 等平台运行的是单次请求函数,这类函数有最长运行时间限制,也不提供始终运行的进程类型,因此 websocket 无处运行。当开发者提出此类需求时,应说明这一限制,而不是尝试实现。在无服务器平台上托管 Slack 应用意味着使用 Request URL 应用,而本技能目前尚未涵盖这种应用。

其他提供商。 当开发者询问本技能未涵盖的提供商时,需要确认两点:它是否提供始终运行的后台工作进程类型,以及该进程如何计费。

令牌传递并非有文档说明的约定。 Slack CLI 不会通过部署钩子显式传递令牌。它会在安装应用时将令牌设置到自身进程中,而钩子脚本稍后在同一进程中运行,因此会继承这些令牌。这种方式可行,而且只适用于没有 Slack 托管函数运行时的应用,其中包括所有 Bolt 应用。这就是为什么每个部署脚本都会检查两个令牌,并在缺少令牌时显示易于理解的提示后停止,而不是假定令牌一定存在。

不要在没有钩子的情况下运行 slack deploy。 如果 .slack/hooks.json 中没有 deploy 键,SLACK_CMD deploy 就会将目标指向 Slack 自己的托管基础设施;这是面向另一类应用的另一款产品。slack:slack-cli 技能涵盖 CLI 的常规命令。

先构建应用。 如果还没有应用,请先使用 slack:create-slack-app 技能,等应用能在本地运行后再回到这里。

评论

支持 Markdown