ایجاد Nodeهای سفارشی در n8n: گسترش قابلیت‌ها

فهرست مطالب

ایجاد Nodeهای سفارشی در n8n: گسترش قابلیت‌ها

در دنیای امروز که سرعت و کارایی حرف اول را می‌زند، اتوماسیون فرآیندهای کاری نقشی حیاتی در موفقیت کسب‌وکارها و پروژه‌ها ایفا می‌کند. n8n، به عنوان یک ابزار قدرتمند و متن‌باز برای اتوماسیون ورک‌فلو (workflow automation)، به کاربران این امکان را می‌دهد که با حداقل کدنویسی، سیستم‌ها و سرویس‌های مختلف را به یکدیگر متصل کرده و فرآیندهای پیچیده را به صورت خودکار اجرا کنند. این پلتفرم با رویکرد بصری خود، امکان ایجاد ورک‌فلوهایی را فراهم می‌آورد که داده‌ها را بین برنامه‌ها جابجا کرده، عملیات منطقی را اجرا نموده و وظایف تکراری را خودکارسازی می‌کنند.

n8n با ارائه مجموعه‌ای گسترده از Nodeهای آماده برای سرویس‌های محبوب مانند Slack، Google Sheets، Trello، Stripe و صدها سرویس دیگر، نیازهای بسیاری از کاربران را پوشش می‌دهد. این Nodeها بلوک‌های ساختاری ورک‌فلوها هستند که هر کدام وظیفه خاصی از قبیل دریافت داده، پردازش داده، ارسال داده به یک سرویس خارجی یا اجرای منطق شرطی را بر عهده دارند. با این حال، ماهیت پویای تکنولوژی و نیازهای خاص و منحصر به فرد هر سازمان، گاهی اوقات مستلزم قابلیت‌هایی است که حتی غنی‌ترین کتابخانه‌های Node نیز نمی‌توانند به طور کامل آن‌ها را برآورده سازند.

اینجاست که مفهوم “ایجاد Nodeهای سفارشی” در n8n اهمیت پیدا می‌کند. Nodeهای سفارشی به توسعه‌دهندگان و کاربران پیشرفته این امکان را می‌دهند که n8n را فراتر از قابلیت‌های پیش‌فرضش گسترش دهند و آن را برای سناریوهای خاص خود تنظیم کنند. چه نیاز به اتصال به یک API داخلی و اختصاصی سازمان باشد، چه پیاده‌سازی یک منطق پردازش داده بسیار پیچیده و یا ادغام با یک سرویس نوظهور که هنوز Node رسمی برای آن وجود ندارد، Nodeهای سفارشی دریچه‌ای به سوی انعطاف‌پذیری نامحدود باز می‌کنند.

توانایی ساخت Nodeهای سفارشی، n8n را از یک ابزار اتوماسیون صرف به یک پلتفرم توسعه‌ای قدرتمند تبدیل می‌کند. این قابلیت به کاربران اجازه می‌دهد که کنترل کاملی بر روی نحوه تعامل n8n با جهان خارج داشته باشند و اطمینان حاصل کنند که هیچ نیازی نادیده گرفته نمی‌شود. در این پست تخصصی، ما به عمق فرآیند ایجاد Nodeهای سفارشی در n8n خواهیم پرداخت. از پیش‌نیازهای اولیه و محیط توسعه گرفته تا طراحی، پیاده‌سازی، تست و در نهایت استقرار و اشتراک‌گذاری Nodeهای خود، تمامی مراحل را به تفصیل بررسی خواهیم کرد. هدف ما این است که شما را با دانش و ابزارهای لازم برای گسترش واقعی قابلیت‌های n8n و ساختن راه‌حل‌های اتوماسیون کاملاً سفارشی و قدرتمند مجهز کنیم.

با ما همراه باشید تا گام به گام در این مسیر هیجان‌انگیز گام برداریم و پتانسیل واقعی n8n را برای حل چالش‌های اتوماسیون شما آزاد کنیم.

پیش‌نیازها و محیط توسعه: آماده‌سازی بستر برای نوآوری

قبل از اینکه بتوانیم وارد دنیای کدنویسی و پیاده‌سازی Nodeهای سفارشی در n8n شویم، ضروری است که محیط توسعه خود را به درستی آماده کنیم و با ابزارها و پیش‌نیازهای لازم آشنا شویم. این مرحله، پایه و اساس موفقیت‌آمیز بودن فرآیند توسعه Node سفارشی را تشکیل می‌دهد.

Node.js و NPM/Yarn: ستون فقرات n8n

n8n خود بر پایه Node.js ساخته شده است، بنابراین منطقی است که Nodeهای سفارشی نیز از این بستر استفاده کنند. Node.js یک محیط اجرای جاوااسکریپت سمت سرور است که به شما امکان می‌دهد کد جاوااسکریپت را خارج از مرورگر اجرا کنید. برای توسعه Nodeهای سفارشی، شما به یک نسخه پایدار و نسبتاً جدید از Node.js نیاز دارید. توصیه می‌شود از نسخه‌های LTS (Long Term Support) مانند Node.js 16 یا بالاتر استفاده کنید. می‌توانید با دستور `node -v` در ترمینال، نسخه نصب‌شده Node.js خود را بررسی کنید. اگر Node.js نصب نیست، به وب‌سایت رسمی Node.js مراجعه کرده و نصب‌کننده مربوط به سیستم‌عامل خود را دانلود و نصب کنید.

همراه با Node.js، شما به یک مدیر بسته مانند npm (که به صورت پیش‌فرض با Node.js نصب می‌شود) یا Yarn نیاز خواهید داشت. این ابزارها برای مدیریت وابستگی‌ها (dependencies) و اسکریپت‌های پروژه Node.js شما حیاتی هستند. اکثر پروژه‌های n8n از npm استفاده می‌کنند، اما Yarn نیز کاملاً سازگار است.


# بررسی نسخه Node.js
node -v

# بررسی نسخه npm
npm -v

# (اختیاری) نصب Yarn اگر ترجیح می‌دهید
npm install -g yarn

TypeScript: قدرت برنامه‌نویسی تایپ‌شده

در حالی که جاوااسکریپت به تنهایی برای نوشتن Nodeهای سفارشی کافی است، n8n به شدت استفاده از TypeScript را توصیه و تشویق می‌کند. TypeScript یک فوق‌مجموعه (superset) از جاوااسکریپت است که قابلیت تایپ استاتیک را به آن اضافه می‌کند. این بدان معناست که شما می‌توانید انواع داده‌ها را برای متغیرها، پارامترهای توابع و مقادیر بازگشتی مشخص کنید. مزایای استفاده از TypeScript در توسعه Nodeهای سفارشی شامل موارد زیر است:

  • **اعتبار سنجی در زمان کامپایل (Compile-time Validation):** TypeScript بسیاری از خطاهای رایج برنامه‌نویسی را قبل از اجرای کد شناسایی می‌کند، که منجر به کدی باگ‌کمتر و پایدارتر می‌شود.
  • **خوانایی و نگهداری بهتر کد:** با مشخص بودن انواع داده‌ها، درک کد برای سایر توسعه‌دهندگان (و حتی خود شما در آینده) آسان‌تر می‌شود.
  • **پشتیبانی IDE پیشرفته:** ویرایشگرهایی مانند VS Code می‌توانند با استفاده از اطلاعات تایپ‌اسکریپت، قابلیت‌هایی مانند تکمیل خودکار هوشمند (IntelliSense)، پیمایش کد و بازآرایی (refactoring) را به شکل چشمگیری بهبود بخشند.
  • **مقیاس‌پذیری:** برای پروژه‌های بزرگتر و Nodeهای پیچیده‌تر، TypeScript مدیریت کد را بسیار آسان‌تر می‌کند.

پروژه اصلی n8n نیز به طور کامل با TypeScript نوشته شده است، بنابراین استفاده از آن برای Nodeهای سفارشی به شما کمک می‌کند تا با الگوهای کدنویسی و ساختارهای داده‌ای که n8n استفاده می‌کند، همگام شوید.

ویرایشگر کد: VS Code، انتخابی هوشمندانه

یک ویرایشگر کد قدرتمند و مناسب، بهره‌وری شما را در حین توسعه به شدت افزایش می‌دهد. Visual Studio Code (VS Code) یک انتخاب بسیار محبوب و توصیه شده برای توسعه Node.js و TypeScript است. این ویرایشگر رایگان، متن‌باز و دارای اکستنشن‌های فراوانی است که می‌توانند تجربه توسعه شما را بهبود بخشند. برخی از ویژگی‌های VS Code که برای توسعه Node سفارشی مفید هستند عبارتند از:

  • **پشتیبانی داخلی از TypeScript:** VS Code به صورت پیش‌فرض پشتیبانی عالی از TypeScript دارد و نیازی به پیکربندی پیچیده ندارد.
  • **دیباگر داخلی (Built-in Debugger):** امکان دیباگ کردن کد Node.js مستقیماً از ویرایشگر.
  • **پشتیبانی از Git:** ادغام آسان با کنترل نسخه Git.
  • **پلاگین‌ها:** اکستنشن‌هایی مانند Prettier (برای فرمت‌بندی کد) و ESLint (برای تحلیل استاتیک کد) می‌توانند به حفظ کیفیت و یکنواختی کد کمک کنند.

