BDS0.1

Cal.com Booking Intake

Transforma agendamentos do Cal.com em leads e reuniões no CRM, criando a pessoa no Core quando preciso.

Revisado 2026-11-06Markdown
Plataforma
n8n · Abrir no n8n
Status
Ativo
ID do workflow
QtaJdIPuUy8l6AXn
Nós
32
Versão no n8n
d1323e82-7bd7-4179-b1d9-2c00b8a9f260
Último salvamento no n8n
2026-11-06T21:25:19.572Z
Sistemas
CRMCore

O Cal.com Booking Intake transforma em registros do CRM um agendamento feito no Cal.com pela landing page de um vendedor. Uma reserva nova vira um Deal (o lead) em Meeting Scheduled, ou passa para Meeting Scheduled o Deal aberto da pessoa com aquele vendedor, mais uma Interaction (a reunião) para o vendedor certo, e a pessoa é criada no Core quando ninguém tem aquele e-mail. Um reagendamento move a mesma reunião; um cancelamento ou recusa a marca como cancelada e põe o próximo contato da reunião em hoje. Um único webhook atende a conta do Cal.com de todos os vendedores.

O maintainer do CRM cuida do roteamento por vendedor e da recuperação; o maintainer do Core revisa as pessoas que o workflow cria.

Fluxo

Gerado da versão do n8n do quadro acima: cada caixa é um nó e cada seta é uma ligação no n8n. Pílulas rosa são gatilhos, hexágonos amarelos são nós If e Switch com as saídas nas setas, cilindros azuis leem (Airtable, Data Table, HTTP GET), cilindros verdes gravam, caixas roxas chamam outro workflow e setas tracejadas são saídas de erro.

Cancelamento e recusa

Reagendamento

Reserva nova

Receber e conferir

sim

não

sim

não

sim

não

sim

não

sim

não

sim

não

sim

não

Cal.com Webhook

Sign Body

Verify & Parse

Is New Booking?

Is Reschedule?

Find Duplicate
GET CRM Interaction

Get Lead Sources
GET CRM Lead Source

Find Person (CRM)
GET CRM People

Resolve

Needs Core?

Find Person (Core)
GET Core People

Exists in Core?

Create Person (Core)
POST Core People

Wait 1 min

Recheck Person (CRM)
GET CRM People

Sync Check

Person Ready?

Find Deals
GET CRM Deal

Prepare Deal

Existing Deal?

Update Deal
PATCH CRM Deal

Create Deal
POST CRM Deal

Prepare Interaction

Create Interaction
POST CRM Interaction

Find Original Meeting
GET CRM Interaction

Prepare Reschedule

Original Found?

Move Meeting
PATCH CRM Interaction

Find Booked Meeting
GET CRM Interaction

Prepare Cancellation

Mark Meeting Cancelled
PATCH CRM Interaction

