n8n: timeout + escalation — как строить согласование, которое не зависает на одном менеджере - Блог Папы Карло

Опубликовано: 4 месяца назад
Просмотров: 83

Привет. Я у себя в мастерской быстро понял одну вещь: согласование в автоматизации ломается не там, где кнопка “Approve”, а там, где один человек ушёл в созвон, забыл открыть чат и утащил процесс в туман. Если коротко, рабочая схема в n8n выглядит так: создаём карточку решения, ставим дедлайн, отправляем запрос на подтверждение, ждём ответ через Wait, а если тишина — поднимаем escalation на следующий уровень. Ниже покажу саму логику, набор узлов, таблицу состояний, антифейлы и чек-лист перед запуском.

Статья пригодится, если вы собираете approval workflow в Telegram, почте, внутреннем кабинете или в связке с CRM. Я буду говорить на примере n8n, но сама механика годится почти для любого бизнес-процесса: скидка менеджеру, согласование закупки, ручной выпуск счёта, подтверждение ответа клиенту, публикация контента и любые действия, где нужен живой человек.

Почему согласование виснет именно на одном менеджере

Самая частая ошибка простая: разработчик собирает красивый сценарий, шлёт сообщение одному руководителю и считает, что дело сделано. А дальше начинается обычная жизнь. Руководитель в дороге, на встрече, в отпуске, уведомление утонуло в чате, а заявка висит со статусом pending и блокирует всё, что идёт ниже по цепочке.

Второй косяк — пытаться держать исходный HTTP-запрос открытым, пока человек не нажмёт кнопку. В n8n это почти всегда плохая идея для длинных согласований. Wait умеет ставить выполнение на паузу и продолжать его потом, а для сценариев с ожиданием по времени, по вебхуку или по форме это как раз тот инструмент, на который и надо опираться. Плюс у Wait есть limit wait time: можно задать верхнюю границу ожидания и не оставлять процесс в подвешенном состоянии.

Третий момент — отсутствие чёткой модели эскалации. Если менеджер №1 не ответил, что делаем дальше? Повторяем пинг? Передаём руководителю группы? Отправляем в общий канал? Делаем автозавершение с пометкой “истёк SLA”? Пока на эти вопросы нет ответа в самой схеме, у вас не approval workflow, а надежда на удачу.

И да, ещё один нюанс. В n8n Wait короче 65 секунд работает как обычная пауза внутри текущего процесса, а длинное ожидание уже уходит в состояние waiting с сохранением данных выполнения. Поэтому для настоящих бизнес-согласований я не строю механику на коротких паузах “ну давай подождём минутку”. Я сразу проектирую нормальный дедлайн и нормальную ветку на случай тишины.

Ноутбук с диаграммой согласования и телефон с уведомлением для менеджера

Как выглядит рабочая схема timeout + escalation в n8n

У меня прижилась вот такая логика. Она скучная, зато крепкая и не устраивает драму на ровном месте.

  1. Приходит событие: новая заявка, заказ, счёт, публикация или ответ клиенту.
  2. Я вычисляю риск и маршрут согласования: кому сначала, сколько ждём, кто второй в цепочке.
  3. Создаю запись в таблице approvals: ID объекта, текущий уровень, дедлайн ответа, канал уведомления, статус.
  4. Отправляю менеджеру сообщение с кнопками или ссылками approve/reject и сшиваю это с execution ID либо approval ID.
  5. Ставлю Wait на ответ по webhook call или на встроенный канал “send and wait for response”, если он подходит под задачу.
  6. Задаю limit wait time. Если ответ пришёл вовремя — пишу решение в журнал и двигаю процесс дальше.
  7. Если ответа нет — workflow сам просыпается по timeout, меняет статус на escalated и шлёт запрос следующему участнику.
  8. После последнего уровня либо принимаю дефолтное решение по правилу, либо отправляю задачу в ручной разбор.

Смысл тут не в одной кнопке, а в том, что каждый шаг имеет дедлайн, владельца и понятный выход. Такую схему легко объяснить команде, легко отлаживать и потом не мучиться вопросом “а где вообще застряло?”.

Состояние Что произошло Что делает сценарий
pending Запрос создан и отправлен первому согласующему Ждёт ответ до дедлайна
approved Кнопка подтверждения нажата Пускает объект дальше по сценарию
rejected Согласующий отклонил действие Останавливает маршрут и пишет причину
timed_out Дедлайн истёк, ответа нет Фиксирует просрочку и запускает escalation
escalated Задача передана следующему уровню Создаёт новый дедлайн и нового владельца
resolved_manually Оператор вмешался руками Закрывает кейс и сохраняет комментарий