نصب و راه‌اندازی n8n محلی در حالت توسعه

برای توسعه و تست Nodeهای سفارشی، شما به یک نمونه در حال اجرای n8n نیاز دارید. بهترین روش برای این منظور، راه‌اندازی n8n به صورت محلی و در حالت توسعه (development mode) است. این کار به n8n اجازه می‌دهد تا Nodeهای سفارشی شما را که در حین توسعه هستند، شناسایی و بارگذاری کند.

روش‌های نصب n8n محلی:

  1. **با استفاده از npm (توصیه شده برای توسعه):**
    
            # یک پوشه برای پروژه n8n خود ایجاد کنید
            mkdir n8n-dev && cd n8n-dev
    
            # n8n را به عنوان یک وابستگی در پروژه محلی نصب کنید
            npm install n8n
    
            # n8n را در حالت توسعه اجرا کنید.
            # N8N_DEVELOPMENT_MODE=true برای بارگذاری Nodeهای سفارشی ضروری است.
            N8N_DEVELOPMENT_MODE=true npm run n8n start
            

    در این روش، n8n در مسیر `node_modules/n8n` نصب می‌شود. فایل‌های Node سفارشی شما باید به گونه‌ای لینک شوند که n8n بتواند آن‌ها را پیدا کند، که در بخش‌های بعدی توضیح داده خواهد شد.

  2. **با استفاده از Docker:**

    اگرچه Docker برای محیط‌های تولیدی عالی است، اما برای توسعه Nodeهای سفارشی ممکن است کمی پیچیده‌تر باشد زیرا نیاز به mount کردن پوشه‌های کد به داخل کانتینر دارد. با این حال، اگر با Docker راحت هستید، می‌توانید از آن استفاده کنید:

    
            docker run -it --rm \
                -p 5678:5678 \
                -e N8N_DEVELOPMENT_MODE=true \
                -v ~/.n8n:/home/node/.n8n \
                -v /path/to/your/custom/nodes:/root/.n8n/custom \ # این مسیر برای Nodeهای سفارشی شماست
                n8nio/n8n
            

    توجه داشته باشید که مسیر `/path/to/your/custom/nodes` باید به پوشه‌ای در سیستم فایل میزبان شما اشاره کند که Nodeهای سفارشی شما در آن قرار دارند.

هنگامی که n8n در حالت توسعه اجرا می‌شود، شما می‌توانید از رابط کاربری آن (معمولاً در `http://localhost:5678`) برای ایجاد و تست ورک‌فلوها با Node سفارشی خود استفاده کنید. حالت توسعه همچنین باعث می‌شود که n8n به طور خودکار تغییرات در فایل‌های Node سفارشی را تشخیص داده و Nodeها را مجدداً بارگذاری کند (گاهی اوقات نیاز به یک راه‌اندازی مجدد کوچک Workflows در n8n UI هست)، که فرآیند توسعه را بسیار سریع‌تر می‌کند.

با آماده‌سازی صحیح این پیش‌نیازها و محیط توسعه، شما آماده‌اید تا به سراغ ساختار داخلی Nodeهای n8n و سپس طراحی و پیاده‌سازی Nodeهای سفارشی خود بروید. این آمادگی تضمین می‌کند که فرآیند توسعه شما هموار، کارآمد و لذت‌بخش خواهد بود.

ساختار یک Node در n8n: کالبدشکافی بلوک‌های سازنده

برای اینکه بتوانیم یک Node سفارشی کارآمد و پایدار در n8n بسازیم، درک عمیقی از ساختار داخلی و اجزای تشکیل‌دهنده یک Node ضروری است. هر Node در n8n از چندین فایل و مفهوم کلیدی تشکیل شده است که هر کدام وظیفه مشخصی را بر عهده دارند.

یک Node سفارشی در n8n معمولاً به عنوان یک پکیج Node.js مجزا در نظر گرفته می‌شود، حتی اگر در ابتدا تنها شامل یک یا چند فایل باشد. این پکیج شامل ساختار دایرکتوری و فایل‌هایی است که n8n برای شناسایی، نمایش و اجرای Node شما به آن‌ها نیاز دارد.

ساختار دایرکتوری Node سفارشی

به طور معمول، یک پکیج Node سفارشی دارای ساختار دایرکتوری زیر است:


my-custom-node-package/
├── package.json
├── tsconfig.json
├── src/
│   ├── nodes/
│   │   ├── MyCustomNode.node.ts       # منطق اصلی Node
│   │   └── MyCustomNodeDescription.ts # تعریف UI Node
│   └── credentials/ (اختیاری)
│       └── MyCustomCredential.credentials.ts # تعریف Credential
├── .gitignore
└── README.md

بیایید اجزای اصلی این ساختار را به تفصیل بررسی کنیم:

۱. `package.json`: شناسنامه پکیج

هر پکیج Node.js، از جمله پکیج Node سفارشی شما، دارای یک فایل `package.json` است. این فایل شامل متادیتا و اطلاعات پیکربندی پروژه است. برای یک Node سفارشی، این فایل اطلاعاتی مانند نام پکیج، نسخه، نویسنده، و مهمتر از همه، وابستگی‌ها (dependencies) و اسکریپت‌های بیلد (build scripts) را مشخص می‌کند.

مثال ساده از `package.json`:


