Перейти к содержанию

Интеграция Google Calendar и n8n: встречи без дублей и ошибок timezone

Обновлено: 2026-05-30

AI summary: Problem/Solution-гайд по Google Calendar и n8n: как проверять занятость, создавать встречи без дублей, учитывать timezone и не отправлять лишние приглашения клиентам.
Готовый blueprint для внедрения

Импортируйте JSON в n8n, замените credentials, IDs, правила доступа и production-политики под вашу инфраструктуру.

Проблема: автоматическая запись на встречу через Google Calendar кажется простой, пока workflow не создаёт два event, не путает часовой пояс клиента и не отправляет лишнее приглашение всем участникам.

Решение: интеграция Google Calendar и n8n должна сначала нормализовать входной слот, проверить freeBusy, посчитать idempotency key, найти уже созданный event и только потом создавать или обновлять встречу. Такой подход закрывает не демонстрационный happy path, а реальную production-боль: повторы, права доступа, пустые поля, API-ошибки и ручной контроль там, где автоматизация может навредить.

Схема интеграции Google Calendar и n8n для бронирования встречи без дублей
Схема показывает путь события через n8n: нормализация, проверка, действие во внешнем сервисе и audit/alert.

Проблема: почему простая связка ломает процесс

Интеграция нужна не ради факта подключения сервиса к n8n. Пользователь ищет конкретный ответ: как настроить сценарий так, чтобы данные не дублировались, права не были избыточными, а результат можно было проверить без ручного расследования execution logs.

Для этой страницы основной объект — calendar event. Входной контракт должен явно фиксировать lead_id, calendar_id, start, end, timezone, attendees. Если эти поля приходят нестабильно, автоматизация начинает угадывать, а угадывание в production почти всегда превращается в дубли, потерю данных или лишние уведомления.

Поэтому workflow строится вокруг детерминированных проверок: сначала validation и idempotency, потом запрос к API, потом запись результата и только после этого уведомление человека или downstream-системы.

Архитектура workflow для n8n

БлокЗадачаProduction-проверка
Webhook / CRM triggerпринимает слот от формы, CRM или booking-виджетаесть lead_id и timezone
Normalize eventпроверяет start/end, attendees и policyISO datetime с offset, end > start
Idempotency lookupищет созданный event по ключуevent_id хранится в CRM/Postgres
Google Calendar freeBusyпроверяет занятость календаряне бронируем занятый слот
Create or update eventсоздаёт или обновляет встречуконтролируем sendUpdates и Meet
Respond + auditвозвращает status и event_idесть execution_id и причина отказа

Такой workflow удобно сопровождать: каждая нода отвечает за один слой ответственности, а не смешивает mapping, API-запрос, retry и уведомления в одном Code Node.

Контракт входных данных

{
  "lead_id": "lead-4812",
  "calendar_id": "sales@example.com",
  "title": "Demo call: Acme / n8n",
  "start": "2026-06-02T10:00:00+03:00",
  "end": "2026-06-02T10:45:00+03:00",
  "timezone": "Europe/Moscow",
  "attendees": [
    "client@example.com",
    "manager@example.com"
  ],
  "source": "tilda",
  "send_updates": "all"
}

Payload можно расширять, но нельзя делать обязательные поля “по настроению”. Если источник не передал внешний ID, timezone, владельца или другой ключевой атрибут, workflow должен остановиться с понятной ошибкой до записи во внешний сервис.

Code Node: нормализация, mapping и guard-условия

const src = $json.body ?? $json;
const required = ['lead_id', 'calendar_id', 'start', 'end', 'timezone'];
for (const key of required) {
  if (!src[key]) throw new Error(`Missing ${key} for Calendar booking`);
}
const start = new Date(src.start);
const end = new Date(src.end);
if (Number.isNaN(start.getTime()) || Number.isNaN(end.getTime())) {
  throw new Error('Invalid ISO datetime for Google Calendar event');
}
if (end <= start) throw new Error('Event end must be after start');
const attendees = Array.isArray(src.attendees) ? src.attendees.filter(Boolean) : [];
const idempotencyKey = `calendar:${src.calendar_id}:${src.lead_id}:${start.toISOString()}`;
return [{
  json: {
    action: 'check_freebusy_then_upsert_event',
    idempotency_key: idempotencyKey,
    calendar_id: src.calendar_id,
    event: {
      summary: String(src.title ?? 'Встреча').trim(),
      start: { dateTime: src.start, timeZone: src.timezone },
      end: { dateTime: src.end, timeZone: src.timezone },
      attendees: attendees.map(email => ({ email })),
      description: `Source=${src.source ?? 'n8n'}; lead_id=${src.lead_id}; key=${idempotencyKey}`
    },
    send_updates: src.send_updates ?? 'all'
  }
}];

