slackapi/slack-skills-plugin/deploy-slack-app

Claude Code and agent skill by slackapi/slack-skills-plugin

Trust tier 3
  • community
Source check pending

Checking that the SKILL.md file is still in the repository.

Use when a developer wants to deploy, host, or run a Slack app somewhere it keeps working after the local process stops, or mentions Railway, Heroku, `railway up`, `git push heroku`, `slack deploy`, a `deploy` hook in `.slack/hooks.json`, hosting a Socket Mode or Request URL (HTTP) Bolt app, deploying from Windows, graduating an app out of a developer sandbox, or tearing down a deployed app.

Install

npx vskill@latest install slackapi/slack-skills-plugin/deploy-slack-app

SKILL.md

Deploy Slack App

Take a Slack app that already works locally and deploy it to a hosting provider as a separate Slack app, with its own app ID, that keeps running without the developer's machine. The local development app is unchanged, and Step 5: Deploy explains how the two coexist. This is the step after the test-slack-app skill confirms the app responds.

The mechanism is the Slack CLI's deploy hook. Adding a deploy key to the project's .slack/hooks.json replaces Slack's own hosted deployment with a script of your choosing, and the CLI runs that script _after_ it has created and installed the deployed app. That ordering is the whole reason this approach is worth using: the app's bot and app-level tokens are already in the script's environment by the time it runs, so nothing here has to prompt for a secret or store one.

Two supported providers, both running the app as a long-lived worker process:

ProviderProcess typeDeploys fromSecretsCurrent pricing
RailwayService, no port binding requiredThe working directoryPassed on stdin<https://railway.com/pricing>
Herokuworker dynoA git push of committed codePassed as arguments<https://www.heroku.com/pricing>

Railway is the better default, and the reasons are in Step 2a: Choose a Provider.


Step 1: Check Prerequisites

1a. Detect the Slack CLI

Use the slack-cli skill (Step 1: Detect the Slack CLI) to check whether the public Slack CLI is installed and resolve its command name. The fingerprint check, alias fallback, and install instructions all live there; do not duplicate them. Refer to the resolved command as SLACK_CMD throughout.

This matters more than it looks. Some machines have an unrelated internal tool named slack on the path, and running that instead produces confusing failures well into the deploy.

1b. Confirm the App Uses Socket Mode

Read the app's manifest rather than asking. The project already declares which mode it uses, so a question here is redundant. Check manifest.json for settings.socket_mode_enabled. If .slack/config.json sets the manifest source to remote, there is no local file, so read it with SLACK_CMD manifest info instead.

  • Socket Mode enabled: continue. The app opens an outbound websocket to Slack, needs no public URL, and binds no HTTP port.
  • Socket Mode disabled, or the app uses a Request URL: stop here. This skill does not cover Request URL apps yet, because a hosted Request URL app also needs a public address captured after the deploy and written back into the app manifest. Tell the developer plainly that this is the gap, and that converting the app to Socket Mode is the supported path today. Support may have shipped in a newer version of the Slack Skills Plugin, so ask the developer to update the plugin and try again. If they are already on the latest version, point them to <https://github.com/slackapi/slack-skills-plugin/issues/172> to add a reaction or comment.

If the manifest is ambiguous, read the app's entrypoint. A Bolt for JavaScript app constructed with socketMode: true and an appToken, or a Bolt for Python app started through SocketModeHandler, is a Socket Mode app.

1c. Confirm the Runtime Is Supported

This flow is verified on macOS and Linux. The deploy hook is a shell script, so a Windows developer needs a PowerShell equivalent that does not exist yet. On Windows, say so rather than letting the deploy fail partway through. WSL is a workable path in the meantime. Support may have shipped in a newer version of the Slack Skills Plugin, so ask the developer to update the plugin and try again. If they are already on the latest version, point them to <https://github.com/slackapi/slack-skills-plugin/issues/171> to add a reaction or comment.


