Skip to content

Глава 9. Sub-workflows и переиспользование логики

По мере роста автоматизаций начинаются повторения: одна и та же логика трансформации данных, одинаковые блоки отправки уведомлений, стандартные HTTP-запросы к одному API. Sub-workflows — механизм для устранения этого дублирования.

Что такое Sub-workflow

Sub-workflow — обычный воркфлоу, который запускается из другого воркфлоу через ноду Execute Sub-workflow. Вызывающий воркфлоу может передать данные и получить результат обратно.

Главный воркфлоу:
  Schedule Trigger
    → [для каждого клиента]
    → Execute Sub-workflow (SendReport)
        ↓ (передаём clientId, period)
        ↓ (получаем {reportUrl, rowCount})
    → Slack (уведомление с reportUrl)

Execute Sub-workflow (вызов подворкфлоу)

Настройка вызывающей ноды

ПараметрОписание
WorkflowID или имя воркфлоу-цели
ModeRun once with all items / Run once for each item
FieldsДанные, передаваемые в подворкфлоу

Run once with all items — все айтемы передаются одним вызовом. Run once for each item — подворкфлоу вызывается отдельно для каждого айтема.

Настройка принимающей стороны (Sub-workflow trigger)

Воркфлоу, который будет использоваться как sub-workflow, должен начинаться с триггера Execute Workflow Trigger (а не Manual или Schedule).

Этот триггер получает данные из вызывающего воркфлоу:

json
{
  "clientId": "client-42",
  "period": "2024-01"
}

Возврат данных

Последняя нода sub-workflow определяет, что вернётся в родительский воркфлоу. Добавьте ноду Set в конец, чтобы явно задать возвращаемые поля:

// В конце sub-workflow:
Set:
  reportUrl: {{ $json.url }}
  rowCount: {{ $json.count }}

В родительском воркфлоу после Execute Sub-workflow:

{{ $json.reportUrl }}   // URL отчёта
{{ $json.rowCount }}    // количество строк

Практика: переиспользование логики форматирования

Допустим, в десяти воркфлоу нужно форматировать денежные суммы: 1234567.891 234 567,89 ₽.

Вместо дублирования ноды Code создайте один sub-workflow:

Sub-workflow "FormatMoney" (триггер: Execute Workflow Trigger):

javascript
// Code node
const amount = $json.amount;
const formatted = new Intl.NumberFormat('ru-RU', {
  style: 'currency',
  currency: 'RUB',
  minimumFractionDigits: 2
}).format(amount);

return [{ json: { formatted } }];

В любом воркфлоу:

Execute Sub-workflow (FormatMoney)
  Fields: amount = {{ $json.total }}

→ получаем {{ $json.formatted }} = 1 234 567,89 ₽.

Workflow Variables (переменные воркфлоу)

Начиная с n8n v1.0, доступны Variables — глобальные переменные, общие для всех воркфлоу экземпляра.

Создание: Settings → Variables → Add variable:

Name: TELEGRAM_CHAT_ID
Value: -1001234567890

Использование в выражениях:

{{ $vars.TELEGRAM_CHAT_ID }}

Отличие Variables от .env

Variables хранятся в базе данных и управляются через UI. Environment Variables задаются при запуске сервера и недоступны для изменения без рестарта. Variables — для конфигурации, которую нужно менять без деплоя.

Static Data — состояние внутри воркфлоу

Иногда воркфлоу нужно помнить что-то между запусками: последний обработанный ID, метку времени последней синхронизации.

javascript
// Чтение сохранённого состояния
const workflowStaticData = $getWorkflowStaticData('global');
const lastProcessedId = workflowStaticData.lastId || 0;

// ... обработка новых записей ...

// Сохранение нового состояния
workflowStaticData.lastId = maxId;

$getWorkflowStaticData('global') — данные общие для всего воркфлоу. $getWorkflowStaticData('node') — данные привязаны к конкретной ноде.

WARNING

Static Data сохраняется только при успешном завершении выполнения. Если воркфлоу упал — состояние не обновится, и при следующем запуске будет использоваться предыдущее значение.

Практика: инкрементальная синхронизация

Синхронизация только новых заказов из API (с запоминанием последнего ID):

javascript
// Code node "Получить последний ID"
const state = $getWorkflowStaticData('global');
return [{ json: { lastId: state.lastId || 0 } }];
HTTP Request: GET /api/orders?since_id={{ $json.lastId }}&limit=100
javascript
// Code node "Сохранить последний ID"
const orders = $input.all();
if (orders.length === 0) return orders;

const maxId = Math.max(...orders.map(o => o.json.id));
const state = $getWorkflowStaticData('global');
state.lastId = maxId;

return orders;
→ [продолжение обработки заказов]

При каждом запуске по расписанию воркфлоу обрабатывает только новые записи.

Шаблоны воркфлоу

n8n имеет встроенный маркетплейс шаблонов по адресу n8n.io/workflows. Более 1000 готовых воркфлоу можно импортировать одним кликом.

Поиск по категориям: Marketing, DevOps, Sales, Finance, Utilities.

Импорт шаблона

  1. Откройте https://n8n.io/workflows → найдите нужный.
  2. Нажмите Use workflow.
  3. В n8n: Workflows → Import from URL или вставьте JSON напрямую.

Экспорт своего воркфлоу

Workflows → три точки → Export → сохраняет JSON-файл. JSON содержит всю конфигурацию нод (без значений credentials). Удобно для версионирования в Git и шеринга.

Git для воркфлоу

В n8n Enterprise доступна встроенная интеграция с Git (Source Control). В Community-версии экспортируйте воркфлоу вручную и коммитьте JSON-файлы в репозиторий. Так вы получаете историю изменений и возможность откатиться.

Неофициальная документация. n8n — продукт n8n GmbH.