Agentes IA
Comente AGENDA no Instagram @gastaomatos

Agente de Agenda no WhatsApp com Google Calendar

Calendly funciona quando o cliente entra no link. No Brasil, o cliente entra no WhatsApp. O agente conversa, consulta sua agenda em tempo real, oferece horários, marca direto no Google Calendar e ainda manda lembrete 1h antes.

O que esse agente substitui

  • Calendly (cliente precisava sair do WhatsApp pra agendar)
  • Você respondendo "qual o melhor horário pra você?" 20 vezes por dia
  • Cliente esquecendo da reunião porque ninguém lembrou
  • Reagendamento manual quando bate em outro compromisso
  • Confirmação de presença que você sempre esquece de pedir

Stack

  • Node.js 22 + TypeScript
  • Baileys para WhatsApp (sem custo) ou WhatsApp Cloud API (oficial)
  • Google Calendar API com OAuth do seu próprio Gmail
  • Anthropic Claude para conduzir a conversa
  • Postgres (Neon) pra guardar histórico de conversa por número
  • Cron node-cron pra disparar lembretes

Prompt completo para Claude Code

Cole no Claude Code dentro de uma pasta vazia:

prompt
Crie um agente de agendamento no WhatsApp com Google Calendar em Node.js + TypeScript.

Schema (Drizzle + Neon):

conversations (
  id text primary key,
  phone text not null,
  role text not null,  // user | assistant | system
  content text not null,
  created_at timestamp default now()
)

scheduled_meetings (
  id text primary key,
  phone text not null,
  client_name text,
  starts_at timestamp not null,
  ends_at timestamp not null,
  google_event_id text not null,
  status text default 'agendada',  // agendada | confirmada | cancelada | realizada
  reminder_sent boolean default false,
  created_at timestamp default now()
)

Fluxo (loop por mensagem recebida):

1. Baileys recebe mensagem de um número
2. Buscar últimas 20 mensagens dessa conversa no banco
3. Chamar Claude com:

   system = `Você é o agente de agenda da [SUA EMPRESA]. Sua missão é
   marcar uma reunião entre o lead e o [NOME DO RESPONSÁVEL].

   Regras do seu calendário:
   - Atende segunda a sexta
   - Horários disponíveis: 9h às 12h e 14h às 17h (fuso America/Sao_Paulo)
   - Cada reunião dura 30 minutos
   - Mínimo 2 horas de antecedência
   - Máximo 14 dias à frente

   Você tem duas ferramentas:
   1. listar_horarios_disponiveis(data_inicio, data_fim)
      Retorna até 6 horários livres no período.
   2. agendar_reuniao(starts_at, client_name)
      Marca direto no Google Calendar.

   Roteiro:
   - Cumprimenta e pergunta o nome se ainda não souber
   - Pergunta o motivo da reunião em 1 frase
   - Chama listar_horarios_disponiveis e oferece 3 opções
   - Cliente escolhe, você confirma o horário e o nome dele
   - Chama agendar_reuniao
   - Manda confirmação com data, hora, link da call e o que esperar

   Tom: direto, sem 'tudo bem?', sem 'espero te encontrar bem'.`

   messages = histórico das últimas 20 + a mensagem atual
   tools = [listar_horarios_disponiveis, agendar_reuniao]

4. Se Claude pedir tool listar_horarios_disponiveis:
   - Chamar Google Calendar API freebusy.query
   - Cruzar com a janela 9-12 e 14-17 nos dias úteis
   - Filtrar horários que sobram em blocos de 30min
   - Retornar pro Claude

5. Se Claude pedir tool agendar_reuniao:
   - Calendar API events.insert criando o evento com Meet automático
     (conferenceData.createRequest)
   - Salvar em scheduled_meetings com google_event_id
   - Retornar pro Claude o link da call

6. Resposta final do Claude vai pelo Baileys pro cliente

7. Salvar a mensagem do cliente e a resposta no conversations

Cron de lembrete (a cada 5 minutos):
- SELECT meetings WHERE starts_at BETWEEN now() + 55min AND now() + 65min
  AND reminder_sent = false AND status != 'cancelada'
- Pra cada um, enviar pelo Baileys:
  "Lembrete: nossa reunião é em 1 hora, às {hora}. Link: {meet_link}.
   Se não puder, responde aqui que reagendamos."
- Marcar reminder_sent = true

