Сотрудник, форма и бот могут почти одновременно проверить один интервал и увидеть его свободным. Если каждый канал после этого создаст событие, клиентам подтвердят одно и то же время. Поэтому защита строится не вокруг единственной проверки доступности, а вокруг всего участка от выбора времени до подтверждения фактического события.
Руководителю нужно заранее определить источник достоверного расписания, единицу бронирования, момент повторной проверки, правила резерва и действия при неопределённом результате. Наличие календарных операций в инструменте автоматизации само по себе эту задачу не решает.
Почему проверка свободного времени не гарантирует запись
Проверка отвечает только на вопрос о состоянии календаря в момент чтения. Сразу после неё другой сотрудник или процесс может занять тот же интервал.
Например, запросы A и B читают расписание в 10:00:00 и оба видят свободное время с 15:00 до 16:00. Запрос A создаёт событие в 10:00:02. Если запрос B опирается только на первое чтение, он тоже попытается создать событие.
Документация узла Google Calendar в n8n подтверждает операции Availability и работу с событиями: Create, Delete, Get, Get Many и Update. Она не подтверждает, что последовательность «проверить доступность — создать событие» выполняется атомарно, содержит временный резерв или автоматически защищает от параллельных запросов. Безопасный порядок нужно проектировать и испытывать отдельно.
Определить источник достоверного расписания и единицу бронирования
Сначала зафиксируйте, где находится окончательное состояние занятости. Это может быть один календарь, несколько календарей по явному правилу объединения или другая система, с которой сверяется Google Calendar. Не назначайте календарь источником истины только потому, что в нём создаётся итоговое событие.
Для каждой записи опишите:
- ресурс: сотрудник, кабинет, оборудование или их сочетание;
- календарь или набор календарей, определяющих занятость;
- часовой пояс;
- начало, конец и длительность услуги;
- буферы до и после встречи;
- рабочие исключения;
- виды событий, которые блокируют интервал.
Если консультации двух специалистов проходят в одном кабинете, свободный календарь одного специалиста ещё не означает, что доступен кабинет. Правило должно проверять всё сочетание ресурсов, которое требуется для записи.

