Привет. Я у себя в мастерской быстро понял одну вещь: согласование в автоматизации ломается не там, где кнопка “Approve”, а там, где один человек ушёл в созвон, забыл открыть чат и утащил процесс в туман. Если коротко, рабочая схема в n8n выглядит так: создаём карточку решения, ставим дедлайн, отправляем запрос на подтверждение, ждём ответ через Wait, а если тишина — поднимаем escalation на следующий уровень. Ниже покажу саму логику, набор узлов, таблицу состояний, антифейлы и чек-лист перед запуском.
Статья пригодится, если вы собираете approval workflow в Telegram, почте, внутреннем кабинете или в связке с CRM. Я буду говорить на примере n8n, но сама механика годится почти для любого бизнес-процесса: скидка менеджеру, согласование закупки, ручной выпуск счёта, подтверждение ответа клиенту, публикация контента и любые действия, где нужен живой человек.
- Почему согласование виснет
- Как выглядит схема timeout + escalation
- Какие узлы я ставлю в n8n
- Какие статусы хранить
- Где держать дедлайны, уровни и аудит
- Где люди чаще всего ловят фейлы
- Чек-лист перед продом
Почему согласование виснет именно на одном менеджере
Самая частая ошибка простая: разработчик собирает красивый сценарий, шлёт сообщение одному руководителю и считает, что дело сделано. А дальше начинается обычная жизнь. Руководитель в дороге, на встрече, в отпуске, уведомление утонуло в чате, а заявка висит со статусом pending и блокирует всё, что идёт ниже по цепочке.
Второй косяк — пытаться держать исходный HTTP-запрос открытым, пока человек не нажмёт кнопку. В n8n это почти всегда плохая идея для длинных согласований. Wait умеет ставить выполнение на паузу и продолжать его потом, а для сценариев с ожиданием по времени, по вебхуку или по форме это как раз тот инструмент, на который и надо опираться. Плюс у Wait есть limit wait time: можно задать верхнюю границу ожидания и не оставлять процесс в подвешенном состоянии.
Третий момент — отсутствие чёткой модели эскалации. Если менеджер №1 не ответил, что делаем дальше? Повторяем пинг? Передаём руководителю группы? Отправляем в общий канал? Делаем автозавершение с пометкой “истёк SLA”? Пока на эти вопросы нет ответа в самой схеме, у вас не approval workflow, а надежда на удачу.
И да, ещё один нюанс. В n8n Wait короче 65 секунд работает как обычная пауза внутри текущего процесса, а длинное ожидание уже уходит в состояние waiting с сохранением данных выполнения. Поэтому для настоящих бизнес-согласований я не строю механику на коротких паузах “ну давай подождём минутку”. Я сразу проектирую нормальный дедлайн и нормальную ветку на случай тишины.

Как выглядит рабочая схема timeout + escalation в n8n
У меня прижилась вот такая логика. Она скучная, зато крепкая и не устраивает драму на ровном месте.
- Приходит событие: новая заявка, заказ, счёт, публикация или ответ клиенту.
- Я вычисляю риск и маршрут согласования: кому сначала, сколько ждём, кто второй в цепочке.
- Создаю запись в таблице approvals: ID объекта, текущий уровень, дедлайн ответа, канал уведомления, статус.
- Отправляю менеджеру сообщение с кнопками или ссылками approve/reject и сшиваю это с execution ID либо approval ID.
- Ставлю Wait на ответ по webhook call или на встроенный канал “send and wait for response”, если он подходит под задачу.
- Задаю limit wait time. Если ответ пришёл вовремя — пишу решение в журнал и двигаю процесс дальше.
- Если ответа нет — workflow сам просыпается по timeout, меняет статус на escalated и шлёт запрос следующему участнику.
- После последнего уровня либо принимаю дефолтное решение по правилу, либо отправляю задачу в ручной разбор.
Смысл тут не в одной кнопке, а в том, что каждый шаг имеет дедлайн, владельца и понятный выход. Такую схему легко объяснить команде, легко отлаживать и потом не мучиться вопросом “а где вообще застряло?”.
| Состояние | Что произошло | Что делает сценарий |
|---|---|---|
| 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 нормален. Но когда уровней много, много повторных пингов, есть ручное вмешательство и аудит, я часто делю схему на два контура:
- workflow A создаёт запрос, пишет запись в базу, отправляет уведомление и завершает активную работу;
- workflow B обрабатывает ответ по webhook, меняет статус, принимает решение о следующем шаге и запускает эскалацию.
Так проще перезапускать отдельные куски, проще разбирать историю, проще тестировать и спокойнее жить. Плюс не держите одну длинную кишку на полэкрана.
Кстати, если у вас согласование встроено в более широкий маршрут обработки заявок, полезно связать это с общей логикой входящего потока. Тут хорошо заходит статья про автоматизацию потока заявок, потому что approval — это обычно один участок в большой цепочке, а не отдельная планета.
Чек-лист перед запуском в прод
- Есть таблица с текущим статусом и дедлайном каждого согласования.
- Есть уникальный ID согласования, а не только ID сообщения в мессенджере.
- Есть маршрут escalation: кто второй, кто третий, что делать на последнем уровне.
- Есть срок жизни ссылки или кнопки, и старое решение не может внезапно оживить кейс.
- Есть разделение “человек молчит” и “система не доставила уведомление”.
- Есть журнал событий, чтобы разбирать историю по минутам.
- Есть дефолтное действие на крайний случай: отклонить, передать оператору или вынести в ручной разбор.
- Есть тест на повторный клик approve/reject и тест на дубликат webhook.
- Есть проверка workflow timeout и общих лимитов инстанса, чтобы дедлайн согласования не упирался в настройки окружения.
- Есть отдельное уведомление инициатору: принято, согласовано, отклонено, передано выше.
Итог такой. Если хотите, чтобы n8n-согласование не умирало в чате одного менеджера, думайте не кнопкой, а состояниями. Нужны карточка решения, дедлайн, владелец, таймер, маршрут escalation и журнал событий. Тогда даже если один человек исчез из радара, процесс не развалится, а просто уйдёт на следующий уровень по заранее заданному правилу.
Я у себя в мастерской именно так и делаю: сначала проектирую путь решения, потом уведомления, и только потом рисую сами узлы. Тогда автоматизация не выглядит хрупким фокусом, а реально работает в бою — в заявках, закупках, контенте и любых штуках, где нужен живой кивок перед следующим шагом.