Recued
Menu
← Back to recipes

Prepare a Cal.com meeting from project updates

by recued-core v5 52 views

Use “Prepare a Cal.com meeting from project updates” in Recued. Reuse current project and task progress to prepare the project portion automatically, then show only unresolved decisions, new topics, and uncovered context.

Complete workflow

Use Meeting Prep from Project Updates - Cal.com in Recued. Keep work current as it happens, then reuse that progress for the project portion of your next meeting and prepare only what remains.

You are viewing one recipe in this workflow. Installing it opens the complete pack so its other recipes and background automations arrive together.

Use “Prepare a Cal.com meeting from project updates” in Recued. Reuse current project and task progress to prepare the project portion automatically, then show only unresolved decisions, new topics, and uncovered context.

pack:meeting-prep-project-context-calcommeeting-prepproject-contextproject-management
by recued-core pinned v5
View pack details, dependencies, and permissions →

Update once, prepare from progress

Keep projects and tasks current as work happens. This recipe reuses those updates to prepare the project portion of an upcoming Cal.com meeting, so attendees do not have to report the same progress again before the meeting. The more current the work is, the less separate preparation remains.

It reads one booking and its attendees, parses the previous meeting notes, and checks the projects you select. Booking intake and an optional existing brief supply genuinely new topics; they do not replace current project state or ask people to repeat it.

What is ready and what still needs attention

The result separates progress already prepared from project updates, unresolved items carried from the previous meeting, decisions that still need the room, and new context from the booking or optional brief. Coverage and omissions show what Recued could not prepare.

This is a project-context supplement, not the whole meeting brief. It stays temporary: nothing is saved as a note, meeting record, or project record, and topics outside the supplied files and selected projects remain outside its claims.

Promises still owed

When an earlier meeting recorded something you promised, it is carried into this preparation as an open item with its own id — read back from what was recorded, not re-read out of the previous meeting’s notes. Only promises still outstanding on the projects in scope appear; anything already settled stays out, so a meeting does not reopen a closed decision.

What “updated” means

Recued reads each selected project and up to 50 current tasks per included project. A task is in the update window when its current updated_at falls on or after Previous meeting time. A project is in the window when its updated_at or last_activity_at does. These timestamps prove only that a row was touched during the window. They are not an audit log and cannot prove which field changed or what its old value was.

Federated projects

A selected local project is eligible directly. A selected federated project is eligible only when an email from the Cal.com booking matches exactly one active participant in that project. Missing or ambiguous matches are reported under omissions instead of exposing that project’s tasks.

Running it before the meeting

Turn this on under Automation and Recued checks every fifteen minutes for bookings starting within your lead time (two hours by default) that it has not prepared yet, and prepares the soonest one. Each meeting is recorded once, so a later check moves on to the next rather than repeating itself; running a meeting by hand is never blocked by that record. Nothing due is a quiet stop, not a failure. What Recued has already prepared is recorded per month, so the check stays the same size however long you run it.

Cal.com has no “before the meeting” webhook — it can tell Recued when a booking is made or when a meeting starts, one too early to be useful and one too late — so the timing is Recued’s own. Each automatic run asks permission to record what it prepared — once per meeting, not once overall. Answer them promptly: a run waiting on approval counts as a failed run, and five in a row switch the automation off until you re-enable it. If you would rather it never asked, lower the risk on the storage operation in Settings; turning the approval off is a decision about your own bookkeeping, not about the meeting.

Inputs and limits

Nothing is required except a Cal.com connection. Use the UID of one future booking occurrence, not a recurring-series UID.

Everything else is found for you, and every part of it can be overruled:

  • Previous meeting — by default the most recent past booking with the same first attendee on the same event type. Set Previous booking UID to pin a different one; both the activity window and the prior-meeting notes then come from that single booking, so re-running gives the same result. Set Previous meeting to skip to ignore earlier meetings entirely — nothing is searched, nothing is downloaded, and no approval is requested.
  • Previous meeting time — the end of that booking. Supply your own to widen or narrow the window regardless of which meeting was used.
  • Previous meeting notes — that booking’s own Cal.com transcript, when one exists. Recued asks before downloading it, because transcript links are private and expire after an hour. Anything you attach is a supplement, not a replacement: your file and the transcript are both read and both go to the preparation, each labelled with where it came from. Attach notes for a meeting Cal.com did not record, or a fuller account of one it did. Use skip when you want nothing from the past read at all.
  • Projects — the project IDs Recued recorded on the booking when it created it. Supply your own list to override.