Step 2: Choose a Provider and a Team

Ask the developer two things the project cannot tell you: which provider to deploy to, and which Slack team to deploy into.

2a. Choose a Provider

Ask which provider, because cost is the thing the developer cannot infer from the project. Give the developer both pricing links from the table above so they can check current terms. Do not fetch the pages or quote prices, plan names, or trial terms. Providers change them often, and this skill can be installed long after it was written.

What does not change with the price list, and is worth saying:

  • Railway is the default recommendation. It accepts secrets on stdin, so the tokens never appear in process arguments. It deploys the working directory, so a re-deploy needs no commit, and it needs no Procfile.
  • Heroku fits when the developer already has an account, or a team standard that points there. It builds from git, so only committed code is deployed. Some accounts, including enterprise-managed ones, cannot own a personal app and must create it on a Heroku team. Personal apps and team apps can have different plans and billing, so ask which team to use rather than picking one: a shared team has a shared budget.

Say plainly that both providers keep the app running continuously, which is what a Socket Mode app requires. Always-on hosting is a paid service in the end, so expect it to cost something once any trial runs out.

Once the developer picks one, read that provider's reference file and follow it: references/railway.md or references/heroku.md. Each holds the install and authentication commands, the provider's own requirements for the project, and the environment variables its deploy script reads. Step 4: Wire Up the Deploy Hook works through them.

2b. Choose a Team

Run SLACK_CMD auth list. If it lists one team, use it. If it lists more than one, show the developer each team's name and ID and ask which one to deploy into.

Never pick the team yourself. Do not assume the standalone workspace or the Enterprise org, and do not reuse the team from .slack/apps.dev.json, which is often a developer sandbox. A wrong guess installs the app into a team the developer did not intend, and a later deploy to the right team creates a second Slack app.


Step 3: Confirm It Works Locally First

Do not deploy an app that has not been seen working. A broken deploy and a broken app look identical in a provider's logs, and separating them afterwards costs far more than checking first.

Use the test-slack-app skill to run the app with SLACK_CMD run and exercise at least one real surface, so there is a known-good behaviour to re-check after the deploy. Note which surface was used: the same one is the check in Step 6: Verify the Deployment.


Step 4: Wire Up the Deploy Hook

Three things to set up. Check whether each already exists before writing it, because re-deploying an app is the common case and clobbering a developer's edited script is not recoverable.

4a. Prepare the Provider

Work through the chosen provider's reference file before writing anything, because the deploy script only checks these and stops. It cannot fix them.

  • Install and authenticate the provider's CLI. Run its whoami check. Logging in opens a browser, so if the check fails, ask the developer to run the login command in their own terminal rather than running it yourself.
  • Settle the names and ownership with the developer. For Heroku: a distinctive app name, and whether the app belongs to a team (heroku teams). For Railway: the workspace, if the account has more than one. These become environment variables on the deploy command in Step 5: Deploy.
  • Meet the provider's project requirements. For Heroku, write the Procfile and commit it. For Railway, confirm the start command it will detect.
4b. Write the Deploy Script

Copy the provider's deploy script into the project's .slack/ directory under the same name, then make it executable:

  • Railway: references/deploy-railway.sh to .slack/deploy-railway.sh
  • Heroku: references/deploy-heroku.sh to .slack/deploy-heroku.sh

For example, chmod +x .slack/deploy-railway.sh.

Each script is self-contained. It validates that both tokens arrived, reads the deployed app ID from .slack/apps.json for its log line, and then runs the provider's preflight, provision, configure, and deploy steps in order. There is nothing else to copy. The CLI runs the hook from the project root, so the script's relative paths resolve there even though the file lives in .slack/.

If the script already exists, show the developer that it is there and ask before overwriting. A developer may have adjusted it.

4c. Register the Hook

Add a deploy key inside the existing hooks object in .slack/hooks.json, pointing at the provider's script. For Railway:

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

