- adds `twenty-slack` to internal application ci - unify config with twenty-last-contact app - add base oxlint config to show error twenty-shared is used in internal app <!-- This is an auto-generated description by cubic. --> <a href="https://cubic.dev/pr/twentyhq/twenty/pull/21849?utm_source=github" target="_blank" rel="noopener noreferrer" data-no-image-dialog="true"><picture><source media="(prefers-color-scheme: dark)" srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img alt="Review in cubic" src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a> <!-- End of auto-generated description by cubic. -->
twenty-slack
Slack tools for Twenty workflows and agents (the same logic functions
are available as workflow steps and as tools where your deployment exposes
them). Uses the official
@slack/web-api WebClient
(Slack retries and error types).
What you can do
Once the app is installed and Slack is connected (see Twenty setup below):
- Workflow steps — post, update, or delete bot messages; send ephemerals; add reactions; list channels. Pick a workspace shared or just for me connection; steps run with that token.
- Agents / AI — when your Twenty instance surfaces app tools to the model, these functions can be invoked the same way as other app logic functions.
- Quick-send — command menu Send Slack message opens a side panel to pick a channel and post (same Slack connection as workflows).
Tools
| Name | Slack API |
|---|---|
slack-post-message |
chat.postMessage |
slack-post-ephemeral-message |
chat.postEphemeral |
slack-update-message |
chat.update |
slack-delete-message |
chat.delete |
slack-add-reaction |
reactions.add |
slack-list-channels |
conversations.list |
Workflow field names (for authors)
Fields use camelCase names in the step UI, for example slackChannelId (Slack channel or DM: name or ID), messageText, and messageTimestamp (Slack’s per-message id — same value as tool output slackTs when chaining steps). Optional parentMessageTimestamp is only for thread replies. Post / update / ephemeral steps support optional messageFormat: markdown sends the body as Slack markdown_text (e.g. **bold**), plain sends text with markup disabled, omit uses Slack’s default for text. Ephemeral steps use recipientSlackUserId; reactions use emojiName (Slack shortcode, for example white_check_mark). Updating a message uses newMessageText.
Quick-send command menu item
This app also ships a global command menu item — Send Slack message — that opens a side-panel form to pick a channel (from conversations.list) and post a message via chat.postMessage. The form is backed by two HTTP routes exposed by the app:
GET /slack/channels— lists channels visible to the bot (mirrorsslack-list-channels).POST /slack/messages— posts a message (mirrorsslack-post-message).
Both routes require an authenticated Twenty user and use the same shared Slack connection as the workflow tools.
Prerequisites (Slack workspace)
- You can install the Slack app on a workspace you administer (or get an admin to approve it).
- For posting: invite the bot to the channel, or rely on
chat:write.public(included in OAuth) to post to public channels without joining — private channels still require membership. slack-list-channelsand the quick-send channel picker needchannels:read/groups:readon the token (requested at connect time; see below).
Slack app setup
-
Create a Slack app at api.slack.com/apps (dedicated to this Twenty app — do not reuse for other Twenty apps).
-
OAuth & Permissions → Bot Token Scopes. Twenty uses Slack’s bot OAuth (
oauth/v2/authorizewithscope=…). You must add scopes here — not only under User Token Scopes — or Slack will refuse install with “doesn’t have a bot user to install” until at least one bot scope exists.The scopes requested at connect time are defined in
src/connection-providers/slack-connection.tsand must also appear under Bot Token Scopes on the Slack app (Slack validates the set). Current list:channels:read—conversations.list/ channel picker (public)chat:write— post, update, delete, ephemeralchat:write.public— post to public channels without the bot joininggroups:read— list private channels the bot is inreactions:write— add reactions
If you add or remove scopes in that file or in the Slack app, existing installs must re-authorize (disconnect and Add connection again, or reinstall the Slack app to the workspace) so the token picks up new scopes.
-
Set the Redirect URL on the Slack app to
<YOUR_TWENTY_SERVER_URL>/auth/apps/callback— the same origin your Twenty server uses for API routes (the callback is not served by the SPA alone). Local monorepo dev often useshttp://localhost:3000(confirm the port yourtwenty-server/SERVER_URLactually uses).Slack “PKCE” app setting vs
localhost: If you turn on PKCE for the Slack app under OAuth & Permissions, Slack treatshttp://localhost…redirect URLs as desktop redirects. Desktop redirects cannot request bot scopes, so OAuth will fail for this integration while you use a localhost callback. For local dev you can either leave Slack’s PKCE opt-in disabled on that Slack app, or use anhttps://redirect (for example a tunnel such as ngrok or Cloudflare Tunnel to your local server), register that URL in the Slack app, and point Twenty’sSERVER_URLat the same public base URL. See Slack’s Using PKCE docs (this is separate from Twenty sending a PKCE challenge on the authorize request). -
Copy the Slack Client ID and Client Secret.
Twenty setup
- Register / install this app on your Twenty server (
twenty-slack). - In Settings → Applications → Twenty Slack, open the Application registration
tab (admin-only) and set:
SLACK_CLIENT_IDSLACK_CLIENT_SECRET
- In the same app, open the Connections tab and click Add connection. Choose Just for me or Workspace shared, then complete the Slack sign-in.
Once connected, workflow steps use the connection access token: a
workspace connection is preferred when present; otherwise the first
connection returned for the Slack provider is used (see
src/logic-functions/utils/get-slack-connection.ts).
Development
cd packages/twenty-apps/internal/twenty-slack
yarn install
yarn lint
yarn test
Use yarn twenty dev from this directory to develop against a local Twenty
instance (see other internal apps in this monorepo).