## Context The Call Recorder schedules Recall bots reactively — a database event trigger reconciles a calendar event when it is created or updated. That misses meetings that already existed before the app was installed, and meetings created far ahead that are never edited as they approach. Neither gets a bot, though recording is on by default. ## What this PR does Moves to the rolling near-term window Recall recommends for [your own calendar integration](https://docs.recall.ai/docs/creating-and-scheduling-bots#scheduling-bots-with-your-own-calendar-integration) — "a daily sync of the next 7 days". Bots are scheduled only for meetings starting within a **7-day horizon**, kept complete by three mechanisms: - **Horizon (policy).** `resolveCallRecorderPolicyResult` caps scheduling at 7 days from now (`EVENT_BEYOND_SCHEDULING_HORIZON`), measured from `startsAt` (the bot's join time). The existing reactive trigger inherits this — far-future creates no longer schedule, and a meeting moved out of the window has its bot canceled. - **Daily sweep (cron).** New `sweep-upcoming-calendar-events` reconciles the 7-day window each day, so a meeting that ages into it without being edited still gets a bot. - **Fresh-install seed (post-install).** The app's single post-install hook (`start-post-install-backfills`) runs the sweep once on a fresh install so a new workspace is covered right away instead of waiting for the first cron; on an upgrade it relies on the cron and backfills missing summaries instead. The sweep runs through the authenticated `reconcile-upcoming-calendar-events` route, which batches ids through the existing reconciliation flow and re-invokes itself near the 900s timeout. Deterministic recording ids keep it idempotent. App self-calls go through a shared `postToOwnRoute` util targeting the server-injected `TWENTY_FUNCTIONS_URL`; a failed kickoff throws so the async hook retries instead of going silently green. Also: fallback titles for call recordings whose calendar event is visibility-restricted; app version → 1.0.7. ## Deferred - Far-future bots already scheduled by the previous no-cap behavior aren't proactively canceled — they fire naturally, or cancel if their event is edited out of the window. - Recall rejects an in-place `join_at` update under 10 min out; today that logs a warning rather than delete-and-recreate. ## Test plan - `yarn test:unit`: 407 tests / 65 files pass — new coverage for the horizon (including a meeting that starts in-window but ends beyond it), the 7-day query filter, the cron handler, the post-install hook's fresh-install vs upgrade branches, and the batch/continuation flow. - `yarn typecheck`, `yarn lint`, and `yarn twenty dev:build` (manifest build) pass. <!-- This is an auto-generated description by cubic. --> <a href="https://cubic.dev/pr/twentyhq/twenty/pull/22552?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. -->
The #1 Open-Source CRM
Website ·
Documentation ·
Roadmap ·
Discord ·
Figma
Why Twenty
Twenty gives technical teams the building blocks for a custom CRM that meets complex business needs and quickly adapts as the business evolves. Twenty is the CRM you build, ship, and version like the rest of your stack.
Learn more about why we built Twenty
Installation
Cloud
The fastest way to get started. Sign up at twenty.com and spin up a workspace in under a minute, with no infrastructure to manage and always up to date.
Build an app
Scaffold a new app with the Twenty CLI:
npx create-twenty-app my-app
Define objects, fields, and views as code:
import { defineObject, FieldType } from 'twenty-sdk/define';
export default defineObject({
nameSingular: 'deal',
namePlural: 'deals',
labelSingular: 'Deal',
labelPlural: 'Deals',
fields: [
{ name: 'name', label: 'Name', type: FieldType.TEXT },
{ name: 'amount', label: 'Amount', type: FieldType.CURRENCY },
{ name: 'closeDate', label: 'Close Date', type: FieldType.DATE_TIME },
],
});
Then ship it to your workspace:
npx twenty app:publish --private
See the app development guide for objects, views, agents, and logic functions.
Self-hosting
Run Twenty on your own infrastructure with Docker Compose, or contribute locally via the local setup guide.
Everything you need
Twenty gives you the building blocks of a modern CRM (objects, views, workflows, and agents) and lets you extend them as code. Here's a tour of what's in the box.
Want to go deeper? Read the User Guide for product walkthroughs, or the
Documentation for developer reference.
|
|
|
|
|
|
Stack
TypeScript
Nx
NestJS, with BullMQ,
PostgreSQL,
Redis
React, with Jotai, Linaria and Lingui
Thanks
Thanks to these amazing services that we use and recommend for code review (Greptile), catching bugs (Sentry) and translating (Crowdin).
Join the Community
Star the repo ·
Discord ·
Feature requests ·
Releases ·
X ·
LinkedIn ·
Crowdin ·
Contribute