Если тема ручного подтверждения вам близка, рядом по смыслу лежит материал про ручное согласование действий ИИ в Telegram. Там хорошо дополняется история, когда approval нужен не только человеку в отделе, но и перед действием ассистента.

Какие узлы я обычно ставлю в таком workflow

Тут народ часто ищет “n8n wait node approval workflow”, “n8n согласование в Telegram”, “n8n timeout workflow” и “n8n escalation manager”. По сути ответ один: нужен не один волшебный узел, а связка из нескольких нормальных кирпичей.

1. Trigger или входной Webhook

На входе прилетает событие. Здесь я сразу делаю валидацию: что согласуем, кто инициатор, какой приоритет, можно ли вообще обрабатывать заявку дальше.

2. Code / Set / IF для маршрутизации

На этом шаге считаю правила. Например: скидка до 10% идёт тимлиду, выше 10% — руководителю отдела, ещё выше — директору. Тут же удобно вычислять срок ответа: 15 минут, 2 часа, до конца рабочего дня, следующая смена и так далее.

3. Таблица хранения

Я люблю Postgres, но Google Sheets, Airtable, Notion или Data Table тоже подходят для простых запусков. Главное — хранить approval_id, entity_id, current_level, approver_id, status, expires_at, decided_at и причину решения. Если этого нет, разбирать историю потом будет больно уже вам, а не системе.

4. Узел отправки уведомления

Telegram, Slack, почта, внутренний вебхук, форма — не так важно. Важно, чтобы у сообщения был уникальный идентификатор и чтобы ответ можно было надёжно привязать к конкретной заявке. В n8n для ожидания по вебхуку помогает $execution.resumeUrl: это уникальный адрес продолжения именно для текущего выполнения.

5. Wait

Вот здесь и живёт сердце схемы. Wait умеет ждать интервал, конкретную дату, webhook call и form submitted. Для согласований чаще всего я беру webhook call, потому что тогда можно слать пользователю ссылку с параметрами решения или пробрасывать её через кнопку в интерфейсе. Для простых кейсов годится и “send and wait for response” в Telegram.

6. IF / Switch после возобновления

После пробуждения сценарий должен понять, что произошло: approve, reject или timeout. Я не люблю размытые ветки, поэтому всегда привожу ответ к нормализованному полю decision и отдельно ставлю флаг escalation_required.

7. Error Workflow и уведомления

Если в согласовании есть внешние API, чат-узлы и база, ошибки будут. Тут рядом очень к месту материал про контроль ошибок и ретраи в n8n. Я стараюсь, чтобы сбой отправки уведомления не маскировался под “менеджер не ответил”. Это две разные проблемы, и лог обязан различать их.

Какие статусы и поля я храню, чтобы не было каши

Когда люди ищут “approval workflow n8n example” или “multi level approval n8n”, им обычно показывают красивую схему из коробочек. Но реальная надёжность живёт в данных. Я бы рекомендовал минимальный набор такой:

  • approval_id — уникальный ID согласования;
  • entity_type и entity_id — что именно согласуем;
  • requested_by — кто инициатор;
  • current_level — текущая ступень;
  • current_approver — кто сейчас владелец решения;
  • status — pending / approved / rejected / timed_out / escalated;
  • deadline_at — до какого момента ждём;
  • decision_at — когда нажали кнопку;
  • decision_comment — причина отклонения или комментарий;
  • escalation_count — сколько раз уже поднимали выше;
  • channel — где шёл запрос: Telegram, email, Slack, web;
  • audit_ref — ссылка на запись в журнале.

Отдельно советую фиксировать не только финальный статус, но и каждое действие: отправили запрос, напомнили, истёк дедлайн, передали выше, согласовали, отклонили, закрыли вручную. В n8n для этого можно использовать Execution Data или custom execution data, а можно писать в свою таблицу аудита. Я чаще беру второй путь, потому что потом удобно строить отчёты по SLA и смотреть, на каком уровне затык повторяется чаще всего.

И вот тут же полезно почитать про дубликаты заявок в автоматизации. Как только у вас появляются напоминания, повторные отправки и ручные перезапуски, риск задвоения резко растёт.

Где держать дедлайны, уровни и аудит

Для маленькой команды можно стартовать хоть с Google Sheets. Но если согласований много, есть несколько уровней менеджеров и важна история действий, я бы не тянул с нормальной базой. Причина простая: timeout + escalation — это уже не просто уведомление, а маленький state machine.