None of this is a chain you have to be at the end of. A first meeting on a project works with nothing to look back on: with no earlier booking and no time supplied there is no activity window at all, every current row is in scope, and coverage says so. Prior-meeting context is optional throughout — without notes the recipe still prepares from current project and task progress, and coverage reports exactly which sources it used and which it could not. The upcoming brief is optional and should contain new agenda material rather than another status report. Choose at most eight project IDs; extra selections are reported as omitted. Task reads are capped at 50 per included project and report any remaining count. The recipe performs no durable writes.

How it works 251 steps

Inspect the data fetches, transforms, gates, and output this recipe runs.

Process (251 steps)
■ config_project_refs default
Apply default
■ has_config_projects compare
Check if config project refs has data
■ supplied_booking_uid trim
Trim whitespace from setting booking uid
■ has_supplied_booking compare
Check if supplied booking uid has data
■ lead_time_minutes clamp
Clamp setting lead time minutes between 5 and 10080
■ sweep_now_iso date_add
Add 0 seconds to
■ sweep_horizon_iso date_add
Add lead time minutes minutes to
◆ upcoming_search recued-core.calcom.booking.search
Search booking on calcom
skip: step.has_supplied_booking equal true
■ upcoming_bookings default
Apply default
■ bookings_with_projects filter
Filter by condition
■ sweep_candidates ternary
Apply ternary
■ sweep_month date_format
Format as a date
■ horizon_month date_format
Format as a date
■ window_spans_two_months compare
Check if sweep month does not equal horizon month
◆ prepared_marks core.storage.shared.list
List storage shared
skip: step.has_supplied_booking equal true
◆ prepared_marks_horizon core.storage.shared.list
List storage shared
skip: step.window_spans_two_months equal false
■ prepared_entries_current default
Apply default
■ prepared_entries_horizon default
Apply default
■ prepared_entries flatten
Flatten nested lists in
■ prepared_uids pluck
Extract value.booking_uid from each item
■ unprepared_bookings filter
Filter by condition
■ sweep_pick find
Find first match in
■ sweep_pick_uid default
Apply default
■ booking_uid default
Apply default
⚠ booking_uid_guard guard
Stop if booking uid is empty
◆ booking_read recued-core.calcom.booking.read
Read booking on calcom
■ booking default
Apply default
⚠ booking_shape_guard guard
Stop if booking uid is empty
■ booking_start_at date_parse
Parse booking start as a date
⚠ booking_start_guard guard
Stop if booking start at is missing
■ now_ms date_parse
Parse sweep now iso as a date
■ booking_is_upcoming compare
Check if booking start at is greater than now ms
⚠ booking_upcoming_guard guard
Stop if booking is upcoming equals
■ booking_is_live compare
Check if booking status is not one of cancelled,rejected
⚠ booking_live_guard guard
Stop if booking is live equals
◆ attendee_read recued-core.calcom.booking.attendee.search
Search booking attendee on calcom
■ attendee_rows default
Apply default
■ host_rows default
Apply default
■ attendee_people map
Extract from each item
■ host_people map
Extract from each item
■ meeting_people_raw flatten
Flatten nested lists in
■ meeting_people_trimmed map
Extract email from each item
■ meeting_people_normalized map
Extract email_trimmed from each item
■ meeting_people filter
Filter by condition
■ meeting_emails_raw pluck
Extract email from each item
■ meeting_emails unique
Remove duplicates from
■ meeting_names_raw pluck
Extract name from each item
■ meeting_phone_numbers_raw pluck
Extract phone_number from each item
■ meeting_phone_numbers unique
Remove duplicates from
■ primary_attendee_rows slice
Take a subset of
■ primary_attendee_emails pluck
Extract email from each item
■ primary_attendee_email_raw join
Join items with ""
■ primary_attendee_email trim
Trim whitespace from primary attendee email raw
■ can_search_previous compare
Check if primary attendee email has data
■ previous_meeting_skipped compare
Check if setting previous meeting mode equals skip
■ previous_uid_override trim
Trim whitespace from setting previous booking uid
■ has_uid_override compare
Check if previous uid override has data
■ discover_previous all
Check if all conditions are true
■ read_pinned_previous all
Check if all conditions are true
◆ pinned_booking_read recued-core.calcom.booking.read
Read booking on calcom
skip: step.read_pinned_previous equal false
■ pinned_booking default
Apply default
■ pinned_booking_uid default
Apply default
■ pinned_booking_end default
Apply default
■ pinned_booking_missing all
Check if all conditions are true
⚠ pinned_booking_guard guard
Stop if pinned booking missing equals
◆ previous_booking_search recued-core.calcom.booking.search
Search booking on calcom
skip: step.discover_previous equal false
■ previous_bookings default
Apply default
■ previous_booking_rows slice
Take a subset of
■ previous_booking_ends pluck
Extract end from each item
■ discovered_booking_end join
Join items with ""
■ previous_booking_uids pluck
Extract uid from each item
■ discovered_booking_uid join
Join items with ""
■ previous_booking_uid default
Apply default
■ previous_booking_end default
Apply default
■ has_previous_booking compare
Check if previous booking uid has data
■ previous_meeting_text trim
Trim whitespace from setting previous meeting at
■ previous_meeting_source default
Apply default
■ previous_meeting_at date_parse
Parse previous meeting source as a date
■ window_floor default
Apply default
■ window_from_supplied compare
Check if previous meeting text has data
■ window_from_booking all
Check if all conditions are true
■ window_source_fallback ternary
Apply ternary
■ previous_meeting_window_source ternary
Apply ternary
■ previous_meeting_selection_found ternary
Apply ternary
■ previous_meeting_selection_active ternary
Apply ternary
■ previous_meeting_selection ternary
Apply ternary
■ window_precedes_meeting any
Check if any of the conditions are true
⚠ window_order_guard guard
Stop if window precedes meeting equals
■ booking_intake default
Apply default
■ booking_intake_json json_stringify
Apply json_stringify
■ has_booking_intake compare
Check if booking intake json does not equal {}
■ notes_file_supplied compare
Check if setting previous notes has data
◆ previous_notes_markdown recued-core.docling.document.to_markdown
To markdown document on docling
skip: step.notes_file_supplied equal false
■ previous_notes_ref default
Apply default
■ has_previous_notes_file compare
Check if previous notes ref has data
✦ previous_notes_extract_file core.ai.extract
AI extracts structured fields from data
skip: step.has_previous_notes_file equal false
■ use_previous_transcript all
Check if all conditions are true
◆ previous_transcript_link_read recued-core.calcom.booking.transcript.search
Search booking transcript on calcom
skip: step.use_previous_transcript equal false
■ previous_transcript_links default
Apply default
◆ previous_transcript_downloads recued-core.curl.http.get_text
Get text http on curl
■ previous_transcript_link_count count
Count items in previous transcript links
■ complete_previous_downloads filter
Filter by condition
■ complete_previous_download_count count
Count items in complete previous downloads
■ previous_transcript_complete all
Check if all conditions are true
■ previous_transcript_parts map
Extract from each item
■ previous_transcript_raw join
Join items with " "
■ previous_transcript_text trim
Trim whitespace from previous transcript raw
■ has_previous_transcript all
Check if all conditions are true
■ previous_transcript_pii_protect pii-protect
Apply pii-protect
✦ previous_notes_extract_transcript core.ai.extract
AI extracts structured fields from data
skip: step.has_previous_transcript equal false
■ previous_notes_extract_transcript_restored pii-restore
Apply pii-restore
■ previous_notes_sources_raw default
Apply default
■ previous_notes_sources filter
Filter by condition
■ previous_notes_source_names pluck
Extract source from each item
■ previous_notes_count count
Count items in previous notes sources
■ has_previous_notes compare
Check if previous notes count is greater than 0
■ previous_notes_source join
Join items with " + "
■ has_upcoming_brief compare
Check if setting upcoming brief has data
◆ upcoming_brief_markdown recued-core.docling.document.to_markdown
To markdown document on docling
skip: step.has_upcoming_brief equal false
■ upcoming_brief_ref default
Apply default
✦ upcoming_brief_extract core.ai.extract
AI extracts structured fields from data
skip: step.has_upcoming_brief equal false
■ upcoming_brief_context default
Apply default
■ booking_metadata default
Apply default
■ metadata_project_text default
Apply default
■ has_metadata_projects compare
Check if metadata project text has data
■ metadata_project_split split
Split metadata project text into parts
■ metadata_project_refs ternary
Apply ternary
■ resolved_project_refs ternary
Apply ternary
■ project_selection_source switch
Map has config projects to one of: true
■ requested_project_refs_unique unique
Remove duplicates from
■ requested_project_count count
Count items in requested project refs unique
⚠ requested_project_guard guard
Stop if requested project refs unique is empty
■ requested_project_refs slice
Take a subset of
■ capped_project_count count
Count items in requested project refs
■ project_cap_omissions math
Calculate: {{step.requested_project_count}} - {{step.capped_project_count}}
◆ project_reads core.work-entity.get
Get work entity
■ found_project_reads filter
Filter by condition
■ candidate_projects map
Extract from each item
■ found_project_refs pluck
Extract id from each item
■ missing_project_reads filter
Filter by condition
■ missing_project_refs pluck
Extract item from each item
◆ federation_reads recued-core.federated-projects.federation.search
Search federation on federated projects
■ federation_groups map
Extract from each item
■ federations flatten
Flatten nested lists in
■ federated_project_refs_raw pluck
Extract project_ref from each item
■ federated_project_refs unique
Remove duplicates from
◆ participant_reads recued-core.federated-projects.participant.search
Search participant on federated projects
■ participant_groups map
Extract from each item
■ participants_raw flatten
Flatten nested lists in
■ participant_page_rows map
Extract from each item
■ truncated_participant_pages filter
Filter by condition
■ truncated_participant_project_refs pluck
Extract project_id from each item
■ participant_index_raw map
Extract from each item
■ participant_index_trimmed map
Extract email from each item
■ participant_index map
Extract email_trimmed from each item
■ matched_participants filter
Filter by condition
■ participant_match_rows map
Extract from each item
■ participant_match_groups group_by
Group by pair_key
■ exact_participant_match_groups filter
Filter by condition
■ exact_participant_match_keys pluck
Extract pair_key from each item
■ exact_participant_matches filter
Filter by condition
■ eligible_federated_project_refs_raw pluck
Extract project_id from each item
■ eligible_federated_project_refs unique
Remove duplicates from
■ eligible_projects filter
Filter by condition
■ eligible_projects_with_updated_at map
Extract updated_at from each item
■ eligible_projects_timestamped map
Extract last_activity_at from each item
■ eligible_project_refs pluck
Extract id from each item
■ unshared_prepared_projects filter
Filter by condition
■ unshared_prepared_project_refs pluck
Extract id from each item
■ omitted_federated_projects filter
Filter by condition
■ omitted_federated_project_refs pluck
Extract id from each item
◆ task_reads core.work-entity.list
List work entity
■ task_groups map
Extract from each item
■ candidate_tasks flatten
Flatten nested lists in
■ overdue_day date_format
Format as a date
■ overdue_day_iso template
Generate text from a template
■ overdue_day_ms date_parse
Parse overdue day iso as a date
■ task_due_day_rows map
Extract from each item
■ task_due_day_iso map
Extract at from each item
■ task_due_day_is_day map
Extract iso from each item
■ task_due_day_date map
Extract iso from each item
■ task_due_day_time map
Extract at from each item
■ task_due_day_values map
Extract from each item
■ task_due_day_local map
Extract at from each item
■ task_due_day_calendar map
Extract from each item
■ task_due_day_calendar_iso map
Extract from each item
■ task_due_day_calendar_ms map
Extract calendar_iso from each item
■ task_due_day_has map
Extract at from each item
■ task_due_day_before map
Extract calendar_ms from each item
■ task_due_day_same map
Extract calendar_ms from each item
■ task_due_days map
Extract from each item
■ candidate_tasks_dated enrich_by
Apply enrich_by
■ candidate_tasks_timestamped map
Extract updated_at from each item
■ task_totals pluck
Extract result.total from each item
■ task_total reduce
Reduce with sum
■ task_fetched_count count
Count items in candidate tasks
■ task_page_omissions math
Calculate: {{step.task_total}} - {{step.task_fetched_count}}
■ recent_tasks filter
Filter by condition
■ recent_projects filter
Filter by condition
◆ commitment_reads core.work-entity.list
List work entity
skip: step.eligible_project_refs is_empty
■ commitment_rows default
Apply default
■ promise_day_rows map
Extract from each item
■ promise_day_iso map
Extract at from each item
■ promise_day_is_day map
Extract iso from each item
■ promise_day_date map
Extract iso from each item
■ promise_day_time map
Extract at from each item
■ promise_day_values map
Extract from each item
■ promise_day_local map
Extract at from each item
■ promise_day_calendar map
Extract from each item
■ promise_day_calendar_iso map
Extract from each item
■ promise_day_calendar_ms map
Extract calendar_iso from each item
■ promise_day_has map
Extract at from each item
■ promise_day_before map
Extract calendar_ms from each item
■ promise_day_same map
Extract calendar_ms from each item
■ promise_days map
Extract from each item
■ commitment_rows_dated enrich_by
Apply enrich_by
■ commitment_index map
Extract from each item
■ open_commitments filter
Filter by condition
■ open_commitment_count count
Count items in open commitments
■ recent_task_count count
Count items in recent tasks
■ recent_project_count count
Count items in recent projects
■ eligible_project_count count
Count items in eligible projects
■ meeting_person_count count
Count items in meeting emails
■ coverage_and_omissions default
Apply default
■ participant_display_names_raw pluck
Extract display_name from each item
■ people_names_raw flatten
Flatten nested lists in
■ people_names unique
Remove duplicates from
■ context_pii_protect pii-protect
Apply pii-protect
■ booking_intake_prompt_json json_stringify
Apply json_stringify
■ previous_notes_json json_stringify
Apply json_stringify
■ upcoming_brief_json json_stringify
Apply json_stringify
■ projects_json json_stringify
Apply json_stringify
■ recent_projects_json json_stringify
Apply json_stringify
■ tasks_json json_stringify
Apply json_stringify
■ recent_tasks_json json_stringify
Apply json_stringify
■ participant_matches_json json_stringify
Apply json_stringify
■ open_commitments_json json_stringify
Apply json_stringify
■ coverage_json json_stringify
Apply json_stringify
■ meeting_start_for_model default
Apply default
✦ synthesize_project_context core.ai.extract
AI extracts structured fields from data
■ context_pii_restore pii-restore
Apply pii-restore
■ prepared_from_progress default
Apply default
■ unresolved_since_previous_meeting default
Apply default
■ decisions_needed default
Apply default
■ optional_new_brief_context default
Apply default
■ booking_month date_format
Format as a date
■ sweep_prepared all
Check if all conditions are true
◆ prepared_mark_write core.storage.shared.write
Write storage shared
skip: step.sweep_prepared equal false
■ booking_start_text date_format
Format as a date
■ changed_tasks_table to_table
Format results as a data table
■ card to_summary
Format results as a summary card
▼
Output
summary card
text prepared_from_progress
json unresolved_since_previous_meeting
json decisions_needed
text optional_new_brief_context
json coverage_and_omissions
table changed_tasks_table
Settings 9 configurable