Código Mermaid
flowchart TD
  subgraph g0["Receber e conferir"]
    n0(["Cal.com Webhook"]):::trigger
    n26["Sign Body"]:::logic
    n29["Verify & Parse"]:::logic
    n13{{"Is New Booking?"}}:::decision
    n14{{"Is Reschedule?"}}:::decision
  end
  subgraph g1["Reserva nova"]
    n8[("Find Duplicate<br/><small>GET CRM Interaction</small>")]:::read
    n12[("Get Lead Sources<br/><small>GET CRM Lead Source</small>")]:::read
    n11[("Find Person (CRM)<br/><small>GET CRM People</small>")]:::read
    n25["Resolve"]:::logic
    n17{{"Needs Core?"}}:::decision
    n10[("Find Person (Core)<br/><small>GET Core People</small>")]:::read
    n5{{"Exists in Core?"}}:::decision
    n3[("Create Person (Core)<br/><small>POST Core People</small>")]:::write
    n30["Wait 1 min"]:::wait
    n24[("Recheck Person (CRM)<br/><small>GET CRM People</small>")]:::read
    n27["Sync Check"]:::logic
    n19{{"Person Ready?"}}:::decision
    n7[("Find Deals<br/><small>GET CRM Deal</small>")]:::read
    n21["Prepare Deal"]:::logic
    n4{{"Existing Deal?"}}:::decision
    n28[("Update Deal<br/><small>PATCH CRM Deal</small>")]:::write
    n1[("Create Deal<br/><small>POST CRM Deal</small>")]:::write
    n22["Prepare Interaction"]:::logic
    n2[("Create Interaction<br/><small>POST CRM Interaction</small>")]:::write
  end
  subgraph g2["Reagendamento"]
    n9[("Find Original Meeting<br/><small>GET CRM Interaction</small>")]:::read
    n23["Prepare Reschedule"]:::logic
    n18{{"Original Found?"}}:::decision
    n16[("Move Meeting<br/><small>PATCH CRM Interaction</small>")]:::write
  end
  subgraph g3["Cancelamento e recusa"]
    n6[("Find Booked Meeting<br/><small>GET CRM Interaction</small>")]:::read
    n20["Prepare Cancellation"]:::logic
    n15[("Mark Meeting Cancelled<br/><small>PATCH CRM Interaction</small>")]:::write
  end
  n0 --> n26
  n26 --> n29
  n29 --> n13
  n13 -->|sim| n8
  n13 -->|não| n14
  n14 -->|sim| n9
  n14 -->|não| n6
  n9 --> n23
  n23 --> n18
  n18 -->|sim| n16
  n18 -->|não| n8
  n6 --> n20
  n20 --> n15
  n8 --> n12
  n12 --> n11
  n11 --> n25
  n25 --> n17
  n17 -->|sim| n10
  n17 -->|não| n7
  n10 --> n5
  n5 -->|sim| n30
  n5 -->|não| n3
  n3 --> n30
  n30 --> n24
  n24 --> n27
  n27 --> n19
  n19 -->|sim| n7
  n19 -->|não| n30
  n7 --> n21
  n21 --> n4
  n4 -->|sim| n28
  n4 -->|não| n1
  n1 --> n22
  n22 --> n2
  n28 --> n22
  classDef trigger fill:#fde7f3,stroke:#d6409f,color:#111
  classDef decision fill:#fff7e0,stroke:#c99a00,color:#111
  classDef read fill:#e8f1ff,stroke:#3b82f6,color:#111
  classDef write fill:#e7f8ee,stroke:#16a34a,color:#111
  classDef subflow fill:#f3e8ff,stroke:#9333ea,color:#111
  classDef wait fill:#f1f1f1,stroke:#888,color:#111
  classDef logic fill:#ffffff,stroke:#999,color:#111

Sistemas que ele toca

Sistema Tabela Lê Grava
CRM Interaction Find Duplicate, Find Original Meeting, Find Booked Meeting Create Interaction, Move Meeting, Mark Meeting Cancelled
CRM Deal Find Deals Create Deal, Update Deal
CRM People (mirror de People do Core) Find Person (CRM), Recheck Person (CRM) Nada
CRM Automation: Lead Source Get Lead Sources Nada
Core People Find Person (Core) Create Person (Core)

Toda chamada ao Airtable é um nó HTTP Request com uma credencial de token do Airtable; o workflow não usa o nó Airtable. As leituras filtram pelo nome do campo ({Booking UID}, {Email} no mirror do CRM, {Email*} no Core); as gravações usam IDs de campo. Renomear um desses três campos quebra as buscas sem erro: a fórmula falha e o nó não devolve nada.

Os outros sistemas só registram o workflow. Communication o lista como o canal Webhook cal-com-bookings → n8n → CRM. Systems Central tem uma linha de System para ele. O Login e o Tool Identifier que ele compara são lookups que chegam ao CRM vindos de Tooling and Access pelo mirror Tool Account.

Gatilho e assinatura

O Cal.com Webhook aceita um POST num path fixo. Ele usa o modo de resposta padrão, então o Cal.com recebe HTTP 200 assim que a requisição chega, antes de qualquer conferência ou gravação. Um 200 no log de webhooks do Cal.com só diz que o n8n recebeu a chamada.