Разберём ваш рабочий пример и покажем согласованный фрагмент решения до договора и предоплаты.
Разделить подбор времени, резерв и подтверждённую запись
Показанный клиенту интервал ещё не зарезервирован. Отправленная команда создания ещё не означает, что событие появилось и связано с заявкой. Разделите эти этапы на состояния.
| Состояние | Что оно означает | Следующее действие |
|---|---|---|
| Кандидат | Интервал подошёл по предварительной проверке | Получить подтверждение клиента |
| Временно зарезервировано | Система удерживает ресурс по проектному правилу | Повторно проверить календарь |
| Создаётся событие | Команда отправлена, итог ещё не подтверждён | Сверить фактический результат |
| Подтверждено | Найдено созданное событие и сохранён его ID | Сообщить результат клиенту |
| Конфликт | Интервал занят или правила расходятся | Предложить варианты или привлечь сотрудника |
| Требуется ручная проверка | Исход операции неизвестен либо данные противоречат друг другу | Передать карточку исключения |
| Отменено | Запрос закрыт без подтверждённой записи | Освободить резерв по правилам |
- Состояние
- Кандидат
- Что оно означает
- Интервал подошёл по предварительной проверке
- Следующее действие
- Получить подтверждение клиента
- Состояние
- Временно зарезервировано
- Что оно означает
- Система удерживает ресурс по проектному правилу
- Следующее действие
- Повторно проверить календарь
- Состояние
- Создаётся событие
- Что оно означает
- Команда отправлена, итог ещё не подтверждён
- Следующее действие
- Сверить фактический результат
- Состояние
- Подтверждено
- Что оно означает
- Найдено созданное событие и сохранён его ID
- Следующее действие
- Сообщить результат клиенту
- Состояние
- Конфликт
- Что оно означает
- Интервал занят или правила расходятся
- Следующее действие
- Предложить варианты или привлечь сотрудника
- Состояние
- Требуется ручная проверка
- Что оно означает
- Исход операции неизвестен либо данные противоречат друг другу
- Следующее действие
- Передать карточку исключения
- Состояние
- Отменено
- Что оно означает
- Запрос закрыт без подтверждённой записи
- Следующее действие
- Освободить резерв по правилам
Временный резерв — требование к архитектуре будущего решения, а не подтверждённая функция Google Calendar или n8n. Для него задайте владельца, идентификатор бронирования, время создания, условие освобождения и способ сверки с календарём. Универсального срока резерва нет: его выбирают с учётом диалога, нагрузки и последствий слишком раннего или позднего освобождения.
Повторно проверить интервал непосредственно перед созданием события
После того как клиент подтвердил данные, система должна снова прочитать актуальную занятость. Затем она сопоставляет найденные события с ресурсом и внутренним резервом. Только после этого можно переходить к созданию события.
Последовательность требований выглядит так:
- Принять подтверждённые данные и идентификатор бронирования.
- Заново прочитать занятость нужных календарей.
- Проверить ресурс, границы интервала, буферы и резерв.
- При свободном интервале отправить команду создания.
- Получить или найти событие и сохранить его ID.
- Только после сверки перевести запрос в состояние «подтверждено».
Между повторным чтением и созданием события всё равно может остаться окно конкуренции. Документация n8n не доказывает атомарность этих двух операций. Поэтому проект должен либо исключать параллельное владение одним ресурсом выбранным механизмом согласования, либо обнаруживать конфликт и переводить его в безопасное состояние. При конфликте автоматизация не должна удалять чужое событие или молча выбирать другое время.
Защитить процесс от повторного запроса
Назначьте бронированию устойчивый идентификатор при первом входящем обращении и сохраняйте его до конечного результата. По нему система отличит повторную доставку того же запроса от новой записи того же клиента.
Перед созданием события процесс должен проверить:
- есть ли уже подтверждённая операция с таким идентификатором;
- сохранён ли связанный ID события;
- существует ли это событие в календаре;
- осталась ли незавершённая попытка с неизвестным исходом.
Если команда создания могла выполниться, но ответ потерялся, нельзя сразу отправлять её повторно. Сначала нужно сверить календарь по сохранённому идентификатору и другим согласованным признакам. Встроенная идемпотентность здесь не предполагается: способ записи и поиска идентификатора нужно определить в проекте.
Обрабатывать ручные изменения и события календаря
Сотрудник может вручную создать, изменить или удалить событие после того, как автоматизация прочитала расписание. Процесс должен учитывать такие изменения и не считать первоначальное чтение вечным подтверждением занятости.
В Google Apps Script устанавливаемый календарный триггер запускается, когда события в календаре пользователя создаются, изменяются или удаляются. Это сигнал об обновлении календаря, а не готовое разрешение конфликта и не доказательство того, какое именно событие изменилось. После сигнала системе всё равно нужна сверка состояния.
Такой триггер выполняется от имени аккаунта, который его создал. Поэтому рабочую учётную запись, права на календари и полномочия на последующие действия согласуют отдельно.
Есть ещё одно ограничение: согласно документации Apps Script, выполнение скриптов и API-запросы обычно не запускают устанавливаемые триггеры. В документации отдельно указано исключение для Form.submitGrades(). Нельзя строить восстановление календарной записи на предположении, что любой программный запрос обязательно вызовет триггер; маршрут проверяют для выбранного способа интеграции.
Передать неразрешимый конфликт сотруднику
Автоматизация должна остановиться, если безопасное решение требует полномочий человека или состояние нельзя достоверно определить. Карточка исключения помогает сотруднику продолжить работу без повторного сбора контекста.
В карточке сохраните:
- исходную заявку;
- запрошенный интервал и ресурс;
- найденные пересечения;
- состояние и срок резерва;
- историю попыток;
- идентификатор бронирования;
- ID и внутреннюю ссылку на связанное событие, если оно найдено;
- причину передачи сотруднику.
Сотруднику можно дать ограниченный набор решений: предложить другое время, подтвердить допустимое исключение при наличии полномочий, отменить запрос или продолжить после исправления данных. Удаление и перенос существующих событий требуют отдельного правила и соответствующих прав.
Учебный пример: две заявки на один интервал
Ниже — синтетический пример для обсуждения требований. Это не клиентский кейс Switch On AI и не результат выполненного теста.
Запросы A и B почти одновременно выбирают один ресурс и интервал с 15:00 до 16:00. Предварительная проверка обоих запросов показывает свободное время.
| Шаг | Запрос A | Запрос B |
|---|---|---|
| Первичное чтение | Интервал свободен | Интервал свободен |
| Идентификатор | Получает booking-A | Получает booking-B |
| Повторная проверка | Пересечений нет | Обнаружено событие A |
| Действие | Отправляет команду создания | Не создаёт второе событие |
| Подтверждение | Сохраняет ID события и статус | Получает статус «конфликт» |
| Продолжение | Клиенту подтверждают запись | Клиенту предлагают варианты или подключают сотрудника |
- Шаг
- Первичное чтение
- Запрос A
- Интервал свободен
- Запрос B
- Интервал свободен
- Шаг
- Идентификатор
- Запрос A
- Получает
booking-A - Запрос B
- Получает
booking-B
- Шаг
- Повторная проверка
- Запрос A
- Пересечений нет
- Запрос B
- Обнаружено событие A
- Шаг
- Действие
- Запрос A
- Отправляет команду создания
- Запрос B
- Не создаёт второе событие
- Шаг
- Подтверждение
- Запрос A
- Сохраняет ID события и статус
- Запрос B
- Получает статус «конфликт»
- Шаг
- Продолжение
- Запрос A
- Клиенту подтверждают запись
- Запрос B
- Клиенту предлагают варианты или подключают сотрудника
Если запрос A доставят повторно с идентификатором booking-A, процесс сначала найдёт подтверждённую операцию и связанное событие. Ожидаемое поведение — вернуть сохранённый результат, а не создать ещё одно событие.
Пример показывает проектный порядок. Он не доказывает наличие временного резерва, атомарной проверки или встроенной защиты от дублей в Google Calendar либо n8n.
Проверить обычный путь, конкуренцию и восстановление
Приёмка должна проверять состояние заявки, календаря, резерва и уведомления сотруднику, а не только успешное завершение workflow.
| Сценарий | Ожидаемый результат |
|---|---|
| Интервал свободен | Создано одно событие, сохранён его ID, заявка подтверждена |
| Две параллельные заявки на ресурс | Не появляются две пересекающиеся подтверждённые записи; проигравший запрос получает конфликт |
| Повтор одного запроса | По одному идентификатору не создаётся второе событие |
| Между проверками создано ручное событие | Повторная проверка обнаруживает занятость и останавливает создание |
| Ошибка после команды создания | Система сначала сверяет календарь, а не повторяет команду вслепую |
| Календарь недоступен | Нет ложного подтверждения; запрос сохраняет определённое состояние или передаётся сотруднику |
| Подтверждённое событие изменили или удалили | Процесс обнаруживает расхождение предусмотренным способом и создаёт задачу на сверку |
- Сценарий
- Интервал свободен
- Ожидаемый результат
- Создано одно событие, сохранён его ID, заявка подтверждена
- Сценарий
- Две параллельные заявки на ресурс
- Ожидаемый результат
- Не появляются две пересекающиеся подтверждённые записи; проигравший запрос получает конфликт
- Сценарий
- Повтор одного запроса
- Ожидаемый результат
- По одному идентификатору не создаётся второе событие
- Сценарий
- Между проверками создано ручное событие
- Ожидаемый результат
- Повторная проверка обнаруживает занятость и останавливает создание
- Сценарий
- Ошибка после команды создания
- Ожидаемый результат
- Система сначала сверяет календарь, а не повторяет команду вслепую
- Сценарий
- Календарь недоступен
- Ожидаемый результат
- Нет ложного подтверждения; запрос сохраняет определённое состояние или передаётся сотруднику
- Сценарий
- Подтверждённое событие изменили или удалили
- Ожидаемый результат
- Процесс обнаруживает расхождение предусмотренным способом и создаёт задачу на сверку
Для каждого сценария заранее запишите входные данные, ожидаемые переходы состояний и признаки успеха. Число примеров зависит от каналов записи, ресурсов и последствий ошибки. Если в решении применяются триггеры Apps Script, отдельно проверьте, какие ручные и программные изменения действительно запускают выбранный маршрут.
Ограничения решения и данные для обсуждения внедрения
Эта схема не обещает абсолютного отсутствия конфликтов, универсального срока резерва или совместимости с любой конфигурацией. Реализация зависит от числа календарей и ресурсов, каналов записи, прав Google Workspace, места хранения состояния, способа запуска и допустимого ручного вмешательства.
Для обсуждения проекта подготовьте:
- схему текущей записи от обращения до подтверждения;
- список календарей, ресурсов и каналов;
- примеры событий и заявок без персональных данных;
- правила занятости, длительности и буферов;
- роли сотрудников и доступные права;
- последствия ошибочной или повторной записи;
- действия, которые автоматизация вправе выполнять без человека.
Switch On AI разрабатывает и внедряет автоматизацию конкретных операций. На первом разборе можно определить точки конкурентного доступа и состав требований, затем согласовать бесплатный прототип ключевого сценария. Прототип помогает сверить понимание задачи, но не равен полноценному внедрению. Состав работ, стоимость, права доступа, эксплуатационные расходы и сопровождение согласуются отдельно. Чтобы обсудить процесс, пришлите его схему и перечень систем.
Вопросы по этой задаче
Можно ли избежать двойной записи одной проверкой доступности?
Нет. Между чтением расписания и созданием события другой запрос может занять тот же интервал. Нужны повторная проверка перед записью и согласованная обработка оставшегося окна конкуренции.
Достаточно ли операции Availability в n8n?
Она позволяет проверить доступность календаря, но документация не подтверждает атомарность связки проверки и создания события или готовую защиту от параллельных запросов.
Зачем нужен устойчивый идентификатор бронирования?
Он помогает отличить повтор того же запроса от новой записи, найти уже созданное событие и не повторять команду создания вслепую.
Где хранить временный резерв?
В хранилище, доступном всем каналам записи и поддерживающем согласованный жизненный цикл резерва. Конкретный вариант выбирают после определения источника истины, прав, нагрузки и требований к восстановлению.
Что делать, если событие могло создаться, но автоматизация получила ошибку?
Не отправлять команду создания повторно сразу. Сначала сверить календарь по идентификатору бронирования и другим согласованным признакам, затем подтвердить результат или передать неопределённость сотруднику.
