Sync new Cal.com bookings to HubSpot contacts, deals, and tasks
Every time someone books a Cal.com meeting, create or update the HubSpot contact, open a deal, schedule a prep task, and ping Slack.
Build a deterministic code workflow that turns every new Cal.com booking into a clean HubSpot CRM record. No AI judgement is needed: field mapping is fixed and configured at the top of the prompt.
Trigger: poll Cal.com for new bookings (event type new_booking).
Pipeline:
1) Cal.com — Get a Booking using the booking id from the trigger payload. Pull the attendee (name, email, phone, company if present), the event type title and slug, the start and end times, the timezone, the booking title, and any UTM or source fields captured in booking responses or metadata.
2) HubSpot — Search Contacts by the attendee's email (exact match, single result). If a contact is found, reuse its id. If no contact is found, call HubSpot Create Contact with: email, first name, last name, phone, company, lifecyclestage = "lead", and a configurable custom property (default cal_event_type) set to the Cal.com event type slug. Use the resulting contact id downstream.
3) HubSpot — Create Deal in the configured pipeline and stage with: dealname = the Cal.com booking title (fall back to "{Event Type} — {Attendee Name}" if title is empty), amount = a configurable default per event type, closedate = the booking start date plus a configurable offset (default 14 days), and the Cal.com event type stored on a configurable custom deal property (default cal_event_type). Associate the contact from step 2 to this deal inline using the associations array.
4) HubSpot — Create Task with subject "Prep for {Event Type}", due date = booking start time minus 1 hour, priority HIGH, status NOT_STARTED, and assigned to the deal owner. Associate the task to both the contact and the deal.
5) Slack Bot — Send a Message to the configured sales channel with one line: "{Attendee Name} from {Company or attendee email domain} booked {Event Type} for {start time formatted in the booking timezone} — Contact: {hubspot contact url} · Deal: {hubspot deal url}". Use chat:write.public so the bot can post even if it is not yet in the channel.
Configuration block at the top of the workflow (user-editable): hubspot deal pipeline id, hubspot deal stage id, default deal amount (number), close date offset days (number), per-event-type overrides for pipeline/stage/amount (object keyed by event type slug), hubspot contact custom property name for cal event type (string, default cal_event_type), hubspot deal custom property name for cal event type (string, default cal_event_type), prep task lead time minutes (number, default 60), slack channel id.
Idempotency: before creating the deal, search HubSpot deals by the Cal.com booking id stored on a custom deal property (e.g. cal_booking_id). If a deal already exists for that booking id, skip deal and task creation but still send the Slack message tagged with "(already in CRM)". This makes the workflow safe to re-run on the same booking.
Error handling: if HubSpot Search Contacts returns more than one match by email, pick the most recently updated contact and continue. If Create Contact fails with INVALID_EMAIL, post a Slack message describing the failure and stop. Retry HubSpot 429s using the Retry-After header.
Output: the contact id, deal id, task id, and the Slack message ts, so the workflow run is auditable.
Additional information
What does this prompt do?
- Watches Cal.com for every new booking and turns it into a clean CRM record with no manual entry.
- Looks up the attendee in HubSpot by email, creates them as a lead if they are new, and saves the event type on their record.
- Opens a deal in your chosen pipeline with the booking title and an expected close date, and links the contact to the deal.
- Schedules a prep task for the deal owner one hour before the call so the meeting never starts cold.
- Posts a one-line heads-up to your sales channel in Slack with the attendee, company, event type, time, and links to the contact and deal.
What do I need to use this?
- A Cal.com account that owns the event types you want tracked.
- A HubSpot account where you can create contacts, deals, and tasks, with a pipeline you want new bookings to land in.
- A Slack workspace and a channel for sales notifications.
- The names of the HubSpot custom property where the Cal.com event type should be stored, the deal pipeline, and the default deal amount you want to use.
How can I customize it?
- Change the deal pipeline, default amount, lifecycle stage, or expected close date logic to match how your team forecasts.
- Adjust the prep task timing (default is one hour before the booking) or who it gets assigned to.
- Edit the Slack message template, swap channels per event type, or route different bookings to different channels.
Frequently asked questions
What happens if the attendee already exists in HubSpot?
Will this work with HubSpot Free or Starter?
Can I send the booking to a different pipeline based on the event type?
Does this handle reschedules or cancellations?
Where do the Slack message links point?
Stop hand-typing Cal.com bookings into HubSpot.
Connect Cal.com, HubSpot, and Slack once, and Geni files every new booking into your CRM the moment it lands.