O Sign Body calcula o HMAC-SHA256 de JSON.stringify(body) com o segredo do webhook do Cal.com. O Verify & Parse compara o resultado com o header x-cal-signature-256 e lança “Invalid Cal.com signature (x-cal-signature-256)” quando eles diferem ou o header falta. Essa execução termina em erro e não grava nada.

O Verify & Parse só segue para BOOKING_CREATED, BOOKING_RESCHEDULED, BOOKING_CANCELLED e BOOKING_REJECTED. Qualquer outro evento não devolve itens e a execução termina ali.

O que o Verify & Parse lê do payload

Valor De onde vem, nesta ordem Quando falta
Nome e sobrenome responses.name (objeto com firstName/lastName, ou texto separado no primeiro espaço), depois o nome do primeiro participante O nome completo vira “Cal.com lead”
E-mail do lead responses.email, depois o e-mail do primeiro participante; sem espaços e em minúsculas Toda busca por e-mail vira FALSE()
Telefone responses.attendeePhoneNumber, responses.phone, depois o telefone do participante Não é gravado
Notas do lead additionalNotes, responses.notes, depois description Não são gravadas
Chaves da conta do vendedor E-mail, username e id do organizador, mais externalId e primaryEmail de cada calendário de destino; em minúsculas Nenhum vendedor identificado
Início da reunião startTime O horário em que o n8n processou a chamada
Dia da reunião e hoje Data no fuso do organizador Fuso America/Sao_Paulo; um fuso inválido cai na data UTC
Booking UID uid, depois bookingId As buscas de duplicata e de cancelamento viram FALSE()
UID original (reagendamento) rescheduleUid, fromReschedule, depois originalRescheduledBooking.uid A busca do original vira FALSE()
Motivo cancellationReason, depois rejectionReason Não é anexado
URL da reunião metadata.videoCallUrl, videoCallData.url, location quando começa com http, depois https://app.cal.com/booking/<uid> Não é gravada
Título title “Cal.com meeting”

Reserva nova

BOOKING_CREATED passa por estes passos, nesta ordem.

  1. Checagem de duplicata. O Find Duplicate procura qualquer Interaction com o mesmo Booking UID. O Resolve para a execução quando encontra uma.
  2. Roteamento por vendedor. O Get Lead Sources lê Automation: Lead Source. O Resolve pega a primeira linha que está Active, cujo Tool inclui cal.com e cujo Tool Identifier ou Login é igual a uma das chaves da conta do vendedor. O Follow up Target: Person da linha vira a pessoa responsável e o Follow up Target: Company, a empresa responsável. Quando nenhuma linha bate, o fluxo segue sem vendedor.
  3. Pessoa no CRM. O Find Person (CRM) procura o e-mail no mirror People do CRM. Quando acha, o fluxo vai direto para o passo 5.
  4. Pessoa no Core. Sem pessoa no CRM e com e-mail, o Find Person (Core) procura em People do Core. Quando a pessoa também não está lá, o Create Person (Core) a cria com os campos de Campos gravados. Nos dois casos o fluxo então espera o mirror do CRM: Wait 1 min, Recheck Person (CRM), Sync Check. Ele sai do loop quando a pessoa aparece ou depois da décima tentativa, cerca de dez minutos. Sem e-mail, os passos 3 e 4 não acham ninguém e nada é criado no Core.
  5. Deal. O Find Deals lê os Deals ligados à pessoa (o Deals (Counterparty) dela). O Prepare Deal fica com os abertos (Deal Status Open) e reaproveita o primeiro cujo Accountable (Person)* contém a pessoa roteada ou, sem vendedor roteado, o primeiro sem pessoa responsável. O Update Deal passa esse Deal para Meeting Scheduled quando o Deal Stage* é Lead, Contacted ou vazio; um estágio posterior (Meeting Scheduled, Pitched, Proposal Sent, Negotiation) é mantido. Sem correspondência, ou sem pessoa no CRM, o Create Deal cria um Deal novo em Meeting Scheduled.
  6. Interaction. O Create Interaction cria a reunião, ligada a esse Deal em Deal° e à pessoa em People°, com Result Meeting booked. Nenhum Relationship é criado, e o fluxo não preenche Campaign° no Deal.

