Skip to content

Cal.com → Close Handler

Implementation: Zapier Code step (JavaScript)
Code file: data/calcom_zapier_handler.js in the workspace repo
Google Doc (live code): https://docs.google.com/document/d/1GyfBA0ea7nlEHTX2Dr1gSddTFOoECSwNuEUhQxwjZhQ/edit
Trigger: Webhooks by Zapier → Catch Raw Hook (Cal.com sends to this URL)


What It Does

When a brand books, reschedules, or cancels a strategy call on Cal.com, this handler:

  • Finds or creates the Close CRM lead for the booker
  • Logs a 02 - Discovery Call Booked custom activity (which triggers a Close automation to create an opportunity)
  • Posts to #calls-booked Slack channel
  • Marks matching Airtable Inbound Messages records as Responded = true and Has Booked = true

Only fires for events matching "Creator Marketing Strategy Call" — other event types are filtered out.


Event Types Handled

BOOKING_CREATED

The main flow. Runs when a brand books a call.

  1. Extract fields from Cal.com webhook payload:

    • bookerEmail / bookerName — the non-CA attendee
    • hostEmail — which CA agent the call is with (from hosts[0].email in the payload)
    • company, budget, linkedin, phone, notes — from booking form responses
  2. Find or create Close lead:

    • Search by exact email → domain fallback → create new
    • New leads get status = Untested, classified as Brand or Brand Side Agency via Claude Haiku
    • Budget range mapped to Close custom field values
  3. Duplicate guard: If a Discovery Scheduled opp already exists for this lead, posts a Slack alert to #calls-booked but still logs the activity.

  4. Log note: Full booking details written as a note on the Close lead.

  5. Log 02 - Discovery Call Booked activity: This fires a Close automation that creates the Discovery opportunity. Do NOT create the opp directly — that would cause duplicates.

  6. Post to #calls-booked Slack: Company name, booker name/email, call time in agent's timezone, budget emoji.

  7. Mark Airtable: Calls markAirtableBooked(bookerEmail) — finds all Inbound Messages records for this email, sets Responded = true and Has Booked = true on all of them. Fails silently if no match (cold booking, not from inbound flow).

BOOKING_RESCHEDULED

Logs a new 02 - Discovery Call Booked activity with the new time. Does NOT edit the original activity — preserves the audit trail. Does NOT reassign the lead owner.

BOOKING_CANCELLED

Logs a 03 - Discovery Call Not Completed activity with Outcome = Cancelled and the cancellation reason. Does NOT change the opportunity stage — agents handle that manually.


Agent Configuration

The handler maps Cal.com host emails to Close user IDs and Slack user IDs:

AgentCal.com emailClose User ID
Appleapple@creatorsagency.couser_y480mbXf0...
Charliecharlie@creatorsagency.couser_ZStky0Wx...
Annieannie@creatorsagency.couser_eMPAMEyo...
Henryhenry@creatorsagency.couser_CThUkFMt...
Partnershipspartnerships@creatorsagency.co→ Apple

Infrastructure

Old setup (RETIRED Mar 20, 2026): Python script calcom_close_handler.py on Mac Mini, received webhooks via Tailscale Funnel. This was fragile and caused a missed booking (BriteCo). The script has been deleted.

Current setup: Zapier Webhooks by Zapier → Code by Zapier. Fully hosted, no local machines involved.

Cal.com webhook: Configured in Cal.com Settings → Developer → Webhooks. Points to the Zapier catch hook URL. Events: BOOKING_CREATED, BOOKING_RESCHEDULED, BOOKING_CANCELLED.


Airtable Integration

The handler marks Airtable records after a successful booking. This is the "Companion Zap 2" behavior — integrated directly into this handler rather than being a separate Zap.

javascript
// At end of handleCreated():
await markAirtableBooked(bookerEmail);

Searches all Inbound Messages records where email = bookerEmail, patches all matches with Responded = true and Has Booked = true. If no match found (brand came through cold outreach, not inbound), returns 0 silently.

See Responded Detection for full details.