Этот скрипт n8n не заменяет бизнес-логику внешнего сервиса. Его задача — привести данные к стабильному контракту, сформировать idempotency key и не пропустить опасный payload дальше по цепочке.

Готовый workflow JSON: скачать и импортировать

В архиве страницы есть импортируемый workflow JSON и тестовый payload. После импорта замените credentials, URL, IDs, папки, владельцев, лимиты и правила доступа. Не запускайте сценарий на production-данных, пока не проверены повторы, пустые значения и ошибки API.

{
  "name": "Nodbot - Google Calendar booking with freeBusy and idempotency",
  "nodes": [
    {
      "name": "Webhook / CRM trigger",
      "type": "n8n-node",
      "purpose": "принимает слот от формы, CRM или booking-виджета"
    },
    {
      "name": "Normalize event",
      "type": "n8n-node",
      "purpose": "проверяет start/end, attendees и policy"
    },
    {
      "name": "Idempotency lookup",
      "type": "n8n-node",
      "purpose": "ищет созданный event по ключу"
    },
    {
      "name": "Google Calendar freeBusy",
      "type": "n8n-node",
      "purpose": "проверяет занятость календаря"
    },
    {
      "name": "Create or update event",
      "type": "n8n-node",
      "purpose": "создаёт или обновляет встречу"
    },
    {
      "name": "Respond + audit",
      "type": "n8n-node",
      "purpose": "возвращает status и event_id"
    }
  ],
  "connections": "Webhook / CRM trigger → Normalize event → Idempotency lookup → Google Calendar freeBusy → Create or update event → Respond + audit"
}
Скачать и проверить: используйте кнопки в начале статьи, затем прогоните curl и сравните результат с audit-log.

Пошаговая настройка связки

  1. Создайте отдельный календарь или process calendar для продаж/записей, а не пишите сразу в личные календари менеджеров.
  2. Подключите Google Calendar credential в n8n и ограничьте доступ только нужными календарями.
  3. Перед созданием event добавьте freeBusy-проверку и ветку отказа, если слот занят.
  4. Сохраняйте Google event_id обратно в CRM, Postgres или таблицу mapping, чтобы повторный запуск обновлял встречу.
  5. В тестах отключите реальные приглашения или используйте test attendees, чтобы не отправить клиентам мусорные invite.
Что проверить после импорта workflow

Откройте каждую ноду, замените credentials и IDs, включите dry-run там, где доступно, затем выполните сценарий на тестовом объекте. Для write-действий добавьте отдельный флаг approval или manual step.

Тесты перед production

Минимальный smoke test:

curl -X POST "https://YOUR-N8N-DOMAIN/webhook/google-calendar-booking-n8n" -H "Content-Type: application/json" --data @integration-google-calendar-n8n-booking-payload.json
  1. тот же lead_id и slot повторно
  2. занятый слот в календаре
  3. другой timezone клиента
  4. пустой attendees
  5. ошибка OAuth или invalid calendar_id

Отдельно проверьте, что retry n8n не создаёт второй объект во внешнем сервисе. Для критичных действий используйте durable storage: Postgres, CRM custom field, Google Sheet mapping или другой слой с уникальным ключом.

Production-риски

  • Не сохраняется event_id — retry создаёт дубль встречи.
  • Timezone берётся из сервера n8n, а не из входного контракта.
  • sendUpdates включён в тестах и отправляет клиентам лишние приглашения.
  • AI выбирает время без deterministic freeBusy-проверки.
  • Recurring event изменяется целиком вместо одного instance.
Карточка результата Google Calendar event с event_id, timezone и status
Визуальный блок результата помогает быстро понять, что именно должно появиться после успешного запуска.

Внутренняя перелинковка помогает быстро перейти от общего integration-гайда к готовым workflow, а внешние ссылки ведут на официальную документацию API и n8n-нод.

Критерии готовности

  1. Повторный payload не создаёт второй event.
  2. Занятый слот возвращает понятный отказ или альтернативы.
  3. event_id и idempotency_key сохраняются вне execution data.
  4. Есть отдельные правила для timezone, attendees, Meet и sendUpdates.
  5. Ошибки 401/403/429 уходят в alert или DLQ.
Нужно внедрить без риска? Nodbot может собрать production workflow под вашу инфраструктуру: credentials, mapping, idempotency, тесты, monitoring, LLM-разметка и понятный runbook для команды.