Узел Code в n8n нужен, когда обычных настроек недостаточно: например, нужно очистить несколько полей и проверить запись по своим правилам. Разберём конкретный пример на JavaScript. Три учебных заказа пройдут через один блок кода; два попадут в готовые данные, третий — в ручную проверку. В конце у вас будет работающая схема и понятный способ проверить её, а не только фрагмент JavaScript.
Результат инструкции
Заказ O1 содержит лишние пробелы, сумму текстом и валюту rub. Схема превратит его в запись с именем «Анна Петрова», суммой 150000 копеек и валютой RUB. Заказ O2 с нулевой суммой тоже пройдёт: ноль не считается отсутствующим значением. Заказ O3 без имени и с суммой «сумма» получит needs_review и две причины ошибки. Никакие письма, платежи или изменения в CRM не выполняются.
Это обычная обработка данных, не AI-агент. Модель, платный тариф и ключ LLM не нужны. Результат хранится только в данных выполнения n8n: постоянный журнал и отправку оператору эта схема не создаёт.
Что понадобится
- Работающий n8n и доступ к редактору workflows. Наш тест выполнен на n8n 2.42.4; точное расположение кнопок в другой версии может отличаться.
- Новый отдельный workflow. Рабочие схемы, credentials и реальные клиентские данные не используйте.
- Скачиваемый JSON или текст ниже. В файле нет API-ключей и активных триггеров.
Установка n8n через Docker, если редактора ещё нет
Шаг 1. Скачайте учебный workflow
Откройте адрес ниже и сохраните файл n8n-code-demo.json. Если браузер показывает JSON вместо скачивания, используйте «Сохранить как». Это файл схемы, а не программа для запуска в PowerShell.
Скачать готовый workflow для Code
Шаг 2. Импортируйте схему в новый workflow
Создайте новый workflow, откройте меню редактора и выберите Import from File. Загрузите n8n-code-demo.json. Должны появиться семь узлов с указанными ниже именами. Если импорт недоступен, добавьте узлы вручную в этом порядке; остальные шаги содержат все нужные настройки.
Manual Trigger → Test Orders → Split Orders → Normalize Orders → Ready Check
├ true → Ready Orders
└ false → Input Review
Test Orders — Edit Fields (Set); Split Orders — Split Out; Normalize Orders — Code; Ready Check — If; последние два узла — No Operation, do nothing. У них нет действий: они только показывают, в какую ветку попала запись. Сохраните workflow под отдельным именем, не публикуйте его и не включайте расписание.
Шаг 3. Добавьте три тестовых заказа
Откройте Test Orders. Выберите Mode: JSON Output и вставьте весь объект ниже. Не добавляйте комментарии в JSON и не заменяйте кавычки типографскими. Выполните этот узел: в OUTPUT должен быть один item с полем orders, внутри которого лежит массив из трёх объектов.
{
"orders": [
{
"order_id": "O1",
"client": " Анна Петрова ",
"amount_minor": "150000",
"currency": "rub"
},
{
"order_id": "O2",
"client": "Борис",
"amount_minor": 0,
"currency": "RUB"
},
{
"order_id": "O3",
"client": "",
"amount_minor": "сумма",
"currency": "RUB"
}
]
}
amount_minor — сумма в копейках. «150000» в первом заказе специально является строкой; во втором 0 — число; в третьем «сумма» — некорректное значение. Данные вымышленные. Нулевой заказ допустим только по правилам этого учебного примера, а не автоматически для любого бизнеса.
Шаг 4. Разделите массив на отдельные items
Откройте Split Orders. В Field to Split Out укажите orders, в Include выберите No Other Fields. Соедините Test Orders с этим узлом и выполните предыдущие узлы вместе с ним. На выходе должно быть три items. В каждом поля order_id, client, amount_minor и currency должны находиться прямо в json, а не внутри orders.
Если непонятна разница между массивом и items
Шаг 5. Выберите правильный режим Code
В Normalize Orders задайте Language: JavaScript и Mode: Run Once for All Items. Режим запускает код один раз для всего входного набора. Это важно: мы не только чистим отдельную запись, но и ищем повторяющиеся ID среди всех входных items. В Run Once for Each Item тот же фрагмент использовать нельзя без изменения логики.
В обычном Expression часто достаточно $json.client. Здесь нужен весь набор, поэтому код начинается с $input.all(). Каждый элемент этого массива имеет оболочку json; это служебная структура n8n, а не ещё одно поле заказа.
Шаг 6. Вставьте JavaScript целиком
Замените стартовый пример в редакторе Code следующим кодом. Не оборачивайте его в {{ }} и не добавляйте перед ним знак =: такие записи нужны для Expressions, а здесь находится обычный JavaScript.
Показать код (32 строк)
const items = $input.all();
const clean = value => typeof value === 'string'
? value.trim().replace(/\s+/g, ' ') : '';
const ids = items.map(item => clean(item.json.order_id));
const counts = new Map();
for (const id of ids) counts.set(id, (counts.get(id) ?? 0) + 1);
return items.map((item, index) => {
const row = item.json;
const order_id = ids[index];
const client = clean(row.client);
const currency = clean(row.currency).toUpperCase();
const raw = row.amount_minor;
const amount_minor = typeof raw === 'number' ? raw
: typeof raw === 'string' && /^\d+$/.test(raw.trim())
? Number(raw.trim()) : NaN;
const errors = [];
if (!order_id) errors.push('order_id_required');
if (order_id && counts.get(order_id) > 1) errors.push('duplicate_order_id');
if (!client) errors.push('client_required');
if (currency !== 'RUB') errors.push('currency_must_be_RUB');
if (!Number.isSafeInteger(amount_minor) || amount_minor < 0)
errors.push('amount_minor_invalid');
const json = { order_id, client, currency,
status: errors.length ? 'needs_review' : 'ready', errors };
if (!errors.length) {
json.amount_minor = amount_minor;
json.amount_rub = amount_minor / 100;
}
return { json, pairedItem: { item: index } };
});
Функция clean убирает пробелы по краям и сжимает повторяющиеся пробелы. counts считает уже очищенные ID. Сумма принимается как безопасное целое число или строка только из цифр; null, «1e3» и «1500,00» не превращаются незаметно в деньги. Number.isSafeInteger отсекает значения вне безопасного целочисленного диапазона JavaScript.
Ошибки записываются в errors. Поля amount_minor и amount_rub появляются только у готового заказа, чтобы ошибочная запись не выглядела как заказ с нулевой суммой. pairedItem связывает каждый результат с его входным item по индексу. В нашем коде количество и порядок записей не меняются. При фильтрации, сортировке или объединении записей такую связь нужно строить по фактическому источнику, а не копировать индекс вслепую.
Шаг 7. Проверьте результат до ветвления
Выполните схему до Normalize Orders. В OUTPUT должно остаться три items. У O1 ожидаются client «Анна Петрова», currency RUB, status ready, amount_minor 150000 и amount_rub 1500. У O2 — ready и обе суммы 0. У O3 — needs_review и массив errors ниже; денежных полей быть не должно.
["client_required", "amount_minor_invalid"]
Если вместо трёх результатов появился один объект, проверьте return items.map(...). n8n ожидает массив items в этом режиме; каждый наш item явно возвращает json. Не сокращайте пример до return row, пока проверяете структуру.
Шаг 8. Настройте две ветки If
В Ready Check добавьте условие String: значение слева — Expression ниже, операция is equal to, справа обычный текст ready. Выход true соедините с Ready Orders, false — с Input Review. Обе ветки заканчиваются узлами No Operation.
{{ $json.status }}
Выполните весь workflow через Manual Trigger. Ready Orders должен получить два items: O1 и O2. Input Review — один item O3. Проверяйте данные обеих веток, а не только зелёный статус выполнения. Импортированный файл уже содержит эти соединения.
Шаг 9. Проверьте допустимый ноль и неверную сумму
В Test Orders временно замените amount_minor у O1 на строку «0», не меняя остальные поля. Повторный запуск должен дать amount_minor 0 и status ready. Затем замените эту строку на «1e3»: теперь O1 должен оказаться в Input Review с amount_minor_invalid. Верните исходный JSON после проверки.
Не используйте Number(raw) для любого входа без проверки: например, Number(null) даёт 0. Ошибка формата не должна превращаться в корректный нулевой заказ. Если ваша система присылает рубли с запятой, сначала согласуйте правила разбора и отдельно протестируйте их; этот код работает с копейками, не с произвольным текстом о цене.
Шаг 10. Проверьте повторяющиеся ID
Поменяйте order_id у второго заказа на строку « O1 » с пробелами. После очистки оба ID станут O1, поэтому оба заказа должны уйти в Input Review с duplicate_order_id. Это намеренная остановка: код не выбирает, какая версия заказа верная. Восстановите O2 и снова запустите схему.
Проверка видит дубли только внутри текущего входного набора Code. Она не помнит ID из прошлых запусков и не обеспечивает идемпотентность отправки в CRM. Если API прислал лишь одну страницу, код не доказывает отсутствие дублей на остальных страницах.
Шаг 11. Посмотрите, как выглядит ошибка самого кода
В отдельной учебной копии workflow временно замените содержимое Normalize Orders одной строкой ниже. Выполните Manual Trigger: Code должен завершиться ошибкой, а новые данные не должны дойти до Ready Orders. Затем обязательно верните полный код из шага 6.
throw new Error('training_error');
Это другой тип ошибки. needs_review — результат нашей проверки записи; исключение JavaScript останавливает узел. В учебной схеме оставьте Settings → On Error: Stop Workflow. Не включайте Continue и не направляйте исключения в готовые заказы. Исторические OUTPUT от прежнего запуска не считайте результатом нового неуспешного выполнения.
Шаг 12. Восстановите данные и сохраните рабочую версию
Верните JSON шага 3 и JavaScript шага 6. Проверьте язык, режим All Items, Stop Workflow и отсутствие закреплённых данных, которые подменяют вход. Выполните всю цепочку заново. Итог: два готовых заказа O1/O2, одна ошибочная запись O3, 1500 рублей у O1 и 0 у O2. Сохраните ручной workflow неопубликованным.
Если результат отличается
| Симптом | Причина | Что проверить |
|---|---|---|
| Code видит только orders | Массив не разделён | Split Out: поле orders |
| Ошибка режима выполнения | Выбран Each Item | Run Once for All Items |
| Нулевая сумма отклонена | Проверка через !amount | Используйте полный код |
| Все записи в Input Review | Не прошли проверки полей | Посмотрите массив errors |
| Дубль прошёл как готовый | Код видит часть набора | Подайте оба заказа вместе |
| После сбоя видны старые данные | Открыт прежний OUTPUT | Выберите новое выполнение |
Перед подключением рабочих данных
Сначала замените только Test Orders на источник с доступом для чтения и сохраните тот же формат. Определите, что означает нулевая сумма, как обрабатывать валюты и по каким полям находить дубли. Не складывайте RUB и USD в один итог и не делайте Number() универсальным исправлением любой суммы.
Не вставляйте секреты в Code и не давайте скопированному коду доступ к рабочим отправкам. Для сетевых запросов используйте HTTP Request, для credentials — штатное хранение n8n. Сначала добавьте отдельный журнал ошибок и ручную сверку; только после этого подключайте подтверждённые действия. Этот пример не отправляет данные оператору и не является полноценным контролем качества исходной системы.
Что проверено редакцией
13 октября 2026 года workflow выполнен через CLI n8n 2.42.4 в отдельной тестовой базе. Проверены десять сценариев: исходные заказы, допустимый ноль, два корректных заказа, отрицательное число, строка 1e3, отсутствующие поля, null, число вне безопасного диапазона, повторяющиеся очищенные ID и валюта USD. Проверены значения, ветки ready/needs_review и pairedItem. Рабочие workflows и контейнеры не менялись. Запуск через редактор и n8n Cloud, намеренное исключение из шага 11, реальные API, отправки, постоянный журнал, пустой вход и большие наборы отдельно не тестировались. Обложка — редакционная AI-иллюстрация, не скриншот n8n.
Частые вопросы
Code в n8n использует нейросеть?
Нет. Этот пример выполняет JavaScript с заданными правилами, без вызова AI-модели, API-ключа и расхода токенов.
Когда нужен Code, а когда достаточно Edit Fields?
Для копирования поля, простого выражения и переименования обычно хватает Edit Fields. Code удобен, когда связанная проверка нескольких полей или всего набора становится слишком сложной в настройках.
Почему используется Run Once for All Items?
Код смотрит на весь входной набор и ищет дубли ID. В режиме Each Item нужен другой код; проверка дублей среди всех заказов не переносится автоматически.
Что означает pairedItem?
Это связь выходного item с входным item данного узла. В примере каждый заказ сохраняет своё место. Если код меняет порядок или число записей, связь нужно строить заново по их реальным источникам.
Можно ли скопировать этот код для настоящей CRM?
Сначала согласуйте формат полей, правила сумм, валют и дублей. Проверьте полную выгрузку и ошибки на копии данных. Готовые строки не отправляйте автоматически, пока не настроены журнал и подтверждение действий.