Skip to content
← Public packages

@kody/slack

Read Slack conversations and safely send messages as the authorizing user through the saved slack OAuth integration.

Featured
Version
1.0.0
License
MIT
Published
September 21, 2026
Pinned commit
db342e2
Rating
★ 5.0 (4)
Forks
21
Adaptation effort
1.3

@kody/slack

Official Slack octothorpe (four-color hash) from Slack brand guidelines.

Intent

Provide reusable, headless Slack helpers that let Kody read conversations the authorizing user can access and send explicitly confirmed messages as that user, never as a bot.

This listing is meant to be forked. After you fork, connect your Slack workspace with a user-token Slack app and run smoke checks on your copy. Do not treat the live @kody/slack integration as yours.

What it does

  • Verify the saved token is a Slack user token (auth.test)
  • List public/private channels, DMs, and group DMs the authorizing user can open
  • Read channel/DM history and threads; resolve authors via workspace users
  • Preview a message with dryRun: true, then send as the user only after confirm: true

Do not use this package as a Slack bot, Event API receiver, or slash-command app. Bot tokens (xoxb-) are rejected.

Prerequisites / setup

Never paste client secrets or tokens into chat. Agents: see AGENTS.md for import paths and smoke checks.

After you fork

  1. Fork this community listing into the user's Kody account (kody id stays slack).
  2. Connect a user-token Slack app (below), then immediately smoke-test the forked package.
  3. If smoke-test says the grant is a bot token, do not retry the helpers. Connect a user-token app (use a distinct name such as slack-user if slack is already a bot grant).
  4. Only then call list/read/send helpers. Pass integration when the connection is not named slack.

Auth model

KindUsed by this package?
BYO Slack app, user-token OAuth (oauth/v2_user + oauth.v2.user.access)Yes — this is the setup path.
/connect/oauth?provider=slack with no authorize/token URLsNo. That reconnects an existing connection. A bot grant fails smoke-test.
API key / raw token pasted into chatNever.
Bot token (xoxb-) or Bot Token Scopes onlyNo. Smoke-test throws.
/account/secrets/new Slack tokenNo. Tokens stay on the OAuth connection.

Required hosts: slack.com (Web API). Add files.slack.com if you later fetch file URLs from message payloads; this package's helpers only call slack.com.

Connect a user-token Slack app

  1. Open api.slack.com/apps → Create New App → From scratch. Name it and pick the workspace.

  2. OAuth & Permissions → Redirect URLs → add exactly https://kody.codes/connect/oauth.

  3. Under User Token Scopes (not Bot Token Scopes) add:

    chat:write, channels:history, channels:read, groups:history, groups:read, im:history, im:read, mpim:history, mpim:read, users:read

  4. Basic Information → note Client ID and Client Secret (paste into Kody, not into chat).

  5. Open this prefilled connect URL while signed in to Kody:

https://kody.codes/connect/oauth?provider=slack&authorizeUrl=https%3A%2F%2Fslack.com%2Foauth%2Fv2_user%2Fauthorize&tokenUrl=https%3A%2F%2Fslack.com%2Fapi%2Foauth.v2.user.access&apiBaseUrl=https%3A%2F%2Fslack.com%2Fapi&flow=confidential&tokenExchangeStyle=form&scopeSeparator=%2C&allowedHosts=slack.com%2Cfiles.slack.com&dashboardUrl=https%3A%2F%2Fapi.slack.com%2Fapps&scopes=chat%3Awrite%2Cchannels%3Ahistory%2Cchannels%3Aread%2Cgroups%3Ahistory%2Cgroups%3Aread%2Cim%3Ahistory%2Cim%3Aread%2Cmpim%3Ahistory%2Cmpim%3Aread%2Cusers%3Aread

Decoded: redirect https://kody.codes/connect/oauth; authorize https://slack.com/oauth/v2_user/authorize; token https://slack.com/api/oauth.v2.user.access; API base https://slack.com/api; flow confidential with tokenExchangeStyle=form; comma scope separator; hosts slack.com, files.slack.com.

  1. Paste the Client ID and Client Secret into the Kody form, continue to Slack, and approve. A workspace admin may need to approve the app.
  2. Smoke-test must show a user identity (user_id and no bot_id).

To connect a second workspace or account, change provider to a distinct name such as slack-work or slack-community, then pass that integration on every helper call. If slack is already a bot-token connection, use provider=slack-user and integration: 'slack-user'.

Reconnect

After invalid_auth, token_revoked, or missing_scope:

https://kody.codes/connect/oauth?provider=slack

Replace slack with your integration name. For a scope change: add the User Token Scope on api.slack.com/apps, then open that reconnect URL.

Scopes

ScopeUsed by
channels:read, groups:read, im:read, mpim:readlist conversations
channels:history, groups:history, im:history, mpim:historyhistory / replies
users:readlist users
chat:writesend message

Private channels and DMs are limited to conversations the authorizing user can already open.

Use only the User Token Scopes listed above — they match Slack's published scope catalog. Keep the prefilled connect URL's scopes= query in sync with that list (and with the scopes you added on the Slack app).

If Slack returns invalid_scope (UI copy is sometimes "incorrect scope"), the authorize URL is asking for a name Slack does not recognize. Example: projects:read is not a Slack OAuth scope; strip unknown scopes from scopes= and retry with the prefilled URL from this README.

Done when

  • Forked copy has a user-token Slack OAuth connection (not a bot grant)
  • Smoke-test reports userIdentity: true and botIdentity: false
  • send-message refuses to post unless dryRun: true or confirm: true
Report this listing

Log in to report this listing.