@kody/slack
Read Slack conversations and safely send messages as the authorizing user through the saved slack OAuth integration.
README.md
94 lines · 5.6 KB · Markdown@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 afterconfirm: 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
- Fork this community listing into the user's Kody account (kody id stays
slack). - Connect a user-token Slack app (below), then immediately smoke-test the forked package.
- 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-userifslackis already a bot grant). - Only then call list/read/send helpers. Pass
integrationwhen the connection is not namedslack.
Auth model
| Kind | Used 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 URLs | No. That reconnects an existing connection. A bot grant fails smoke-test. |
| API key / raw token pasted into chat | Never. |
Bot token (xoxb-) or Bot Token Scopes only | No. Smoke-test throws. |
/account/secrets/new Slack token | No. 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
Open api.slack.com/apps → Create New App → From scratch. Name it and pick the workspace.
OAuth & Permissions → Redirect URLs → add exactly
https://kody.codes/connect/oauth.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:readBasic Information → note Client ID and Client Secret (paste into Kody, not into chat).
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%3AreadDecoded: 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.
- 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.
- Smoke-test must show a user identity (
user_idand nobot_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=slackReplace 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
| Scope | Used by |
|---|---|
channels:read, groups:read, im:read, mpim:read | list conversations |
channels:history, groups:history, im:history, mpim:history | history / replies |
users:read | list users |
chat:write | send 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: trueandbotIdentity: false send-messagerefuses to post unlessdryRun: trueorconfirm: true