N8n Code Node: Полное руководство по использованию узла для выполнения пользовательского кода
Узел Code (код) в n8n — это мощный инструмент, который позволяет выполнять пользовательский код JavaScript (Node.js) или Python непосредственно внутри рабочего процесса. Он предоставляет максимальную гибкость для обработки данных, реализации сложной логики, интеграции со сторонними библиотеками и решения задач, которые невозможно выполнить с помощью стандартных узлов платформы. Этот узел является мостом между визуальным программированием n8n и традиционной разработкой на скриптовых языках.
Архитектура и принцип работы Code Node
Узел Code выполняется в изолированной среде (песочнице) на стороне сервера, где запущен n8n. Он получает входные данные (items) из предыдущих узлов рабочего процесса, обрабатывает их с помощью написанного пользователем скрипта и возвращает результат последующим узлам. Код выполняется синхронно для каждого элемента (item) или для всего массива элементов сразу, в зависимости от выбранного режима.
Ключевые компоненты узла:
- Редактор кода: Встроенная среда для написания скриптов с подсветкой синтаксиса и базовым автодополнением.
- Контекст выполнения (Sandbox): Ограниченная среда, которая предоставляет доступ к определенным объектам и функциям (например,
$input,$json,$), но блокирует опасные операции (доступ к файловой системе, сетевые вызовы) для безопасности. - Библиотеки: Предустановленный набор популярных npm-пакетов (для JavaScript) и модулей (для Python), доступных для немедленного использования.
- Режимы выполнения: Возможность запускать код для «Каждого элемента» (по отдельности) или «Один раз для всех элементов» (пакетная обработка).
- Версия Node.js: Зависит от версии n8n (обычно последняя LTS).
- Доступные модули:
axios,moment,lodash,jsonwebtoken,crypto-jsи многие другие. Полный список можно найти в документации n8n. - Версия Python: Обычно Python 3.9+.
- Особенности: Код выполняется через отдельный процесс. Обмен данными между n8n и Python-процессом происходит через стандартные потоки ввода-вывода (stdin/stdout), что может влиять на производительность при работе с большими объемами данных.
- Доступные пакеты:
pandas,numpy,requestsи другие. Список также указан в документации.
Доступные языки программирования и их особенности
JavaScript/Node.js
Это основной и наиболее интегрированный язык в n8n. Он предоставляет прямой доступ к объектам n8n и имеет наиболее полную документацию.
Python
Поддержка Python добавляет возможность использовать богатую экосистему библиотек для data science, машинного обучения и специфических вычислений.
Ключевые объекты и переменные в окружении Code Node
Для взаимодействия с данными рабочего процесса в коде доступны специальные объекты.
| Объект/Переменная | Описание | Пример использования (JavaScript) |
|---|---|---|
$input |
Предоставляет методы для получения входных данных от предыдущего узла: .first(), .all(), .item. |
const data = $input.first().json; |
$json |
Содержит JSON-данные текущего элемента (в режиме «Для каждого элемента»). | const email = $json.email; |
$item |
Объект, представляющий текущий элемент, включая его json, binary данные и метаинформацию. |
const fileName = $item.binary['file.pdf'].fileName; |
$index |
Индекс (номер) текущего элемента (начинается с 0). Актуален в режиме «Для каждого элемента». | const position = $index + 1; |
$ (доллар) |
Утилита для работы с датами и временем (на основе moment). |
const now = $.now(); const formatted = $.formatDate(now, 'YYYY-MM-DD'); |
items |
Массив всех элементов, полученных на входе. Используется в режиме «Один раз для всех элементов». | const allIds = items.map(item => item.json.id); |
Практические примеры использования Code Node
Пример 1: Преобразование и обогащение данных (JavaScript)
Задача: Получить список пользователей из CRM, рассчитать их возраст на основе даты рождения и добавить категорию «старше 30».
// Режим: Для каждого элемента const birthDate = new Date($json.date_of_birth); const today = new Date(); let age = today.getFullYear() - birthDate.getFullYear(); const m = today.getMonth() - birthDate.getMonth(); if (m < 0 || (m === 0 && today.getDate() 30 ? 'старше 30' : '30 и младше'; // Возвращаем модифицированный объект return $json;
Пример 2: Агрегация данных (Python, режим «Один раз для всех элементов»)
Задача: Получить массив заказов и рассчитать общую сумму, средний чек и количество.
import pandas as pd import jsonitems содержит все элементы
orders = [item['json'] for item in items] df = pd.DataFrame(orders) total_sum = df['amount'].sum() average_order = df['amount'].mean() order_count = len(df)Создаем новый элемент с агрегированными данными
result_item = { "total_sum": float(total_sum), "average_order": float(average_order), "order_count": int(order_count), "report_date": pd.Timestamp.now().strftime('%Y-%m-%d') }Возвращаем массив с одним элементом
return [result_item]
Пример 3: Работа с бинарными данными (JavaScript)
Задача: Получить изображение из предыдущего узла, создать его миниатюру (с использованием библиотеки jimp).
const Jimp = require('jimp');
// Получаем бинарные данные изображения
const binaryData = $item.binary['image'];
// Jimp читает данные из буфера
const image = await Jimp.read(Buffer.from(binaryData.data, 'base64'));
// Изменяем размер
await image.resize(100, Jimp.AUTO);
// Получаем буфер обработанного изображения
const resizedBuffer = await image.getBufferAsync(Jimp.MIME_JPEG);
// Создаем новый элемент с новыми бинарными данными
const newItem = {
json: { ...$json, resized: true },
binary: {
'thumbnail': {
data: resizedBuffer.toString('base64'),
mimeType: Jimp.MIME_JPEG,
fileName: `thumb_${binaryData.fileName}`
}
}
};
return newItem;
Обработка ошибок и отладка
Для отладки кода в узле Code используется функция console.log() (для JavaScript) или print() (для Python). Вывод этих функций можно увидеть во вкладке «Выполнение» (Execution) при тестовом запуске рабочего процесса.
Рекомендуется оборачивать код в блоки try-catch для корректной обработки исключений и предотвращения падения всего рабочего процесса.
try {
// Код, который может вызвать ошибку
const result = riskyOperation($json.data);
$json.result = result;
return $json;
} catch (error) {
// В случае ошибки возвращаем элемент с флагом ошибки
$json.error = error.message;
$json.success = false;
return $json;
}
Производительность и ограничения
- Таймаут выполнения: По умолчанию код не должен выполняться дольше нескольких минут (точное значение зависит от конфигурации). Долгие операции могут быть прерваны.
- Память: Код выполняется в ограниченной по памяти среде. Обработка очень больших массивов данных может привести к ее исчерпанию.
- Библиотеки: Использование непредустановленных библиотек невозможно без модификации Docker-образа или установки n8n через npm и ручного добавления зависимостей.
- Python: Запуск Python-кода имеет дополнительную нагрузку из-за межпроцессного взаимодействия, что делает его менее производительным для поточной обработки множества мелких элементов по сравнению с JavaScript.
Лучшие практики использования Code Node
- Приоритет стандартным узлам: Всегда сначала ищите решение с помощью стандартных узлов n8n (Function, Item Lists, Aggregate и т.д.). Они надежнее и производительнее.
- Документирование кода: Добавляйте комментарии в сложные скрипты, объясняющие логику.
- Модульность: Для очень длинных скриптов рассмотрите возможность разбивки логики на несколько последовательных узлов Code.
- Обработка ошибок: Всегда реализуйте обработку исключений.
- Тестирование: Тестируйте код на небольшом наборе данных перед запуском рабочего процесса в продакшене.
- Безопасность: Не используйте узел Code для выполнения непроверенного пользовательского кода. Избегайте eval() и подобных функций.
Ответы на часто задаваемые вопросы (FAQ)
Как добавить собственную npm-библиотеку в Code Node?
При стандартной установке (через Docker или исполняемый файл) это невозможно. Необходима установка n8n через npm (npm install n8n) в собственном проекте. Затем вы можете установить нужные пакеты в папке проекта (npm install <package-name>) и перезапустить n8n. Пакет станет доступен в песочнице Code Node.
Почему мой Python-код работает медленнее, чем JavaScript?
Это связано с архитектурой выполнения. Каждый вызов Python-узла запускает новый процесс интерпретатора, происходит сериализация/десериализация данных в JSON, что создает накладные расходы. Для пакетной обработки всех элементов сразу (режим «Один раз») разница менее заметна.
Можно ли использовать асинхронный код (async/await) в JavaScript Code Node?
Да, полностью. Редактор кода поддерживает современный JavaScript (ES2022+). Вы можете использовать async/await, Promise, стрелочные функции и другие современные синтаксические конструкции.
Как передать данные между несколькими узлами Code?
Данные передаются через выход узла. Убедитесь, что ваш код возвращает объект или массив объектов в формате, ожидаемом следующим узлом. Обычно это объект с полем json (и опционально binary). Следующий узел Code получит эти данные через $input или $json.
Есть ли ограничение на длину кода в редакторе?
Жесткого ограничения нет, но для лучшей поддерживаемости рабочего процесса не рекомендуется писать скрипты длиной в сотни строк. Лучше вынести сложную логику во внешний скрипт (если это возможно) или разбить ее на несколько узлов.
Можно ли совершать HTTP-запросы из Code Node?
Да, для этого в предустановленных библиотеках доступен axios (JavaScript) и requests (Python). Однако для типовых HTTP-запросов рекомендуется использовать стандартный узел «HTTP Request», так как он имеет встроенную обработку ошибок, повторные попытки и более удобную настройку.
Как обрабатывать бинарные данные (файлы) в Code Node?
Бинарные данные доступны через объект $item.binary. Каждый файл представлен объектом со свойствами data (строка в base64), mimeType и fileName. Вы можете декодировать данные из base64 в Buffer (Node.js) или bytes (Python), обработать их и закодировать обратно в base64 для возврата из узла.
Что делать, если в консоли отладки я вижу «Required module ‘X’ not found»?
Это означает, что библиотека ‘X’ не входит в список предустановленных для песочницы. Вам необходимо либо найти альтернативу из списка доступных, либо, как описано выше, установить n8n через npm и добавить библиотеку вручную, либо реализовать нужную функциональность нативно или с помощью других узлов n8n.
Добавить комментарий