Reagendamento

BOOKING_RESCHEDULED roda o Find Original Meeting com o UID original. O Prepare Reschedule só aceita uma Interaction cujo Result é Meeting booked.

Quando acha uma, o Move Meeting atualiza essa mesma Interaction: Date*, Title*, Booking UID (agora o UID novo), Next Contact Date° e Next Action°, a Evidence URL quando o payload traz URL da reunião, e uma linha anexada a Note. O Deal não muda, nem Result e Accountable.

Quando não acha nenhuma (o original foi cancelado ou nunca chegou ao CRM), o item vai para o Find Duplicate; veja em Lacunas conhecidas o que acontece ali.

Cancelamento e recusa

BOOKING_CANCELLED e BOOKING_REJECTED rodam o Find Booked Meeting com o UID atual. O Prepare Cancellation escolhe a Interaction cujo Result é Meeting booked. Quando não há nenhuma (já cancelada, ou a reserva nunca chegou ao CRM), a execução termina sem gravar.

O Mark Meeting Cancelled põe Result em Meeting cancelled, Next Contact Date° em hoje, Next Action° em “Meeting cancelled, reach out to rebook” (“rejected” numa recusa) e anexa a Note uma linha com o motivo. É nessa Interaction que o follow-up aparece. O Deal não muda: o Deal Stage* continua em Meeting Scheduled, ou onde estava.

Campos gravados

People do Core (Create Person (Core))

Campo Valor
First Name* Nome, ou o nome completo quando não há nome
Last Name* Sobrenome, só quando existe
Email* E-mail do lead
Telephone* Telefone, só quando existe
Status Proposed
Tags cal-lead-n8n
Notes “Created by n8n from a Cal.com booking (uid …) on <data>.” mais o nome da Lead Source e a conta do Cal.com

Deal do CRM

O workflow não grava nada no Relationship, que foi apagado em 04/11/2026.

Campo Create Deal Update Deal
Deal Stage* Meeting Scheduled Meeting Scheduled quando estava em Lead, Contacted ou vazio; senão, o estágio atual
Source° Inbound Não muda
Notes° Cartão do lead, notas do lead e avisos quando faltam a pessoa ou o vendedor Não muda
Tags cal-lead-n8n Não muda
People° A pessoa do CRM, quando encontrada Não muda
Accountable (Person)* Pessoa roteada, quando encontrada Não muda
Accountable (Company)* Empresa roteada, quando encontrada Não muda

O Company° não é gravado; o vendedor preenche quando souber a empresa do lead.

Interaction do CRM

Campo Create Interaction Move Meeting Mark Meeting Cancelled
Deal° O Deal do passo 5 Não muda Não muda
People° A pessoa do CRM, quando encontrada Não muda Não muda
Date* Início da reunião Novo início Não muda
Title* Título da reunião Novo título Não muda
Type Meeting Não muda Não muda
Result Meeting booked Não muda Meeting cancelled
Note Cartão do lead, notas do lead, local, conta do Cal.com, nome da Lead Source Anexa “Rescheduled via Cal.com on <hoje> from <início antigo>.” Anexa “Meeting cancelled via Cal.com on <hoje>.” e o motivo
Booking UID Booking UID UID novo Não muda
Evidence URL URL da reunião, quando existe Nova URL da reunião, quando existe Não muda
Next Contact Date° Dia da reunião Novo dia da reunião Hoje
Next Action° “Meeting booked via Cal.com: <título>” “Meeting rescheduled via Cal.com: <título>” “Meeting cancelled (ou rejected), reach out to rebook”
Accountable (Person) Pessoa roteada, quando encontrada Não muda Não muda
Accountable (Company) Empresa roteada, quando encontrada Não muda Não muda
Tags cal-lead-n8n Não muda Não muda

