Files
twenty/packages/twenty-apps/internal/twenty-slack
Raphaël Bosi c52c983b90 Source app About description from README and improve internal app READMEs (#22012)
## What

- The SDK manifest build now sources an app's `aboutDescription` (the
long-form "About" tab content) from its `README.md`. An explicit
`aboutDescription` in the config still wins, matching the existing
marketplace CDN fallback.
- Removed the now-duplicated `aboutDescription` from internal app
configs and deleted the standalone `ABOUT_DESCRIPTION` constant files.
- Rewrote internal app READMEs to read as user-facing About content:
stripped developer/build/source-path noise, and expanded the thin ones.
`call-recording` and `self-hosting` (one-liners over substantial apps)
and `people-data-labs` were rewritten from a close reading of the code;
`twenty-exa` was verified for accuracy.
- Added a unit test (and a fixture README) covering README →
`aboutDescription` in the build.

## Why

The README and the About description were maintained separately and
drifted. Making the README the single source keeps the About tab
accurate and removes duplicated copy.

## Notes for reviewers

- Internal apps depend on the published `twenty-sdk`, so the build
change takes effect for them after an SDK release + dependency bump.
Until then, published apps still get README → `aboutDescription` via the
marketplace CDN sync.
- Standard/Custom app descriptions are unchanged (they are resolved in
the frontend, not via the manifest).

<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/22012?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. -->
2026-06-23 15:27:52 +02:00
..
2026-05-20 10:21:22 +00:00

Slack for Twenty

Slack tools for Twenty workflows and agents — the same logic functions are available as workflow steps and as tools where your deployment exposes them.

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 (Slacks 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 Slacks 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 (mirrors slack-list-channels).
  • POST /slack/messages — posts a message (mirrors slack-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-channels and the quick-send channel picker need channels:read / groups:read on the token (requested at connect time; see below).

Slack app setup

  1. Create a Slack app at api.slack.com/apps (dedicated to this Twenty app — do not reuse for other Twenty apps).

  2. OAuth & PermissionsBot Token Scopes. Twenty uses Slacks bot OAuth (oauth/v2/authorize with scope=…). You must add scopes here — not only under User Token Scopes — or Slack will refuse install with “doesnt have a bot user to install” until at least one bot scope exists.

    The scopes requested at connect time must also appear under Bot Token Scopes on the Slack app (Slack validates the set). Current list:

    • channels:readconversations.list / channel picker (public)
    • chat:write — post, update, delete, ephemeral
    • chat:write.public — post to public channels without the bot joining
    • groups:read — list private channels the bot is in
    • reactions:write — add reactions

    If you add or remove scopes for this app 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.

  3. 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 uses http://localhost:3000 (confirm the port your twenty-server / SERVER_URL actually uses).

    Slack “PKCE” app setting vs localhost: If you turn on PKCE for the Slack app under OAuth & Permissions, Slack treats http://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 Slacks PKCE opt-in disabled on that Slack app, or use an https:// redirect (for example a tunnel such as ngrok or Cloudflare Tunnel to your local server), register that URL in the Slack app, and point Twentys SERVER_URL at the same public base URL. See Slacks Using PKCE docs (this is separate from Twenty sending a PKCE challenge on the authorize request).

  4. Copy the Slack Client ID and Client Secret.

Twenty setup

  1. Register / install this app on your Twenty server (twenty-slack).
  2. In Settings → Applications → Twenty Slack, open the Application registration tab (admin-only) and set:
    • SLACK_CLIENT_ID
    • SLACK_CLIENT_SECRET
  3. 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.