Я обычно разделяю данные так:

  • таблица approvals — текущие живые запросы;
  • таблица approval_events — журнал каждого действия;
  • таблица approval_routes — кто идёт после кого и с каким SLA;
  • таблица business_objects — сами заявки, заказы, публикации, счета.

Если согласования массовые, а в одном инстансе крутится ещё куча сценариев, рано или поздно упрётесь в производительность. На этот случай советую глянуть разбор про воркеры и queue mode. Когда waiting-экзекьюшенов много, тема уже не теоретическая.

Ещё один практический трюк: не храните в сообщении всю бизнес-логику. Сообщение должно нести только контекст для человека и ссылку на действие. Истина должна лежать в таблице. Тогда вы спокойно меняете текст уведомлений, не ломая сам маршрут.

Где чаще всего ловят фейлы в согласовании через n8n

Первый фейл — открытый входной вебхук, который ждёт решения человека. На бумаге выглядит красиво, в проде заканчивается таймаутами на прокси, фронте или клиентском приложении. На практике я почти всегда отвечаю инициатору сразу: “заявка принята в обработку”, а само согласование уже живёт отдельно.

Второй фейл — отсутствие дедлайна. Если у согласования нет expires_at, оно не процесс, а музейный экспонат. Такие штуки висят месяцами, а потом кто-то случайно нажимает старую кнопку и запускает неактуальное действие.

Третий фейл — отсутствие защиты ссылок. Если вы шлёте approve/reject через webhook, ссылка должна быть одноразовой или хотя бы иметь срок жизни, подпись и проверку контекста. Тут я полностью за взрослый подход: токен, expiry, сверка approval_id и пользователя, который имеет право нажать кнопку.

Четвёртый фейл — смешивание timeout и ошибки доставки. Если уведомление не ушло в Telegram, это не молчание менеджера. Это отдельный инцидент, который должен попадать в error workflow или хотя бы в алерт.

Пятый фейл — слишком длинный единый workflow. Для простых сценариев один процесс с Wait нормален. Но когда уровней много, много повторных пингов, есть ручное вмешательство и аудит, я часто делю схему на два контура:

  1. workflow A создаёт запрос, пишет запись в базу, отправляет уведомление и завершает активную работу;
  2. workflow B обрабатывает ответ по webhook, меняет статус, принимает решение о следующем шаге и запускает эскалацию.

Так проще перезапускать отдельные куски, проще разбирать историю, проще тестировать и спокойнее жить. Плюс не держите одну длинную кишку на полэкрана.

Кстати, если у вас согласование встроено в более широкий маршрут обработки заявок, полезно связать это с общей логикой входящего потока. Тут хорошо заходит статья про автоматизацию потока заявок, потому что approval — это обычно один участок в большой цепочке, а не отдельная планета.

Чек-лист перед запуском в прод

  • Есть таблица с текущим статусом и дедлайном каждого согласования.
  • Есть уникальный ID согласования, а не только ID сообщения в мессенджере.
  • Есть маршрут escalation: кто второй, кто третий, что делать на последнем уровне.
  • Есть срок жизни ссылки или кнопки, и старое решение не может внезапно оживить кейс.
  • Есть разделение “человек молчит” и “система не доставила уведомление”.
  • Есть журнал событий, чтобы разбирать историю по минутам.
  • Есть дефолтное действие на крайний случай: отклонить, передать оператору или вынести в ручной разбор.
  • Есть тест на повторный клик approve/reject и тест на дубликат webhook.
  • Есть проверка workflow timeout и общих лимитов инстанса, чтобы дедлайн согласования не упирался в настройки окружения.
  • Есть отдельное уведомление инициатору: принято, согласовано, отклонено, передано выше.

Итог такой. Если хотите, чтобы n8n-согласование не умирало в чате одного менеджера, думайте не кнопкой, а состояниями. Нужны карточка решения, дедлайн, владелец, таймер, маршрут escalation и журнал событий. Тогда даже если один человек исчез из радара, процесс не развалится, а просто уйдёт на следующий уровень по заранее заданному правилу.

Я у себя в мастерской именно так и делаю: сначала проектирую путь решения, потом уведомления, и только потом рисую сами узлы. Тогда автоматизация не выглядит хрупким фокусом, а реально работает в бою — в заявках, закупках, контенте и любых штуках, где нужен живой кивок перед следующим шагом.

Метки: , , , , , , , , ,