Configurable at install. Defaults shown — change them anytime in Recued.

booking uid setting =
project refs setting =
previous notes setting = [object Object]
upcoming brief setting = [object Object]
lead time minutes setting = 120
prep state prefix setting = recipe.meeting-prep-calcom
previous meeting at setting =
previous booking uid setting =
previous meeting mode setting = auto

Uses (13 operations)

Pack operation Search booking on calcom recued-core.calcom.booking.search
Shared store List storage shared core.storage.shared.list
Pack operation Read booking on calcom recued-core.calcom.booking.read
Pack operation Search booking attendee on calcom recued-core.calcom.booking.attendee.search
Pack operation To markdown document on docling recued-core.docling.document.to_markdown
AI models AI extracts structured fields from data core.ai.extract
Pack operation Search booking transcript on calcom recued-core.calcom.booking.transcript.search
Pack operation Get text http on curl recued-core.curl.http.get_text
Tasks & notes Get work entity core.work-entity.get
Pack operation Search federation on federated projects recued-core.federated-projects.federation.search
Pack operation Search participant on federated projects recued-core.federated-projects.participant.search
Tasks & notes List work entity core.work-entity.list
Shared store Write storage shared core.storage.shared.write

Trust & control

What installing this recipe would let it do. Recued grants these permissions at install — review them there before approving.

What it's allowed to do

Read Shared store core.storage.shared.list read-only
Read AI models core.ai.extract read-only
Read Tasks & notes core.work-entity.get read-only
Read Tasks & notes core.work-entity.list read-only
Write Shared store core.storage.shared.write external change

8 more aren't listed here. You'll see them at install.

Data it touches

SurfacesShared storeAI modelsTasks & notes
Warehousedata.shared

About

Tags

pack:meeting-prep-project-context-calcommeeting-prepproject-contextproject-managementfederated-projectcalcomdoclingai_surfaceread-onlytransient

Details

251 steps 9 configurable settings recipe_id: prepare-project-context-calcom