Навіщо потрібні кастомні ноди?
Стандартний набір n8n включає HTTP Request, Function, Webhook та інші. Однак при інтеграції з сучасними API часто виникають завдання, які складно вирішити вбудованими засобами: складна пагінація, retry з експоненційною затримкою, підтримка кількох версій API, вбудований OAuth2 з refresh-токенами. Кастомна нода — це TypeScript-пакет, який реєструється в n8n і працює як нативна. Вона дає повний контроль над логікою та перевикористовується в будь-якому workflow.
Візьмемо реальний кейс: інтеграція з CRM з rate limit 100 запитів/хв і необхідністю обробки помилок 429 та 500. У кастомній ноді ми реалізували чергу запитів із затримкою, retry з backoff і власний моніторинг. Результат — стабільна синхронізація десятків тисяч контактів без ручного втручання. Наш досвід — понад 20 інтеграцій для CRM, платіжних систем і пагінованих API. Працюємо з актуальними версіями n8n та TypeScript.
«Custom nodes are TypeScript packages that extend n8n’s functionality» — n8n docs
Як ми розробляємо кастомні ноди?
Розробка починається з аналізу документації API: визначаємо ресурси, операції, ліміти. Потім проектуємо схему credentials, структуру ноди та параметри. Реалізація на TypeScript з урахуванням усіх сценаріїв, включаючи обробку помилок. Після — тестування з моками та інтеграційні тести. Фінальний етап — пакування та постачання через npm registry або архів.
Типова структура проекту
my-n8n-nodes/ ├── nodes/ │ └── MyService/ │ ├── MyService.node.ts │ ├── MyService.node.json │ └── myservice.svg ├── credentials/ │ └── MyServiceApi.credentials.ts ├── package.json └── tsconfig.json Credentials та основна нода
package.json:
{ "name": "n8n-nodes-myservice", "version": "1.0.0", "description": "n8n nodes for MyService API", "main": "index.js", "n8n": { "n8nNodesApiVersion": 1, "credentials": ["dist/credentials/MyServiceApi.credentials.js"], "nodes": ["dist/nodes/MyService/MyService.node.js"] }, "devDependencies": { "n8n-workflow": "*", "typescript": "^5.0.0" } } Credentials:
// credentials/MyServiceApi.credentials.ts import { ICredentialType, INodeProperties } from 'n8n-workflow'; export class MyServiceApi implements ICredentialType { name = 'myServiceApi'; displayName = 'MyService API'; documentationUrl = 'https://docs.myservice.com/api'; properties: INodeProperties[] = [ { displayName: 'API Key', name: 'apiKey', type: 'string', typeOptions: { password: true }, default: '', }, { displayName: 'Base URL', name: 'baseUrl', type: 'string', default: 'https://api.myservice.com/v1', }, ]; } Основна нода:
// nodes/MyService/MyService.node.ts import { IExecuteFunctions, INodeExecutionData, INodeType, INodeTypeDescription, NodeApiError, } from 'n8n-workflow'; export class MyService implements INodeType { description: INodeTypeDescription = { displayName: 'MyService', name: 'myService', icon: 'file:myservice.svg', group: ['transform'], version: 1, description: 'Interact with MyService API', defaults: { name: 'MyService' }, inputs: ['main'], outputs: ['main'], credentials: [ { name: 'myServiceApi', required: true } ], properties: [ { displayName: 'Resource', name: 'resource', type: 'options', options: [ { name: 'Contact', value: 'contact' }, { name: 'Deal', value: 'deal' }, ], default: 'contact', }, { displayName: 'Operation', name: 'operation', type: 'options', displayOptions: { show: { resource: ['contact'] } }, options: [ { name: 'Create', value: 'create', action: 'Create a contact' }, { name: 'Get', value: 'get', action: 'Get a contact' }, { name: 'Update', value: 'update', action: 'Update a contact' }, ], default: 'create', }, { displayName: 'Email', name: 'email', type: 'string', displayOptions: { show: { resource: ['contact'], operation: ['create'] } }, default: '', required: true, }, ], }; async execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> { const items = this.getInputData(); const returnData: INodeExecutionData[] = []; const credentials = await this.getCredentials('myServiceApi'); const resource = this.getNodeParameter('resource', 0) as string; const operation = this.getNodeParameter('operation', 0) as string; for (let i = 0; i < items.length; i++) { try { let responseData: unknown; if (resource === 'contact' && operation === 'create') { const email = this.getNodeParameter('email', i) as string; responseData = await this.helpers.request({ method: 'POST', url: `${credentials.baseUrl}/contacts`, headers: { 'Authorization': `Bearer ${credentials.apiKey}`, 'Content-Type': 'application/json', }, body: { email }, json: true, }); } returnData.push({ json: responseData as object }); } catch (error) { if (this.continueOnFail()) { returnData.push({ json: { error: error.message }, pairedItem: i }); continue; } throw new NodeApiError(this.getNode(), error); } } return [returnData]; } } Як встановити кастомну ноду в n8n?
Встановлення здійснюється через npm: npm install /path/to/my-n8n-nodes або з публічного registry. При використанні Docker монтуйте директорію з нодами через volume та вкажіть змінну середовища N8N_CUSTOM_EXTENSIONS. Після встановлення нода з'являється в редакторі та готова до використання.
Кастомна нода проти ланцюжка HTTP + Function: що обрати?
| Характеристика | Кастомна нода | Ланцюжок HTTP + Function |
|---|---|---|
| Обробка помилок | Вбудована, з кастомною логікою | Вимагає додаткових нод |
| Пагінація | Автоматична, без налаштування | Ручна реалізація з циклами |
| Продуктивність | У 10-50 разів швидше | Знижується на великих обсягах |
| Повторне використання | Один раз розробив — використовуй у всіх workflow | Копіюй блоки щоразу |
| Супровід | Єдина кодова база | Фрагменти розкидані |
Типи credentials для кастомних нод
Кастомні ноди дозволяють реалізувати будь-які типи авторизації: API Key, OAuth2, Basic Auth, Bearer Token, Session Cookie. Для OAuth2 підтримується автоматичне оновлення refresh-токенів. У credentials можна додати кастомну перевірку та документацію.
| Тип credentials | Складність реалізації | Приклад використання |
|---|---|---|
| API Key | Низька | Зовнішні REST API |
| OAuth2 | Середня | Google, Facebook, GitHub |
| Basic Auth | Низька | Корпоративні системи |
| Session Cookie | Висока | CMS без REST API |
Обсяг робіт та терміни
У послугу входить: вихідний код ноди (TypeScript) з коментарями, credentials-клас, інструкція по встановленню (npm/docker), документація з використання та тестове покриття (модульні + інтеграційні тести). Також надаємо консультацію з інтеграції з існуючими workflow.
Терміни: проста нода з 2–3 операціями та credentials — 2–4 дні. Складна нода з polling trigger, пагінацією, binary data — 1–2 тижні. Вартість розраховується індивідуально після аналізу вашого API. Інвестиція в кастомну ноду окупається за рахунок автоматизації. Зв'яжіться з нами для оцінки — надішлемо кошторис протягом дня. Замовте розробку, і ваша інтеграція перестане вимагати ручного втручання.
Чому варто інвестувати в кастомну ноду?
Кастомна нода — це не просто зручність, це зниження operational overhead. Замість десятків однакових workflow ви отримуєте єдину, протестовану інтеграцію. Ми гарантуємо стабільну роботу та надаємо підтримку. Наші інженери мають досвід роботи з найрізноманітнішими API — від платіжних до CRM. Отримайте консультацію інженера — напишіть нам.
Як відбувається тестування кастомних нод?
Ми проводимо модульне та інтеграційне тестування. Впроваджуємо моки для HTTP-запитів, тестуємо граничні випадки та обробку помилок. Це гарантує стабільну роботу в бойових сценаріях. Типове покриття — близько 80% рядків коду.
Типові помилки при розробці custom nodes
- Неправильна типізація параметрів displayOptions
- Відсутність обробки помилок для кожного виклику API
- Неправильне використання credentials в execute
- Ігнорування rate limit та пагінації
- Відсутність тестів
Детальніше про створення custom nodes читайте в офіційній документації n8n.