For Heroku, the value is ./.slack/deploy-heroku.sh. Leave the `get-hooks` entry exactly as it is. Its value differs between Bolt for JavaScript and Bolt for Python projects, so do not copy one from elsewhere.

If a `deploy` key is already present, do not add a second one. A duplicate key produces invalid JSON, and the CLI will reject the project rather than deploy it. If the existing key already points at the chosen provider's script, leave it. If it points somewhere else, such as the other provider's script, show the developer and ask before changing it.


Step 5: Deploy

Run SLACK_CMD deploy from the project root and watch the output. The CLI creates the deployed app, installs it, and then runs the hook script, so the first part of the output is app installation and the second is the provider's build.

Four flags matter when running this outside an interactive terminal, which includes most agent sessions. The CLI asks four questions, and each one is fatal unanswered: a non-interactive shell gets The input device is not a TTY or does not support interactivity and nothing is deployed.

  • --skip-update stops the CLI pausing to offer an upgrade.
  • --team <team ID> picks the workspace or organization. Use the team the developer chose in Step 2b: Choose a Team.
  • --app deployed selects the deployed app environment, and creates that app on a first deploy. Without it the CLI asks the developer to choose between an existing app and a new one. This is the flag most easily missed, because the prompt it answers only appears on a project that has never been deployed.
  • --org-workspace-grant all answers the workspace-grant prompt for an org-installed app.

So the full command is SLACK_CMD deploy --skip-update --team <team ID> --app deployed --org-workspace-grant all.

Put any provider variables settled in Step 4a: Prepare the Provider in front of it. The hook inherits the CLI's environment, so this is how they reach the script:

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

The deployed app is a different app from the one `SLACK_CMD run` uses. The CLI writes the deployed app to .slack/apps.json and the local development app to .slack/apps.dev.json, keyed by team. Both keep working independently, which is the intended design, not a mistake to correct.

Commit `.slack/apps.json` after the first deploy. It holds app and team IDs, not secrets, and the project's .slack/.gitignore leaves it tracked on purpose. Committing it keeps every later deploy pointed at the same app. On Heroku it also stops the deploy script warning about uncommitted changes on each re-deploy.

One consequence to warn the developer about: the two apps declare the same slash commands in the same workspace. Running SLACK_CMD run while the deployed app is live makes it ambiguous which one answers a slash command. Stop the local process when checking the deployed app, which Step 6: Verify the Deployment does anyway.


Step 6: Verify the Deployment

This is the start of the file. Read the full SKILL.md on GitHub.

Security

  • Security scanPassed, 90 of 100Pattern checks on the skill's files.
  • Model reviewPassed

Quality evaluation

  • Task evaluationNot runNo evaluation yet. Run one in Skill Studio.

Source

Popularity

7-day trend score
0

Not refreshed yet.

Works with

Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.

  • Claude Code
  • Cursor
  • GitHub Copilot
  • Windsurf
  • Codex
  • Gemini CLI
  • Cline
  • Amp
  • Roo Code
  • Goose
  • Continue
  • Kilo Code
  • Junie
  • Trae
  • OpenHands
  • Qwen Code
  • AI Agent
  • Tabnine Chat
  • Sourcegraph Cody
  • Amazon Q
  • Firebase Genkit
  • Sweep
  • Devin
  • Phind
  • Mentat
  • Claude Desktop
  • Aider
  • GPT Pilot
  • Plandex
  • bolt.new
  • v0
  • Replit Agent
  • Anse
  • TypingMind
  • BetterChatGPT
  • LibreChat
  • Warp AI
  • Pieces
  • Fig AI
Embed badge
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/slackapi/slack-skills-plugin/deploy-slack-app/badge)](https://verified-skill.com/skills/slackapi/slack-skills-plugin/deploy-slack-app)

Something wrong with this skill or its page? Tell us.