O Company° não é gravado. As gravações em Deal, Interaction e People do Core mandam typecast: true, então um valor de select que ainda não existe (um Result ou Deal Stage* renomeado, por exemplo) é criado como opção nova em vez de falhar.

Nós

O workflow tem 32 nós: 31 que executam e uma nota adesiva. Num nó If, a saída 0 é verdadeiro e a saída 1 é falso.

Nó Tipo O que faz
Cal.com Webhook webhook Recebe o POST do Cal.com e responde na hora
Sign Body crypto HMAC-SHA256 do body já parseado com o segredo do Cal.com
Verify & Parse code Confere a assinatura, descarta outros eventos, normaliza a reserva
Is New Booking? if BOOKING_CREATED ou não
Find Duplicate httpRequest Interaction do CRM com o mesmo Booking UID
Get Lead Sources httpRequest Todas as linhas de Automation: Lead Source do CRM (primeira página)
Find Person (CRM) httpRequest Mirror People do CRM pelo e-mail
Resolve code Para em duplicata, identifica o vendedor, prepara a pessoa do Core
Needs Core? if Sem pessoa no CRM e com e-mail
Find Person (Core) httpRequest People do Core pelo e-mail
Exists in Core? if Pessoa do Core encontrada ou não
Create Person (Core) httpRequest POST de uma pessoa Proposed em People do Core
Wait 1 min wait Espera um minuto pela sincronização do mirror
Recheck Person (CRM) httpRequest Mirror People do CRM pelo e-mail de novo
Sync Check code Conta tentativas; termina ao achar ou após 10
Person Ready? if Sai do loop ou espera de novo
Find Deals httpRequest Os Deals do CRM da pessoa
Prepare Deal code Escolhe o Deal aberto do vendedor e o novo estágio, ou monta um Deal novo
Existing Deal? if Atualizar ou criar
Update Deal httpRequest PATCH do Deal Stage* do Deal reaproveitado
Create Deal httpRequest POST de um Deal novo em Meeting Scheduled
Prepare Interaction code Monta a Interaction da reunião
Create Interaction httpRequest POST da Interaction
Is Reschedule? if BOOKING_RESCHEDULED ou cancelamento/recusa
Find Original Meeting httpRequest Interaction do CRM pelo Booking UID original
Prepare Reschedule code Escolhe a Interaction Meeting booked e monta o patch dela
Original Found? if Interaction original em Meeting booked encontrada ou não
Move Meeting httpRequest PATCH na Interaction original
Find Booked Meeting httpRequest Interaction do CRM pelo Booking UID atual
Prepare Cancellation code Escolhe a Interaction Meeting booked e monta o patch dela
Mark Meeting Cancelled httpRequest PATCH na Interaction para Meeting cancelled
Sticky Note stickyNote Nota de configuração no canvas; não executa

Ligações

De Saída Para
Cal.com Webhook 0 Sign Body
Sign Body 0 Verify & Parse
Verify & Parse 0 Is New Booking?
Is New Booking? 0 Find Duplicate
Is New Booking? 1 Is Reschedule?
Find Duplicate 0 Get Lead Sources
Get Lead Sources 0 Find Person (CRM)
Find Person (CRM) 0 Resolve
Resolve 0 Needs Core?
Needs Core? 0 Find Person (Core)
Needs Core? 1 Find Deals
Find Person (Core) 0 Exists in Core?
Exists in Core? 0 Wait 1 min
Exists in Core? 1 Create Person (Core)
Create Person (Core) 0 Wait 1 min
Wait 1 min 0 Recheck Person (CRM)
Recheck Person (CRM) 0 Sync Check
Sync Check 0 Person Ready?
Person Ready? 0 Find Deals
Person Ready? 1 Wait 1 min
Find Deals 0 Prepare Deal
Prepare Deal 0 Existing Deal?
Existing Deal? 0 Update Deal
Existing Deal? 1 Create Deal
Update Deal 0 Prepare Interaction
Create Deal 0 Prepare Interaction
Prepare Interaction 0 Create Interaction
Is Reschedule? 0 Find Original Meeting
Is Reschedule? 1 Find Booked Meeting
Find Original Meeting 0 Prepare Reschedule
Prepare Reschedule 0 Original Found?
Original Found? 0 Move Meeting
Original Found? 1 Find Duplicate
Find Booked Meeting 0 Prepare Cancellation
Prepare Cancellation 0 Mark Meeting Cancelled

