c52c983b90
## 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. -->
Twenty for Twenty
The official Twenty internal app, with modules for Resend and more.
Overview
Twenty for Twenty is the official internal Twenty app. It is organized into modules, each integrating a third-party service with Twenty.
Resend module
Two-way sync between Twenty and the Resend email platform. The module syncs contacts, segments, templates, broadcasts, and emails.
Inbound (Resend → Twenty):
- A cron job runs every 5 minutes to pull all entities from the Resend API.
- A webhook endpoint receives real-time events for contacts and emails.
Outbound (Twenty → Resend):
- Contact and segment changes in Twenty are pushed back to Resend when records are created, updated, or deleted.
Configuration
In Twenty, go to Settings → Applications → Twenty for Twenty and set:
- RESEND_API_KEY — your Resend API key. Create one at https://resend.com/api-keys (full access recommended).
- RESEND_WEBHOOK_SECRET — the signing secret for verifying inbound webhooks (see "Webhook setup" below).
Webhook setup
The app exposes an HTTP endpoint at /s/webhook/resend that receives Resend webhook events. To connect it:
- Go to https://resend.com/webhooks
- Click Add webhook
- Set the Endpoint URL to your Twenty server's public URL +
/s/webhook/resend(e.g.https://your-domain.com/s/webhook/resend) - Set Event types to All Events
- Click Add
- Copy the signing secret Resend displays and paste it into the
RESEND_WEBHOOK_SECRETapp variable in Twenty
Sync behavior
Inbound
| Source | Mechanism | Entities |
|---|---|---|
| Cron (every 5 min) | Polls Resend API, upserts into Twenty | Contacts, segments, templates, broadcasts, emails |
| Webhook (real-time) | Receives Resend events via HTTP | Contacts, emails |
Outbound
| Twenty action | Resend |
|---|---|
| Create contact | Creates the contact in Resend |
| Update contact (name, email, unsubscribed) | Updates the Resend contact |
| Delete contact | Removes the Resend contact |
| Create segment | Creates the segment in Resend |
| Delete segment | Removes the Resend segment |