{
  "name": "n8n-nodes-mycustomnode",
  "version": "1.0.0",
  "description": "This is my custom n8n node package.",
  "scripts": {
    "build": "tsc",
    "watch": "tsc --watch",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [
    "n8n",
    "n8n-node",
    "mycustomnode"
  ],
  "author": "Your Name",
  "license": "MIT",
  "devDependencies": {
    "n8n-workflow": "^1.0.0",
    "typescript": "^4.0.0"
  },
  "dependencies": {
    "axios": "^0.21.1" // برای مثال، اگر از axios برای درخواست‌های API استفاده می‌کنید
  }
}

نکات کلیدی:

  • `name`: نام پکیج شما. n8n اغلب از پیشوند `n8n-nodes-` برای پکیج‌های Node استفاده می‌کند (مثلاً `n8n-nodes-mycustomnode`).
  • `devDependencies`: شامل وابستگی‌هایی مانند `n8n-workflow` (که شامل تایپ‌های n8n است) و `typescript`.
  • `dependencies`: شامل هر پکیج دیگری که Node شما برای اجرای منطق خود نیاز دارد (مانند `axios` برای درخواست‌های HTTP).
  • `scripts`: اسکریپت‌های لازم برای بیلد و تست. `tsc` برای کامپایل TypeScript به جاوااسکریپت استفاده می‌شود.

۲. `tsconfig.json`: پیکربندی TypeScript

اگر از TypeScript استفاده می‌کنید (که شدیداً توصیه می‌شود)، به یک فایل `tsconfig.json` نیاز دارید تا تنظیمات کامپایلر TypeScript را مشخص کنید. این فایل به کامپایلر می‌گوید که چگونه فایل‌های `.ts` شما را به `.js` تبدیل کند.


{
  "compilerOptions": {
    "target": "es2020",
    "module": "commonjs",
    "lib": ["es2020", "dom"],
    "declaration": true,
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true,
    "outDir": "./dist", // پوشه‌ای که فایل‌های جاوااسکریپت کامپایل‌شده در آن قرار می‌گیرند
    "rootDir": "./src"  // پوشه‌ای که فایل‌های سورس TypeScript در آن قرار دارند
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules", "dist"]
}

۳. `src/nodes/MyCustomNode.node.ts`: منطق اصلی Node

این فایل قلب Node شماست و حاوی منطق اجرایی آن است. یک Node باید از رابط `INodeType` (یا کلاس `Node` که آن را implements می‌کند) در `n8n-workflow` ارث‌بری کند. مهمترین بخش این فایل، متد `execute` است که هر زمان Node در یک ورک‌فلو اجرا می‌شود، فراخوانی می‌گردد.


import { INodeType, INodeTypeDescription } from 'n8n-workflow';

export class MyCustomNode implements INodeType {
  description: INodeTypeDescription = {
    // ارجاع به فایل توضیحات Node
    displayName: 'My Custom Node',
    name: 'myCustomNode',
    group: ['transform'],
    version: 1,
    description: 'A custom node for n8n',
    defaults: {
      value: {},
    },
    inputs: ['main'],
    outputs: ['main'],
    properties: [
      // اینجا می‌توان پارامترهای Node را تعریف کرد، اما بهتر است در فایل جداگانه انجام شود.
    ],
  };

  async execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {
    const items = this.getInputData(); // دریافت داده‌های ورودی
    const returnItems: INodeExecutionData[] = [];

    for (const item of items) {
      // دسترسی به پارامترهای Node
      const myParameter = this.getNodeParameter('myParameterName', item.itemIndex) as string;

      // اجرای منطق اصلی Node
      const result = `Hello, ${myParameter}!`;

      // اضافه کردن نتایج به خروجی
      returnItems.push({
        json: {
          outputData: result,
        },
        pairedItem: {
          item: item.itemIndex,
        },
      });
    }

    return [returnItems];
  }
}

۴. `src/nodes/MyCustomNodeDescription.ts`: تعریف رابط کاربری Node

این فایل تعریف UI (رابط کاربری) و پارامترهای Node شما را در محیط n8n فراهم می‌کند. این بخش از نوع `INodeTypeDescription` است و مشخص می‌کند که Node شما چگونه در رابط کاربری n8n ظاهر شود، چه پارامترهایی داشته باشد، چه ورودی‌ها و خروجی‌هایی بپذیرد و سایر جزئیات مربوط به نمایش آن. این فایل معمولاً به صورت یک آبجکت `INodeTypeDescription` اکسپورت می‌شود و در فایل منطق اصلی Node به آن ارجاع داده می‌شود.


import { INodeTypeDescription } from 'n8n-workflow';

export const MyCustomNodeDescription: INodeTypeDescription = {
  displayName: 'My Custom Node',
  name: 'myCustomNode', // باید با name در Node.node.ts یکسان باشد
  group: ['examples'],
  version: 1,
  description: 'This is an example custom node that greets the user.',
  defaults: {
    value: {},
  },
  inputs: ['main'],
  outputs: ['main'],
  properties: [
    {
      displayName: 'Your Name',
      name: 'myName',
      type: 'string',
      default: 'World',
      placeholder: 'Enter your name',
      description: 'The name to greet.',
    },
    {
      displayName: 'Operation Type',
      name: 'operation',
      type: 'options',
      options: [
        {
          name: 'Say Hello',
          value: 'sayHello',
          description: 'Says hello to the provided name.',
        },
        {
          name: 'Say Goodbye',
          value: 'sayGoodbye',
          description: 'Says goodbye to the provided name.',
        },
      ],
      default: 'sayHello',
      description: 'Choose the operation to perform.',
    },
    {
      displayName: 'Include Timestamp',
      name: 'includeTimestamp',
      type: 'boolean',
      default: false,
      description: 'Whether to include a timestamp in the output.',
      displayOptions: {
        show: {
          operation: ['sayHello'], // این فیلد فقط زمانی نمایش داده می‌شود که operation = 'sayHello'
        },
      },
    },
  ],
};

۵. `src/credentials/MyCustomCredential.credentials.ts` (اختیاری): مدیریت اعتبارنامه‌ها

اگر Node سفارشی شما نیاز به احراز هویت با یک سرویس خارجی (مانند API Key، OAuth Token یا نام کاربری و رمز عبور) دارد، باید یک Credential سفارشی برای آن تعریف کنید. این فایل مسئول تعریف فیلدهای مورد نیاز برای ذخیره اطلاعات احراز هویت است و از رابط `ICredentialType` استفاده می‌کند.


import { ICredentialType, INodeProperties } from 'n8n-workflow';

export class MyCustomApi implements ICredentialType {
  name = 'myCustomApi';
  displayName = 'My Custom API Credential';
  properties: INodeProperties[] = [
    {
      displayName: 'API Key',
      name: 'apiKey',
      type: 'string',
      default: '',
      typeOptions: { password: true }, // برای مخفی کردن ورودی
      description: 'The API Key for My Custom Service.',
    },
    {
      displayName: 'Base URL',
      name: 'baseUrl',
      type: 'string',
      default: 'https://api.mycustomservice.com',
      description: 'The base URL for My Custom Service API.',
    },
  ];
}

این فایل‌ها و ساختار دایرکتوری، بلوک‌های اساسی را برای ساخت یک Node سفارشی در n8n فراهم می‌کنند. درک صحیح نقش هر یک از این اجزا، کلید توسعه Nodeهای قدرتمند و قابل نگهداری است. با این دانش، می‌توانیم به فاز طراحی مفهومی Node سفارشی خود بپردازیم.

طراحی Node سفارشی: فاز مفهومی و برنامه‌ریزی استراتژیک

پیش از غرق شدن در دنیای کدنویسی، یک مرحله حیاتی وجود دارد که اغلب نادیده گرفته می‌شود اما تأثیر چشمگیری بر موفقیت و کارایی Node سفارشی شما خواهد داشت: فاز طراحی مفهومی. در این مرحله، ما هدف، Scope، ورودی‌ها، خروجی‌ها و سایر جنبه‌های Node خود را به دقت تعریف و برنامه‌ریزی می‌کنیم. یک طراحی قوی، زمان توسعه را کاهش داده، از خطاهای احتمالی جلوگیری می‌کند و اطمینان می‌دهد که Node شما نیازهای واقعی را برآورده می‌کند.

تعیین هدف و Scope: چرا این Node را می‌سازیم؟

اولین گام، تعریف واضح هدف Node سفارشی شماست. از خود بپرسید:

  • این Node قرار است چه مشکلی را حل کند؟
  • چه وظیفه‌ای را در یک ورک‌فلو انجام می‌دهد؟
  • با چه سیستم‌ها یا APIهایی قرار است تعامل داشته باشد؟
  • آیا این Node یک عملیات خواندن (Read)، نوشتن (Write)، به‌روزرسانی (Update) یا حذف (Delete) انجام می‌دهد؟ یا ترکیبی از آن‌ها؟

تعیین Scope نیز به همان اندازه مهم است. آیا Node شما قرار است یک وظیفه بسیار خاص و کوچک را انجام دهد، یا یک عملیات پیچیده‌تر با چندین گزینه؟ تلاش برای گنجاندن بیش از حد قابلیت‌ها در یک Node می‌تواند آن را پیچیده و نگهداری آن را دشوار کند. گاهی اوقات بهتر است یک عملیات پیچیده را به چند Node کوچکتر و تخصصی‌تر تقسیم کرد.

مثال:
هدف: یک Node برای تعامل با API سرویس مدیریت پروژه “ProjectMaster”.
Scope: در ابتدا، Node می‌تواند شامل عملیات “ایجاد پروژه جدید” و “دریافت لیست پروژه‌ها” باشد. عملیات‌های پیچیده‌تر مانند “مدیریت وظایف پروژه” می‌تواند در Nodeهای جداگانه یا نسخه‌های بعدی اضافه شود.

ورودی‌ها و خروجی‌ها: جریان داده‌ها

در n8n، داده‌ها بین Nodeها به صورت آرایه‌ای از آبجکت‌های JSON منتقل می‌شوند. درک دقیق اینکه Node شما چه نوع داده‌ای را به عنوان ورودی انتظار دارد و چه نوع داده‌ای را به عنوان خروجی تولید می‌کند، حیاتی است.

  • **ورودی‌ها (Inputs):**
    • Node شما چه فیلدهایی را در آبجکت‌های JSON ورودی نیاز دارد؟
    • آیا این فیلدها اجباری هستند؟
    • فرمت داده‌های ورودی (مثلاً رشته، عدد، آرایه، آبجکت) چیست؟
    • آیا Node شما می‌تواند چندین ورودی (مثلاً از چند ورودی متفاوت در ورک‌فلو) را مدیریت کند؟

    مثلاً، برای ایجاد پروژه جدید در ProjectMaster، ممکن است به فیلدهایی مانند `projectName`، `description`، `startDate` و `endDate` در ورودی نیاز داشته باشیم.

  • **خروجی‌ها (Outputs):**
    • پس از اجرای عملیات، Node شما چه داده‌ای را به Node بعدی ارسال می‌کند؟
    • فرمت خروجی (JSON) چگونه خواهد بود؟
    • آیا Node اطلاعاتی در مورد موفقیت/شکست عملیات، داده‌های بازگشتی از API، یا وضعیت خاصی را برمی‌گرداند؟

    برای ایجاد پروژه جدید، خروجی ممکن است شامل `projectId`، `projectName` و `status` پروژه ایجاد شده باشد. برای دریافت لیست پروژه‌ها، خروجی می‌تواند یک آرایه از آبجکت‌های پروژه باشد.

پارامترها و گزینه‌ها: کنترل کاربر

پارامترها و گزینه‌ها، ابزارهایی هستند که به کاربر نهایی امکان پیکربندی و سفارشی‌سازی رفتار Node را در رابط کاربری n8n می‌دهند. این‌ها همان فیلدهایی هستند که در بخش `properties` از `INodeTypeDescription` تعریف می‌شوند.

  • **نوع پارامتر (Parameter Type):**
    • **String:** برای ورودی‌های متنی (مثلاً نام پروژه، توضیحات).
    • **Number:** برای مقادیر عددی.
    • **Boolean:** برای گزینه‌های بله/خیر (مثلاً “پروژه فعال باشد؟”).
    • **Options:** برای انتخاب از یک لیست ثابت از گزینه‌ها (مثلاً “وضعیت پروژه: فعال، غیرفعال، معلق”).
    • **Collection:** برای گروه‌بندی چندین فیلد مرتبط (مثلاً مشخصات مدیر پروژه شامل نام، ایمیل).
    • **Fixed Collection:** شبیه به Collection اما با تعداد ثابتی از ورودی‌ها (مثلاً برای تعریف هدرهای API که همیشه دو فیلد Key و Value دارند).
    • **JSON:** برای وارد کردن داده‌های JSON خام.
    • **Credential:** برای انتخاب یک اعتبارنامه احراز هویت (API Key, OAuth).
  • **DisplayName و Name:** `displayName` نامی است که در UI به کاربر نمایش داده می‌شود، در حالی که `name` نام برنامه‌نویسی است که در کد Node برای دسترسی به مقدار آن پارامتر استفاده می‌شود.
  • **Description:** یک توضیح کوتاه و مفید برای راهنمایی کاربر.
  • **Default Value:** مقدار پیش‌فرض برای پارامتر.
  • **Display Options (Conditional Fields):** آیا پارامتری باید فقط تحت شرایط خاصی (مثلاً وقتی یک گزینه دیگر انتخاب شده است) نمایش داده شود؟ این قابلیت برای جلوگیری از شلوغی رابط کاربری و نمایش فقط فیلدهای مرتبط بسیار مهم است.

برای Node ProjectMaster، پارامترهایی مانند `Operation` (با گزینه‌های “Create Project”, “List Projects”), `Project Name` (string), `Project Description` (string) و `Project Status` (options) می‌توانند تعریف شوند. `Project Description` می‌تواند با `displayOptions` فقط زمانی نمایش داده شود که `Operation` برابر با “Create Project” باشد.

اعتبارسنجی و مدیریت خطا: استحکام و قابلیت اطمینان

Nodeهای سفارشی باید به گونه‌ای طراحی شوند که در برابر ورودی‌های نامعتبر، خطاهای API و مشکلات شبکه مقاوم باشند. برنامه‌ریزی برای اعتبارسنجی و مدیریت خطا در مرحله طراحی، از مشکلات جدی در آینده جلوگیری می‌کند.

  • **اعتبارسنجی ورودی (Input Validation):**
    • آیا پارامترهای اجباری وارد شده‌اند؟
    • آیا داده‌ها در فرمت صحیح هستند (مثلاً ایمیل معتبر، عدد در محدوده خاص)؟
    • آیا می‌توانیم برخی از اعتبارسنجی‌ها را در UI انجام دهیم (مثلاً با استفاده از `typeOptions` خاص) یا باید در کد Node بررسی شوند؟
  • **مدیریت خطا (Error Handling):**
    • Node شما چگونه با خطاهای API (مثل کد وضعیت HTTP 400، 401، 500) برخورد می‌کند؟
    • در صورت بروز خطا، آیا Node باید عملیات را متوقف کند، خطایی را به n8n گزارش دهد، یا تلاش مجدد (retry) کند؟
    • چگونه پیام‌های خطای معنی‌دار و قابل درکی به کاربر ارائه دهیم؟ (n8n دارای مکانیزم‌های داخلی برای گزارش خطاها مانند `NodeOperationError` است).
    • آیا باید از بلوک‌های `try-catch` برای مدیریت استثنائات در کد خود استفاده کنیم؟

امنیت و اعتبارسنجی (Authentication and Credentials): اتصال امن

اگر Node شما با یک سرویس خارجی تعامل دارد، تقریباً همیشه نیاز به احراز هویت خواهید داشت. n8n یک سیستم قوی برای مدیریت اعتبارنامه‌ها (Credentials) دارد که امنیت اطلاعات حساس مانند API Keyها و توکن‌ها را تضمین می‌کند.

  • **نوع احراز هویت:**
    • **API Key:** رایج‌ترین روش، که کلید در هدر یا پارامتر URL ارسال می‌شود.
    • **OAuth2:** برای سرویس‌هایی که نیاز به اجازه کاربر دارند (مثل Google، Microsoft).
    • **Basic Authentication:** نام کاربری و رمز عبور.
    • **Custom:** برای هر مکانیزم احراز هویت دیگری که سرویس هدف شما نیاز دارد.
  • **تعریف Credential:** برنامه‌ریزی کنید که چه فیلدهایی برای Credential شما لازم است (مثلاً `apiKey`, `clientId`, `clientSecret`, `redirectUrl`).
  • **استفاده از Credential در Node:** چگونه Node شما به اطلاعات Credential ذخیره‌شده دسترسی پیدا می‌کند و از آن‌ها در درخواست‌های API استفاده می‌کند؟
  • **امنیت:** هرگز اطلاعات حساس را مستقیماً در کد Node ذخیره نکنید. همیشه از سیستم Credential n8n استفاده کنید.

با اتمام فاز طراحی، شما یک نقشه راه دقیق برای پیاده‌سازی Node سفارشی خود خواهید داشت. این سند مفهومی به عنوان یک مرجع در طول فرآیند توسعه عمل می‌کند و به شما کمک می‌کند تا تمرکز خود را حفظ کرده و Nodeی بسازید که دقیقاً مطابق انتظارات شما عمل کند.

پیاده‌سازی Node: گام به گام تا تولد یک Node سفارشی

پس از مرحله دقیق طراحی مفهومی، زمان آن رسیده است که ایده‌ها را به واقعیت تبدیل کنیم و Node سفارشی خود را کدنویسی کنیم. این بخش، عمیق‌ترین و جامع‌ترین قسمت از فرآیند توسعه Node سفارشی در n8n است و تمام جزئیات مربوط به پیاده‌سازی را پوشش می‌دهد.

۱. ایجاد ساختار اولیه پروژه Node

توصیه می‌شود از ابزار خط فرمان n8n برای ایجاد یک پروژه Node سفارشی استفاده کنید، زیرا این ابزار بسیاری از تنظیمات اولیه و فایل‌های boilerplate را برای شما ایجاد می‌کند.

در دایرکتوری که می‌خواهید پروژه Node شما در آن قرار گیرد، دستور زیر را اجرا کنید:


npx n8n generate:node

این دستور از شما سوالاتی مانند نام Node، نام پکیج، توضیحات و غیره را خواهد پرسید و ساختار پروژه (شامل `package.json`, `tsconfig.json`, `src/nodes/MyNode.node.ts` و `src/nodes/MyNodeDescription.ts`) را با مقادیر پیش‌فرض ایجاد می‌کند. پس از ایجاد، به دایرکتوری پروژه جدید خود بروید (`cd n8n-nodes-yourpackage`) و وابستگی‌ها را نصب کنید:


npm install

اگر ترجیح می‌دهید به صورت دستی پروژه را ایجاد کنید، باید پوشه‌های `src/nodes` و `src/credentials` را ایجاد کرده و فایل‌های `package.json` و `tsconfig.json` را مطابق بخش “ساختار یک Node در n8n” تنظیم کنید و سپس `npm install` را اجرا کنید.

۲. تعریف رابط کاربری Node در `MyCustomNodeDescription.ts`

این فایل مسئول تعریف ظاهر و پارامترهای Node شما در رابط کاربری n8n است. شما باید آبجکت `MyCustomNodeDescription` را از نوع `INodeTypeDescription` تعریف کنید.

پارامترهای اصلی:

  • `displayName` (string): نامی که در UI n8n به کاربر نمایش داده می‌شود.
  • `name` (string): یک شناسه منحصر به فرد و برنامه‌نویسی‌شده برای Node شما. باید با `name` در فایل اصلی Node مطابقت داشته باشد.
  • `group` (string[]): دسته‌بندی که Node شما در پنل Nodeها قرار می‌گیرد (مثلاً `[‘transform’]`, `[‘trigger’]`, `[‘utility’]`).
  • `version` (number): شماره نسخه Node شما.
  • `description` (string): توضیح مختصری درباره عملکرد Node.
  • `defaults` (object): مقادیر پیش‌فرض برای پیکربندی‌های داخلی n8n، معمولاً `value: {}`.
  • `inputs` (string[]): تعداد و نام ورودی‌ها. معمولاً `[‘main’]`.
  • `outputs` (string[]): تعداد و نام خروجی‌ها. معمولاً `[‘main’]`.

تعریف `properties` (پارامترهای کاربر):

آرایه `properties` حاوی تعاریف تمام پارامترهایی است که کاربر می‌تواند در UI پیکربندی کند. هر عنصر این آرایه یک آبجکت از نوع `INodeProperties` است.


import { INodeTypeDescription, INodeProperties } from 'n8n-workflow';

export const MyCustomNodeDescription: INodeTypeDescription = {
  // ... سایر مشخصات Node ...
  properties: [
    // پارامترهای عمومی
    {
      displayName: 'Operation',
      name: 'operation',
      type: 'options',
      options: [
        {
          name: 'Create Item',
          value: 'create',
          action: 'Create an item in My Custom Service',
        },
        {
          name: 'Get Item',
          value: 'get',
          action: 'Get an item from My Custom Service',
        },
      ],
      default: 'create',
      description: 'The operation to perform on My Custom Service.',
      no

e, you can implement the API call.
      const apiKey = await this.getCredentials('myCustomApi') as IDataObject; // Accessing credential
      const baseUrl = apiKey.baseUrl as string;

      // Make API call based on operation
      if (operation === 'create') {
        const itemName = this.getNodeParameter('itemName', item.itemIndex) as string;
        const itemDescription = this.getNodeParameter('itemDescription', item.itemIndex) as string;
        const isActive = this.getNodeParameter('isActive', item.itemIndex) as boolean;

        // Example API call using axios (npm install axios)
        const response = await axios.post(`${baseUrl}/items`, {
          name: itemName,
          description: itemDescription,
          active: isActive,
        }, {
          headers: {
            'Authorization': `Bearer ${apiKey.apiKey}`,
            'Content-Type': 'application/json',
          },
        });

        // Add the response data to the output
        returnItems.push({
          json: {
            message: 'Item created successfully!',
            data: response.data,
          },
          pairedItem: {
            item: item.itemIndex,
          },
        });

      } else if (operation === 'get') {
        const itemId = this.getNodeParameter('itemId', item.itemIndex) as string;

        const response = await axios.get(`${baseUrl}/items/${itemId}`, {
          headers: {
            'Authorization': `Bearer ${apiKey.apiKey}`,
          },
        });

        returnItems.push({
          json: {
            message: `Item ${itemId} retrieved.`,
            data: response.data,
          },
          pairedItem: {
            item: item.itemIndex,
          },
        });
      }
    } catch (error) {
      // Handle errors
      if (this.continueOnFail()) {
        // If "Continue On Fail" is checked, add error to current item
        items[item.itemIndex].json.error = error.message;
        returnItems.push(items[item.itemIndex]);
      } else {
        // Otherwise, throw an error to stop the workflow or catch with error handling node
        throw new NodeOperationError(this.getNode(), error);
      }
    }

    return [returnItems];
  }
}

توضیحات کلیدی:

  • `this.getInputData()`: یک آرایه از `INodeExecutionData` را برمی‌گرداند که حاوی داده‌های ورودی هر آیتم است.
  • `this.getNodeParameter(name, itemIndex, defaultValue)`: مقدار یک پارامتر Node را برمی‌گرداند. `itemIndex` مهم است زیرا پارامترها می‌توانند برای هر آیتم ورودی متفاوت باشند.
  • `this.getCredentials(credentialName)`: برای دسترسی به مقادیر Credential ذخیره شده.
  • `this.helpers.httpRequest()`: یک متد کمکی برای ساخت درخواست‌های HTTP که قابلیت‌هایی مانند retry و مدیریت خطا را دارد. استفاده از این متد به جای `axios` توصیه می‌شود، اما `axios` نیز قابل استفاده است.
  • `this.helpers.returnJsonArray(data)`: برای فرمت‌بندی و برگرداندن داده‌ها به عنوان خروجی Node.
  • `try…catch`: برای مدیریت خطاهای احتمالی در حین اجرای API callها یا پردازش داده‌ها ضروری است.
  • `NodeOperationError`: نوع خطایی است که n8n آن را می‌شناسد و به کاربر در UI نمایش می‌دهد.

۴. استفاده از Credentials: اتصال امن به سرویس‌ها

اگر Node شما نیاز به احراز هویت دارد، باید یک Credential سفارشی تعریف کرده و از آن در Node اصلی استفاده کنید.

الف. تعریف Credential در `src/credentials/MyCustomCredential.credentials.ts`:


import { ICredentialType, INodeProperties } from 'n8n-workflow';

export class MyCustomApi implements ICredentialType {
  name = 'myCustomApi'; // شناسه منحصر به فرد Credential
  displayName = 'My Custom API'; // نامی که در UI نمایش داده می‌شود
  properties: INodeProperties[] = [
    {
      displayName: 'API Key',
      name: 'apiKey',
      type: 'string',
      default: '',
      typeOptions: { password: true }, // برای نمایش به صورت رمز عبور
      description: 'The API Key for My Custom Service.',
    },
    {
      displayName: 'Base URL',
      name: 'baseUrl',
      type: 'string',
      default: 'https://api.example.com/v1',
      description: 'The base URL for My Custom Service API.',
    },
  ];
}

ب. ارجاع به Credential در `MyCustomNodeDescription.ts`:

در فایل `MyCustomNodeDescription.ts`، یک پارامتر از نوع `credential` اضافه کنید:


import { INodeTypeDescription, INodeProperties } from 'n8n-workflow';

export const MyCustomNodeDescription: INodeTypeDescription = {
  // ...
  properties: [
    {
      displayName: 'Credential',
      name: 'myCustomApi', // باید با name در Credential.credentials.ts یکسان باشد
      type: 'credential',
      default: 'myCustomApi',
      required: true,
      credentialNames: ['myCustomApi'], // لیست Credentialهایی که این Node می‌تواند استفاده کند
      description: 'The credential to use for My Custom Service.',
    },
    // ... سایر پارامترها ...
  ],
};

ج. دسترسی به Credential در `MyCustomNode.node.ts`:

همانطور که در مثال متد `execute` نشان داده شد، از `await this.getCredentials(‘myCustomApi’)` برای بازیابی اطلاعات Credential استفاده کنید.

با اتمام این مراحل، Node سفارشی شما از نظر کدنویسی کامل است. حال باید آن را تست و عیب‌یابی کنیم تا از عملکرد صحیح آن اطمینان حاصل شود.

تست و عیب‌یابی: اطمینان از عملکرد بی‌نقص Node سفارشی

پس از پیاده‌سازی Node سفارشی، مرحله حیاتی تست و عیب‌یابی آغاز می‌شود. این مرحله تضمین می‌کند که Node شما همان‌طور که انتظار می‌رود عمل می‌کند، خطاهای احتمالی را به درستی مدیریت می‌کند و با سایر اجزای n8n سازگار است. نادیده گرفتن تست می‌تواند منجر به مشکلات عملکردی و امنیتی در ورک‌فلوهای تولیدی شود.

۱. راه‌اندازی n8n در حالت توسعه (Development Mode)

برای تست Node سفارشی، n8n باید در حالت توسعه اجرا شود تا بتواند Nodeهای محلی شما را شناسایی و بارگذاری کند. همانطور که در بخش پیش‌نیازها توضیح داده شد، این کار با تنظیم متغیر محیطی `N8N_DEVELOPMENT_MODE=true` انجام می‌شود:


N8N_DEVELOPMENT_MODE=true npm run n8n start

اگر Node شما در یک پکیج Node.js جداگانه قرار دارد (که بهترین روش است)، باید این پکیج را به n8n اصلی لینک کنید تا n8n بتواند آن را پیدا کند. این کار معمولاً با استفاده از `npm link` یا `yarn link` انجام می‌شود:

  1. در دایرکتوری پروژه Node سفارشی خود:
    
            npm run build # اطمینان حاصل کنید که Node کامپایل شده است
            npm link
            
  2. در دایرکتوری نصب n8n (جایی که `package.json` اصلی n8n قرار دارد، مثلاً `n8n-dev` که قبلاً ساختید):
    
            npm link n8n-nodes-mycustomnode # نام پکیج شما
            

پس از لینک کردن، n8n را مجدداً راه‌اندازی کنید تا Node سفارشی شما در پالت Nodeها ظاهر شود. اگر Node را در حین اجرای n8n تغییر دادید، با اجرای `npm run watch` در دایرکتوری Node سفارشی و سپس ذخیره فایل‌ها، تغییرات به صورت خودکار کامپایل می‌شوند. ممکن است لازم باشد ورک‌فلو را در UI n8n مجدداً فعال (deactivate/activate) کنید تا n8n تغییرات را تشخیص دهد.

۲. تست در رابط کاربری n8n

ساده‌ترین و مستقیم‌ترین روش تست، ایجاد یک ورک‌فلو جدید در UI n8n و استفاده از Node سفارشی خود است. مراحل زیر را دنبال کنید:

  • **ایجاد ورک‌فلو:** یک ورک‌فلو جدید ایجاد کنید. می‌توانید یک Node `Start` ساده یا یک Node `Webhook` برای تریگر کردن آن اضافه کنید.
  • **اضافه کردن Node سفارشی:** Node سفارشی خود را از پالت Nodeها پیدا کرده و به ورک‌فلو اضافه کنید.
  • **پیکربندی پارامترها:** تمام پارامترهای Node را با مقادیر مختلف و حالت‌های گوناگون پیکربندی کنید. این شامل تست مقادیر پیش‌فرض، مقادیر معتبر، و مقادیر نامعتبر است تا اعتبارسنجی را بررسی کنید.
  • **تست با داده‌های ورودی:** Node قبلی (یا Node `Set`) را طوری پیکربندی کنید که داده‌های ورودی مختلفی را به Node سفارشی شما ارسال کند. مطمئن شوید که Node شما با انواع مختلف داده‌ها (مثل رشته‌های خالی، اعداد صفر، آبجکت‌های پیچیده) به درستی کار می‌کند.
  • **اجرای ورک‌فلو:** ورک‌فلو را اجرا کنید (manual run یا با تریگر کردن).
  • **بررسی خروجی:** خروجی Node سفارشی را بررسی کنید. آیا داده‌ها مطابق انتظار هستند؟ آیا فرمت خروجی صحیح است؟ آیا پیام‌های خطا در صورت بروز مشکل، واضح و معنی‌دار هستند؟

۳. استفاده از Logها و DevTools

در حین اجرای Node سفارشی، لاگ‌ها و ابزارهای توسعه می‌توانند اطلاعات ارزشمندی برای عیب‌یابی ارائه دهند:

  • **`console.log` در کد Node:** برای اشکال‌زدایی، می‌توانید از `console.log()` در کد Node خود استفاده کنید تا مقادیر متغیرها، وضعیت جریان برنامه و پاسخ‌های API را در کنسول ترمینال n8n مشاهده کنید.
    
            console.log('Input data:', JSON.stringify(item.json, null, 2));
            console.log('API response:', response.data);
            
  • **لاگ‌های n8n:** سرور n8n خود لاگ‌هایی از عملیات‌ها، خطاها و هشدارهای سیستم تولید می‌کند. این لاگ‌ها را در ترمینالی که n8n را اجرا کرده‌اید، به دقت بررسی کنید. تنظیم متغیر محیطی `N8N_LOG_LEVEL=debug` می‌تواند جزئیات بیشتری را در لاگ‌ها نمایش دهد.
  • **DevTools مرورگر:** اگر Node شما با APIهای خارجی تعامل دارد و خطاهای شبکه مشکوک هستید، می‌توانید از DevTools مرورگر خود (تب Network) برای بررسی درخواست‌های HTTP ارسال‌شده توسط n8n به APIها (البته این مورد بیشتر برای UI n8n است تا خود Node.js) استفاده کنید. برای بررسی درخواست‌های Node.js، باید به لاگ‌های سرور یا دیباگ کردن کد بپردازید.

۴. دیباگ کردن با VS Code

VS Code یک دیباگر قدرتمند داخلی برای Node.js دارد که به شما امکان می‌دهد کد TypeScript/JavaScript خود را گام به گام اجرا کرده، نقاط توقف (breakpoints) تنظیم کنید و مقادیر متغیرها را در زمان اجرا مشاهده کنید.
برای دیباگ کردن Node سفارشی خود با VS Code:

  1. **پیکربندی `launch.json`:** یک فایل `launch.json` در پوشه `.vscode` پروژه Node سفارشی خود ایجاد کنید. یک پیکربندی ساده برای اتصال به n8n در حال اجرا به شرح زیر است:
    
            {
              "version": "0.2.0",
              "configurations": [
                {
                  "type": "node",
                  "request": "attach",
                  "name": "Attach to n8n",
                  "port": 9229, // پورت دیباگ n8n
                  "restart": true,
                  "protocol": "inspector"
                }
              ]
            }
            
  2. **اجرای n8n با فلگ دیباگ:** n8n را با فلگ دیباگ ` –inspect` اجرا کنید.
    
            N8N_DEVELOPMENT_MODE=true npm run n8n start -- --inspect=9229
            

    یا اگر از `n8n-node-dev` استفاده می‌کنید:

    
            npx n8n-node-dev --inspect=9229
            
  3. **اتصال دیباگر:** در VS Code، به نمای Run and Debug بروید، پیکربندی “Attach to n8n” را انتخاب کرده و دکمه “Start Debugging” را فشار دهید.
  4. **تنظیم Breakpoints:** نقاط توقف را در کد `MyCustomNode.node.ts` خود تنظیم کنید. هنگامی که ورک‌فلو در n8n اجرا شود و به این نقاط برسد، اجرا متوقف شده و می‌توانید مقادیر متغیرها را بررسی کنید.

۵. مدیریت خطا در کد Node

اطمینان حاصل کنید که Node شما خطاهای احتمالی را به درستی گزارش می‌دهد. n8n ابزارهایی برای این منظور فراهم می‌کند:

  • `this.continueOnFail()`: بررسی می‌کند که آیا کاربر گزینه “Continue On Fail” را برای Node فعال کرده است یا خیر.
  • `this.addOutputData()` / `this.addOutputData(outputIndex, data)`: اگر `continueOnFail` فعال باشد، می‌توانید داده‌های خطا را به خروجی Node اضافه کنید.
  • `throw new NodeOperationError(this.getNode(), error)`: اگر `continueOnFail` فعال نیست، این متد باعث می‌شود که ورک‌فلو متوقف شده و خطا در UI n8n نمایش داده شود.
  • `throw new NodeApiError(this.getNode(), response, { message: ‘API error’ })`: برای خطاهای مربوط به APIها، این نوع خطا پیام‌های دقیق‌تری را فراهم می‌کند.

تست و عیب‌یابی فرآیندی تکراری است. انتظار داشته باشید که Node خود را بارها تست و اصلاح کنید تا به پایداری و عملکرد مورد نظر دست یابید. با استفاده صحیح از این ابزارها و تکنیک‌ها، می‌توانید Node سفارشی خود را به یک جزء قابل اعتماد و کارآمد در n8n تبدیل کنید.

بهینه‌سازی و بهترین شیوه‌ها: ارتقای کیفیت Node سفارشی

پس از اینکه Node سفارشی شما به درستی کار کرد و تست‌های اولیه را پشت سر گذاشت، زمان آن است که به بهترین شیوه‌ها و بهینه‌سازی‌ها فکر کنیم. هدف این مرحله، بهبود کیفیت کد، افزایش پایداری، عملکرد و قابلیت نگهداری Node است. رعایت این اصول نه تنها به شما کمک می‌کند Nodeهای قوی‌تری بسازید، بلکه همکاری با دیگران را نیز آسان‌تر می‌کند و اطمینان می‌دهد که Node شما در بلندمدت قابل اعتماد خواهد بود.

۱. استفاده کامل از TypeScript

اگرچه TypeScript را به عنوان یک پیش‌نیاز معرفی کردیم، استفاده کامل و صحیح از آن بسیار مهم است. این به معنای فقط نوشتن کد در فایل‌های `.ts` نیست، بلکه استفاده از قابلیت‌های پیشرفته آن است:

  • **تعریف اینترفیس‌ها و تایپ‌ها:** برای ورودی‌ها، خروجی‌ها و پاسخ‌های API، اینترفیس‌های (interfaces) واضح و دقیقی تعریف کنید. این کار به `IntelliSense` کمک می‌کند و تضمین می‌کند که ساختار داده‌ها ثابت می‌ماند.
    
            interface MyApiItem {
              id: string;
              name: string;
              status: 'active' | 'inactive';
            }
            
  • **تایپ کردن پارامترها و متغیرها:** همیشه پارامترهای توابع و متغیرها را با تایپ‌های مناسب مشخص کنید.
  • **Strict Mode در `tsconfig.json`:** فعال کردن `strict: true` در `tsconfig.json` باعث می‌شود TypeScript بررسی‌های سخت‌گیرانه‌تری انجام دهد و بسیاری از خطاهای پنهان را آشکار کند.

۲. مدیریت خطا قوی و کاربرپسند

یک Node خوب، علاوه بر انجام وظیفه اصلی خود، باید به خوبی با خطاها نیز برخورد کند. پیام‌های خطا باید برای کاربر نهایی معنی‌دار و راهگشا باشند:

  • **Try-Catch جامع:** هر بخش از کد که ممکن است خطا ایجاد کند (مانند فراخوانی APIها، پردازش داده‌های نامعتبر)، باید در یک بلوک `try-catch` قرار گیرد.
  • **استفاده از `NodeOperationError` و `NodeApiError`:** از کلاس‌های خطای اختصاصی n8n برای گزارش خطا استفاده کنید. این‌ها به n8n کمک می‌کنند تا خطا را به درستی در UI نمایش دهد و اطلاعات مفیدی ارائه کند.
    
            throw new NodeApiError(this.getNode(), { message: 'Failed to connect to API.' }, { statusCode: 500 });
            
  • **پیام‌های خطا واضح:** پیام‌های خطا باید دقیق باشند و کاربر را به سمت راه‌حل هدایت کنند (مثلاً “API Key نامعتبر است” به جای “خطای احراز هویت”).
  • **`continueOnFail` را در نظر بگیرید:** Node خود را طوری طراحی کنید که اگر گزینه `continueOnFail` فعال بود، بتواند خطا را به عنوان بخشی از خروجی برگرداند تا ورک‌فلو متوقف نشود.

۳. مستندسازی کد و استفاده از JSDoc

کد شما باید خوانا و قابل درک باشد، حتی بدون توضیح اضافی. با این حال، مستندسازی مناسب با JSDoc به بهبود درک کد کمک می‌کند و ابزارهای توسعه را نیز بهره‌مند می‌سازد:

  • **توضیحات برای توابع و کلاس‌ها:** هر کلاس، متد یا تابع مهم را با JSDoc مستند کنید.
    
            /**
             * Creates a new item in My Custom Service.
             * @param {string} itemName - The name of the item to create.
             * @param {string} itemDescription - The description of the item.
             * @returns {Promise<MyApiItem>} The created item object.
             */
            async function createItem(itemName: string, itemDescription: string): Promise<MyApiItem> {
              // ... implementation ...
            }
            
  • **نکات مهم در خطوط کد:** از کامنت‌ها (`//` یا `/* */`) برای توضیح بخش‌های پیچیده یا غیرواضح کد استفاده کنید.
  • **README.md جامع:** یک فایل `README.md` در ریشه پکیج Node خود ایجاد کنید که شامل دستورالعمل‌های نصب، پیکربندی، مثال‌های استفاده و جزئیات API باشد.

۴. عملکرد (Performance)

برای Nodeهایی که با حجم زیادی از داده‌ها کار می‌کنند یا عملیات‌های سنگینی انجام می‌دهند، عملکرد بسیار مهم است:

  • **درخواست‌های API کارآمد:**
    • **Batching (بچینگ):** اگر API مقصد از بچینگ پشتیبانی می‌کند، درخواست‌های متعدد را در یک درخواست واحد گروه‌بندی کنید تا تعداد رفت و برگشت‌های شبکه کاهش یابد.
    • **Pagination (صفحه‌بندی):** برای بازیابی لیست‌های بزرگ، از مکانیزم صفحه‌بندی API استفاده کنید تا همه داده‌ها یکباره بارگذاری نشوند.
    • **کش کردن (Caching):** برای داده‌هایی که کمتر تغییر می‌کنند، مکانیزم‌های کش ساده را در نظر بگیرید (اگرچه n8n به طور پیش‌فرض کش خاصی برای Nodeها ندارد).
  • **پردازش داده کارآمد:** از الگوریتم‌های بهینه برای پردازش داده‌ها در داخل Node استفاده کنید. از حلقه‌های تو در تو غیرضروری و عملیات‌های سنگین در حلقه‌های بزرگ خودداری کنید.

۵. امنیت (Security)

امنیت در هر Node سفارشی که با داده‌های حساس یا سرویس‌های خارجی تعامل دارد، از اهمیت بالایی برخوردار است:

  • **مدیریت Credentials:** همیشه از سیستم Credential n8n برای ذخیره اطلاعات حساس (API Key، توکن‌ها) استفاده کنید. هرگز این اطلاعات را به صورت hardcode در کد Node قرار ندهید یا در لاگ‌ها چاپ نکنید.
  • **اعتبارسنجی ورودی:** ورودی‌های کاربر را به دقت اعتبارسنجی کنید تا از حملاتی مانند Injection (SQL Injection, Command Injection) جلوگیری شود.
  • **اصل حداقل امتیاز (Principle of Least Privilege):** فقط دسترسی‌های مورد نیاز Node را به سرویس‌های خارجی بدهید (مثلاً فقط دسترسی خواندن اگر Node فقط قرار است داده‌ای را بخواند).
  • **به‌روز نگه داشتن وابستگی‌ها:** وابستگی‌های پکیج Node خود را به صورت منظم به‌روزرسانی کنید تا از آسیب‌پذیری‌های امنیتی شناخته‌شده در کتابخانه‌های شخص ثالث جلوگیری شود.

۶. سازگاری با نسخه‌های جدید n8n

n8n یک پروژه فعال است و به طور منظم به‌روزرسانی می‌شود. ممکن است تغییراتی در API داخلی آن ایجاد شود که Node سفارشی شما را تحت تأثیر قرار دهد:

  • **بررسی مستندات n8n:** به طور منظم مستندات توسعه‌دهندگان n8n را برای اطلاع از تغییرات API و بهترین شیوه‌های جدید بررسی کنید.
  • **تست با نسخه‌های جدید:** Node سفارشی خود را با نسخه‌های بتا یا جدید n8n تست کنید تا از سازگاری اطمینان حاصل کنید.
  • **استفاده از نسخه‌های پایدار:** در `package.json` خود، نسخه‌های وابستگی‌های n8n (مانند `n8n-workflow`) را به گونه‌ای مشخص کنید که فقط به‌روزرسانی‌های جزئی و پچ‌ها را دریافت کنند (مثلاً `^1.0.0` به جای `*`) تا از تغییرات ناگهانی جلوگیری شود.

۷. ساختاردهی کد برای Nodeهای پیچیده

برای Nodeهای بسیار پیچیده با چندین عملیات، ممکن است نیاز به سازماندهی پیشرفته‌تری داشته باشید:

  • **تقسیم منطق:** منطق پیچیده را به توابع کمکی (helper functions) کوچک‌تر و ماژولار تقسیم کنید. می‌توانید یک پوشه `utils` یا `helpers` در کنار `nodes` و `credentials` ایجاد کنید.
  • **استفاده از کلاس‌ها:** برای عملیات‌های خاص، می‌توانید کلاس‌های مجزا تعریف کنید که متدهای مربوط به آن عملیات را encapsulate کنند.

با رعایت این بهترین شیوه‌ها، Node سفارشی شما نه تنها به درستی کار خواهد کرد، بلکه یک دارایی ارزشمند، پایدار و قابل نگهداری برای هر محیط n8n خواهد بود. این رویکرد به شما اطمینان می‌دهد که سرمایه‌گذاری شما در توسعه Node سفارشی، در بلندمدت نتیجه‌بخش خواهد بود.

استقرار و اشتراک‌گذاری: رساندن Node سفارشی به دست کاربران

پس از اینکه Node سفارشی شما با موفقیت توسعه، تست و بهینه‌سازی شد، آخرین مرحله این است که آن را در دسترس n8n خود یا سایر کاربران قرار دهید. n8n چندین روش برای استقرار و اشتراک‌گذاری Nodeهای سفارشی ارائه می‌دهد که هر کدام مزایا و محدودیت‌های خاص خود را دارند.

۱. نصب در n8n محلی (و سرورهای خودمیزبان)

ساده‌ترین راه برای استفاده از Node سفارشی، نصب آن به صورت محلی در نمونه n8n شما یا در سرور خودمیزبان (self-hosted) است.

الف. کپی کردن فایل‌ها (مناسب برای تست سریع و توسعه):
این روش عمدتاً برای توسعه‌دهندگانی مفید است که Node را به صورت محلی توسعه می‌دهند. n8n دارای یک پوشه اختصاصی برای Nodeهای سفارشی است که Node شما می‌تواند در آنجا قرار گیرد.

  1. **کامپایل کردن Node:** ابتدا مطمئن شوید که کد TypeScript شما به جاوااسکریپت کامپایل شده است. در دایرکتوری پروژه Node سفارشی خود:
    
            npm run build
            

    این کار خروجی‌های کامپایل شده (معمولاً در پوشه `dist`) را ایجاد می‌کند.

  2. **کپی کردن به پوشه `custom` n8n:** پوشه `dist` Node سفارشی خود را به مسیر `/custom/nodes` در n8n کپی کنید. اگر این پوشه وجود ندارد، آن را ایجاد کنید.

    مسیر `N8N_DATA_FOLDER` معمولاً:

    • Linux/macOS: `~/.n8n`
    • Windows: `%USERPROFILE%\.n8n`
    • Docker: `/home/node/.n8n` (نیاز به mount کردن دارد)

    مثلاً، اگر نام پکیج شما `n8n-nodes-mycustomnode` است، پس از بیلد، شما پوشه‌ای مانند `dist/nodes/MyCustomNode.node.js` خواهید داشت. باید کل پوشه `dist` را به `~/.n8n/custom/nodes/n8n-nodes-mycustomnode` کپی کنید.

  3. **راه‌اندازی مجدد n8n:** برای اینکه n8n Node جدید را شناسایی کند، باید آن را یک بار راه‌اندازی مجدد کنید.

ب. نصب به عنوان یک پکیج npm محلی (توصیه شده برای محیط‌های خودمیزبان):
این روش تمیزتر و قابل نگهداری‌تر از کپی کردن فایل‌هاست، به خصوص اگر Node شما وابستگی‌های خودش را دارد.

  1. **بسته‌بندی Node:** در دایرکتوری پروژه Node سفارشی خود، پکیج را آماده برای نصب کنید:
    
            npm run build
            npm pack
            

    این دستور یک فایل `.tgz` (مثلاً `n8n-nodes-mycustomnode-1.0.0.tgz`) در همان دایرکتوری ایجاد می‌کند.

  2. **نصب در n8n:** به دایرکتوری `N8N_DATA_FOLDER` (مثلاً `~/.n8n`) بروید و پکیج `.tgz` را نصب کنید:
    
            cd ~/.n8n
            npm install /path/to/your/my-custom-node-package/n8n-nodes-mycustomnode-1.0.0.tgz
            

    این کار Node سفارشی شما را به عنوان یک وابستگی در n8n نصب می‌کند و در پوشه `node_modules` مربوط به n8n قرار می‌دهد.

  3. **راه‌اندازی مجدد n8n:** مجدداً، n8n را راه‌اندازی کنید تا Node جدید شناسایی شود.

۲. انتشار به عنوان یک پکیج عمومی npm

اگر Node سفارشی شما قابلیت استفاده عمومی دارد و می‌خواهید آن را با جامعه n8n به اشتراک بگذارید، می‌توانید آن را در رجیستری عمومی npm منتشر کنید. این روش استاندارد برای اشتراک‌گذاری ماژول‌های Node.js است.

  1. **آماده‌سازی `package.json`:** مطمئن شوید که `package.json` شما شامل تمام متادیتاهای لازم (نام، نسخه، توضیحات، نویسنده، مجوز) و وابستگی‌های صحیح است.
  2. **ورود به npm:** اگر قبلاً این کار را نکرده‌اید، با حساب npm خود وارد شوید:
    
            npm login
            
  3. **انتشار:** در دایرکتوری ریشه پروژه Node سفارشی خود (پس از `npm run build`):
    
            npm publish
            

    این کار پکیج شما را در npmjs.com منتشر می‌کند.

  4. **نصب توسط کاربران:** سایر کاربران می‌توانند Node شما را به سادگی با رفتن به پوشه `N8N_DATA_FOLDER` خود و اجرای دستور زیر نصب کنند:
    
            cd ~/.n8n
            npm install n8n-nodes-mycustomnode # نام پکیج شما در npm
            

۳. کمک به مخزن رسمی n8n (Community Nodes)

n8n یک مخزن رسمی برای “Community Nodes” دارد. اگر Node شما به اندازه کافی عمومی و با کیفیت بالا باشد، می‌توانید آن را به این مخزن کمک کنید. این کار مزایای زیادی دارد، از جمله:

  • **دید بالاتر:** Node شما در کنار Nodeهای رسمی n8n نمایش داده می‌شود.
  • **تایید کیفیت:** Node شما توسط تیم n8n بررسی و تایید می‌شود.
  • **نگهداری و به‌روزرسانی آسان‌تر:** با ادغام در مخزن اصلی، نگهداری Node در بلندمدت آسان‌تر خواهد شد.

برای کمک به مخزن Community Nodes:

  1. **مطالعه دستورالعمل‌ها:** به مستندات n8n در مورد “Contributing to n8n” مراجعه کرده و دستورالعمل‌های مربوط به Nodeهای جامعه را به دقت مطالعه کنید. این دستورالعمل‌ها شامل کیفیت کد، مستندسازی، تست‌ها و سایر استانداردها هستند.
  2. **ایجاد Pull Request:** کد Node خود را در یک Pull Request به مخزن Community Nodes n8n ارسال کنید.
  3. **بازبینی و ادغام:** تیم n8n کد شما را بازبینی خواهد کرد و ممکن است درخواست تغییراتی را برای اطمینان از مطابقت با استانداردها بدهد. پس از تایید، Node شما ادغام و در نسخه‌های آینده n8n قرار خواهد گرفت.

۴. استفاده از مخازن خصوصی یا Git Submodules

برای سازمان‌هایی که Nodeهای سفارشی داخلی و اختصاصی دارند و نمی‌خواهند آن‌ها را عمومی کنند، می‌توانند از روش‌های زیر استفاده کنند:

  • **Private npm Registry:** راه‌اندازی یک رجیستری npm خصوصی (مانند Nexus Repository یا Verdaccio) برای میزبانی پکیج‌های Node داخلی.
  • **Git Submodules:** قرار دادن پروژه Node سفارشی به عنوان یک Submodule در پروژه n8n خود. این کار امکان مدیریت نسخه‌ها را فراهم می‌کند.
  • **Direct Git Install:** نصب مستقیم پکیج از یک مخزن Git خصوصی با استفاده از `npm install git+ssh://git@github.com:yourorg/your-private-node.git`.

انتخاب روش استقرار و اشتراک‌گذاری بستگی به هدف، مخاطبان و سیاست‌های امنیتی شما دارد. هر روشی که انتخاب کنید، این امکان را فراهم می‌کند که Node سفارشی شما به بخشی جدایی‌ناپذیر از اکوسیستم n8n تبدیل شده و به افزایش قابلیت‌ها و کارایی ورک‌فلوهای اتوماسیون شما کمک کند.

نتیجه‌گیری: قدرت بی‌پایان گسترش‌پذیری با Nodeهای سفارشی در n8n

در طول این پست، ما سفری عمیق و جامع به دنیای ایجاد Nodeهای سفارشی در n8n داشتیم. از درک اهمیت این قابلیت گرفته تا آماده‌سازی محیط توسعه، کالبدشکافی ساختار یک Node، فاز حیاتی طراحی مفهومی، مراحل گام به گام پیاده‌سازی، اهمیت تست و عیب‌یابی، و در نهایت، بهترین شیوه‌ها برای بهینه‌سازی و روش‌های مختلف استقرار و اشتراک‌گذاری؛ تمامی جنبه‌های کلیدی را با جزئیات بررسی کردیم.

قابلیت ساخت Nodeهای سفارشی، n8n را از یک ابزار اتوماسیون قدرتمند به یک پلتفرم فوق‌العاده انعطاف‌پذیر تبدیل می‌کند. این ویژگی به شما امکان می‌دهد تا n8n را به معنای واقعی کلمه برای هر نیاز خاص و منحصر به فرد کسب‌وکار خود تنظیم کنید. چه نیاز به اتصال به یک API داخلی قدیمی باشد که هیچ Node آماده‌ای برای آن وجود ندارد، چه پیاده‌سازی منطق پردازش داده‌ای پیچیده که فراتر از قابلیت‌های Nodeهای موجود است، و یا حتی ایجاد رابطی برای سرویس‌های نوآورانه‌ای که به تازگی ظهور کرده‌اند، Nodeهای سفارشی این قدرت را به شما می‌دهند که هیچ محدودیتی در اتوماسیون فرآیندهای خود نداشته باشید.

تسلط بر فرآیند ایجاد Nodeهای سفارشی، شما را به یک توسعه‌دهنده n8n توانمندتر تبدیل می‌کند و دریچه‌های جدیدی را برای حل چالش‌های اتوماسیون باز می‌کند. این دانش به شما اجازه می‌دهد تا با اطمینان خاطر، n8n را به عنوان ستون فقرات اتوماسیون برای سیستم‌های سازمانی پیچیده یا پروژه‌های شخصی جاه‌طلبانه به کار بگیرید.

جهان اتوماسیون در حال تحول مداوم است و ابزارهایی مانند n8n با قابلیت گسترش‌پذیری بی‌نظیرشان، به ما این امکان را می‌دهند که همگام با این تحولات پیش برویم و راه‌حل‌هایی بسازیم که نه تنها نیازهای امروز را برآورده می‌کنند، بلکه برای چالش‌های آینده نیز آماده‌اند. اکنون که با اصول و فرآیند ساخت Nodeهای سفارشی آشنا شده‌اید، وقت آن است که دست به کار شوید، ایده‌های خود را به کد تبدیل کنید و پتانسیل واقعی n8n را برای خود و سازمانتان آزاد سازید.

با ساخت Nodeهای سفارشی، شما نه تنها بهره‌وری را افزایش می‌دهید، بلکه به جامعه متن‌باز n8n نیز کمک می‌کنید و مرزهای آنچه را که می‌توان با اتوماسیون به دست آورد، گسترش می‌دهید. به یاد داشته باشید، هر Node سفارشی جدید، یک قدم به سمت یک اکوسیستم اتوماسیون هوشمندتر و یکپارچه‌تر است.

“تسلط به برنامه‌نویسی پایتون با هوش مصنوعی: آموزش کدنویسی هوشمند با ChatGPT”

قیمت اصلی 2.290.000 ریال بود.قیمت فعلی 1.590.000 ریال است.

"تسلط به برنامه‌نویسی پایتون با هوش مصنوعی: آموزش کدنویسی هوشمند با ChatGPT"

"با شرکت در این دوره جامع و کاربردی، به راحتی مهارت‌های برنامه‌نویسی پایتون را از سطح مبتدی تا پیشرفته با کمک هوش مصنوعی ChatGPT بیاموزید. این دوره، با بیش از 6 ساعت محتوای آموزشی، شما را قادر می‌سازد تا به سرعت الگوریتم‌های پیچیده را درک کرده و اپلیکیشن‌های هوشمند ایجاد کنید. مناسب برای تمامی سطوح با زیرنویس فارسی حرفه‌ای و امکان دانلود و تماشای آنلاین."

ویژگی‌های کلیدی:

بدون نیاز به تجربه قبلی برنامه‌نویسی

زیرنویس فارسی با ترجمه حرفه‌ای

۳۰ ٪ تخفیف ویژه برای دانشجویان و دانش آموزان