Розробка кастомних нод для n8n

Наша компанія займається розробкою, підтримкою та обслуговуванням сайтів будь-якої складності. Від простих односторінкових сайтів до масштабних кластерних систем, побудованих на мікро сервісах. Досвід розробників підтверджено сертифікатами від вендорів.

Розробка та обслуговування будь-яких видів сайтів:

Інформаційні сайти або веб-програми
Сайти візитки, landing page, корпоративні сайти, онлайн каталоги, квіз, промо-сайти, блоги, ресурси новин, інформаційні портали, форуми, агрегатори
Сайти або веб-програми електронної комерції
Інтернет-магазини, B2B-портали, маркетплейси, онлайн-обмінники, кешбек-сайти, біржі, дропшиппінг-платформи, парсери товарів
Веб-програми для управління бізнес-процесами
CRM-системи, ERP-системи, корпоративні портали, системи управління виробництвом, парсери інформації
Сайти або веб-програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, конструктори сайтів, портали надання електронних послуг, відеохостинги, тематичні портали

Це лише деякі з технічних типів сайтів, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

Пропоновані послуги
Показано 1 з 1 послугУсі 2065 послуг
Розробка кастомних нод для n8n
Середня
~3-5 робочих днів
Часті питання

Наші компетенції:

Етапи розробки

Останні роботи

  • image_website-b2b-advance_0.png
    Розробка сайту компанії B2B ADVANCE
    1262
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1171
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    874
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1094
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    831
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Розробка веб-сайту для компанії ФІКСПЕР
    851

Розробка кастомних нод для n8n

Коли вбудованих нод n8n недостатньо, розробляються custom nodes — TypeScript-пакети, які додаються в інсталяцію n8n та працюють як нативні ноди в редакторі.

Структура кастомної ноди

my-n8n-nodes/
├── nodes/
│   └── MyService/
│       ├── MyService.node.ts   # Основна нода
│       ├── MyService.node.json # Мета-дані
│       └── myservice.svg       # Іконка
├── credentials/
│   └── MyServiceApi.credentials.ts
├── package.json
└── tsconfig.json

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 install /path/to/my-n8n-nodes
# або з npm registry
npm install n8n-nodes-myservice
# docker-compose: монтування кастомних нод
volumes:
  - ./custom-nodes:/home/node/.n8n/custom
environment:
  N8N_CUSTOM_EXTENSIONS: "/home/node/.n8n/custom"

Терміни

Кастомна нода з 2–3 операціями + credentials — 2–4 дні. Складна нода з polling trigger, пагінацією, binary data — 1–2 тижні.