Configurações e tratamento de erro

Configuração Valor
Ordem de execução v1
Workflow de erro Nenhum
Retry on fail Desligado em todos os nós
On error Para o workflow (padrão) em todos os nós
Caller policy Workflows do mesmo dono
Disponível no MCP Sim
Retenção dos dados de execução Padrão da instância; este workflow não define

Não há agendamento; o workflow só roda quando o Cal.com o chama. Uma chamada ao Airtable que falha para a execução onde está, depois que as gravações anteriores já foram salvas.

Lacunas conhecidas

Estas vêm da configuração dos nós. A versão com Deal foi publicada em 04/11/2026 e testada só numa simulação local (quatro casos); nenhuma reserva real passou por ela ainda. Na versão anterior, com Relationship, três caminhos rodaram no n8n: uma reserva nova para uma pessoa existente, um reagendamento com o original encontrado e um cancelamento.

Lacuna Efeito
Um reagendamento cujo original não é encontrado chega ao Find Duplicate sem a fórmula de duplicata O Find Duplicate filtra com fórmula vazia, o Airtable devolve a primeira Interaction da tabela e o Resolve para. O reagendamento não grava nada
O segredo do webhook fica nos parâmetros do Sign Body, não numa credencial do n8n Quem abre o workflow consegue ler, e uma exportação do workflow o leva junto
A assinatura é calculada sobre o body já parseado, não sobre a requisição crua Um payload cujo JSON re-serializado difere do que o Cal.com assinou falha como assinatura inválida
O Cal.com recebe 200 antes da conferência da assinatura Uma entrega recusada ou que falhou parece bem-sucedida no Cal.com; só a lista de execuções do n8n mostra o erro
A checagem de duplicata é uma busca, não uma trava Duas entregas da mesma reserva no mesmo instante podem criar registros as duas
Get Lead Sources e Find Deals leem uma página (até 100 registros) Acima de 100 linhas de Lead Source, ou 100 Deals de uma pessoa, uma correspondência pode ser perdida
Uma reserva sem e-mail, ou uma pessoa que ainda não está no mirror depois de dez minutos, cria um Deal sem People° e uma Interaction sem People° A linha de Notes° sempre diz que a pessoa não chegou ao mirror a tempo, mesmo quando a causa é a falta de e-mail. Uma reserva seguinte da mesma pessoa cria outro Deal
Só Deals abertos são reaproveitados Uma reserva de uma pessoa cujo Deal com aquele vendedor está Won, Lost ou Abandoned cria um Deal novo em Meeting Scheduled
O Company° nunca é gravado no Deal nem na Interaction O Name do Deal mostra só a pessoa até o vendedor ligar a empresa

Recuperar uma gravação parcial

Veja o que foi salvo antes de reenviar uma entrega.

O que foi salvo O que fazer
Pessoa criada no Core, mirror do CRM ainda sem ela Espere ou corrija a sincronização, depois ligue a pessoa em People° do Deal novo e da Interaction
Deal gravado, Interaction falhou Procure a Interaction pelo Booking UID antes de reenviar; o reenvio reaproveita o Deal aberto quando ele tem People° e o mesmo vendedor, e cria a Interaction
Dois registros para um Booking UID Fique com um, mova os links dele, depois apague o outro; nada os junta automaticamente

Manter esta página em dia

O quadro no topo mostra a versão do n8n que esta página descreve. Abra o workflow no n8n: quando o último salvamento dele é mais novo que a data do quadro, esta página está desatualizada até a próxima revisão. Todos os nós e todas as ligações dessa versão estão em Nós e Ligações.