## 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. -->
2.8 KiB
Twenty Meeting Bot
Capture every customer conversation automatically. A meeting bot joins eligible meetings and records calls for you.
Recall.ai configuration
This app schedules Recall.ai meeting bots and ingests their lifecycle events.
A server admin configures Recall credentials through server variables on the application registration (Settings → Applications → Twenty Meeting Bot):
| Server variable | Required | Purpose |
|---|---|---|
RECALL_API_KEY |
Yes | Recall.ai API key for the configured region; used to schedule, update, and cancel bots. |
RECALL_REGION |
No | Recall.ai region for API requests. Defaults to eu-central-1. |
MEETING_BOT_RECORDING_RETENTION_HOURS |
No | How many hours Recall.ai retains recording media after processing. Defaults to 166 hours (6 days and 22 hours) to stay below Recall.ai's 7-day free storage window. Values above 168 hours may incur Recall.ai storage charges. |
RECALL_WEBHOOK_SECRET |
Yes | Svix signing secret (whsec_…) used to verify incoming Recall webhooks. |
Recall.ai retention only controls Recall.ai's copy of the recording media. Twenty stores ingested transcript and video artifacts in its own storage, so deleting Recall.ai media after the retention window does not remove the artifacts already stored in Twenty.
A workspace admin can adjust bot behavior through application variables:
| Application variable | Default | Purpose |
|---|---|---|
MEETING_BOT_NAME |
Twenty Meeting Bot |
Display name the meeting bot uses when it joins a call. |
MEETING_BOT_JOIN_EARLY_MINUTES |
1 |
How many minutes before the meeting start time the bot should join. Set to 0 to join at the scheduled start time. |
MEETING_BOT_WAITING_ROOM_TIMEOUT_SECONDS |
1200 |
How many seconds the bot waits in a meeting lobby before giving up and leaving. |
MEETING_BOT_NOONE_JOINED_TIMEOUT_SECONDS |
1200 |
How many seconds the bot stays in an empty meeting when no one else ever joins. |
MEETING_BOT_EVERYONE_LEFT_TIMEOUT_SECONDS |
2 |
How many seconds the bot keeps recording after everyone else leaves the meeting. |
Configuring the webhook
The app exposes an unauthenticated route, POST /webhook/recall, that verifies the Recall/Svix signature and updates the matching CallRecording's lifecycle status (JOINING → RECORDING → PROCESSING, or FAILED_UNKNOWN).
- In the Recall.ai dashboard, create a webhook endpoint (Status Change Webhooks) pointing at the public URL of this app's
POST /webhook/recallroute. - Copy the endpoint's signing secret — it starts with
whsec_. - Set it as the
RECALL_WEBHOOK_SECRETserver variable on the Twenty Meeting Bot application registration.
The handler ignores out-of-order or duplicate deliveries (it never moves a recording's status backwards) and returns a non-2xx response on signature failures so Recall retries.