OAuth Google Calendar:
- Setup inicial 1x: console.cloud.google.com cria OAuth client
- Rotina /admin/connect-google: você loga e o agente guarda refresh_token
- Token renovado automaticamente, sem você precisar reconectar

Variáveis de ambiente:
DATABASE_URL
ANTHROPIC_API_KEY
GOOGLE_CLIENT_ID
GOOGLE_CLIENT_SECRET
GOOGLE_REFRESH_TOKEN
GOOGLE_CALENDAR_ID  // pode ser o "primary" ou um calendário específico
BAILEYS_SESSION_PATH

Deploy: Railway com Dockerfile Node 22. Volume pra sessão Baileys.

Estrutura de arquivos:
src/
  baileys/client.ts
  google/calendar.ts       // wrapper Calendar API
  google/auth.ts           // OAuth flow
  ai/agent.ts              // loop de conversa com tools
  workers/reminder.ts      // cron de 1h antes
  routes/admin.ts          // tela pra conectar Google + ver agenda
  db/schema.ts

Como conectar o Google Calendar

  • console.cloud.google.com, novo projeto, ativa Calendar API
  • Cria OAuth client tipo Web Application, redirect URI: https://seu-dominio/auth/google/callback
  • Anota client_id e client_secret nas variáveis de ambiente
  • Roda o agente, abre /admin/connect-google, loga com sua conta Google
  • O agente guarda o refresh_token e nunca mais pede pra você logar

Como ensinar as regras do seu calendário

  • Dias úteis e janela de atendimento (segunda a sexta, 9-12 e 14-17): hardcoded no system prompt
  • Duração da reunião (30, 45 ou 60min): variável de ambiente MEETING_DURATION_MINUTES
  • Antecedência mínima: variável MIN_HOURS_BEFORE (padrão 2)
  • Janela futura máxima: variável MAX_DAYS_AHEAD (padrão 14)
  • Calendários específicos: GOOGLE_CALENDAR_ID = "primary" ou ID do calendário separado

Confirmação e lembrete

  • Logo após marcar: mensagem com data, hora, link do Meet e instruções de como entrar
  • 1h antes: lembrete automático no WhatsApp pelo cron de 5 em 5 minutos
  • Lembrete inclui o link do Meet de novo (sem ter que rolar conversa)
  • Cliente pode responder o lembrete pra cancelar: agente lê resposta com Claude, identifica intent de cancelamento, deleta evento no Google e atualiza status
  • Você recebe notificação no seu número pessoal sempre que uma reunião é marcada ou cancelada

Perguntas frequentes

O agente entende quando o cliente pede "amanhã às 10"?

Entende. O Claude com a tool listar_horarios_disponiveis traduz "amanhã às 10" para uma data no fuso America/Sao_Paulo, consulta o calendário e responde se está livre ou oferece a alternativa mais próxima. Datas relativas funcionam bem em português.

O que acontece se 2 clientes pedirem o mesmo horário ao mesmo tempo?

O Calendar API trata isso com lock interno. O segundo a chamar events.insert no mesmo horário recebe erro de conflito, o agente captura, pede desculpa e oferece outro horário. Na prática, o intervalo entre 2 mensagens é maior que o tempo de criar evento, então o conflito é raríssimo.

Posso usar com o calendário compartilhado da empresa?

Pode. GOOGLE_CALENDAR_ID aceita qualquer calendário que sua conta tenha permissão de escrita. Calendário compartilhado, calendário do recurso (sala, equipamento) ou calendário pessoal mesmo. Você pode rodar múltiplos agentes em paralelo, um por calendário.

O agente funciona com WhatsApp Business API oficial?

Funciona. Basta trocar o canal channels/whatsapp.ts: em vez de Baileys, usar a WhatsApp Cloud API. O fluxo de tools e cron continua igual. Vale pra quem já tem número Business API aprovado e prefere não usar lib não oficial.

Quanto custa rodar o agente por mês?

Railway hobby R$ 25/mês, Neon grátis, Google Calendar API grátis. Anthropic cobra por conversa, aproximadamente R$ 0,05 por agendamento completo (várias trocas de mensagem). Pra 100 reuniões marcadas no mês, total fica em torno de R$ 30.

Quer implementar isso?

Me chama no WhatsApp. Ajudo você a configurar ou implemento pra você.

Quero ajuda no WhatsApp
DT

Gastão Matos

@gastaomatos