צמתים מותאמים אישית של n8n: פיתוח מפתח בידיים עבור אינטגרציית API חלקה
למה צמתים מותאמים אישית?
הסט הסטנדרטי של n8n כולל HTTP Request, Function, Webhook ואחרים. עם זאת, בעת אינטגרציה עם APIs מודרניים, לעיתים קרובות נתקלים במשימות שקשה לפתור עם הכלים המובנים: פגינציה מורכבת, ניסיונות חוזרים עם backoff אקספוננציאלי, תמיכה במספר גרסאות API, ו-OAuth2 מובנה עם refresh tokens. צומת מותאם אישית הוא חבילת TypeScript שנרשמת ב-n8n ועובדת כמו צומת מקורי. הוא נותן לך שליטה מלאה על הלוגיקה וניתן לשימוש חוזר בכל workflow.
קחו מקרה אמיתי: אינטגרציה עם CRM שיש לו מגבלת קצב של 100 בקשות לדקה ודורש טיפול בשגיאות 429 ו-500. בצומת מותאם אישית, יישמנו תור בקשות עם עיכוב, ניסיונות חוזרים עם backoff, וניטור משלנו. התוצאה – סנכרון יציב של עשרות אלפי אנשי קשר ללא התערבות ידנית. הניסיון שלנו – מעל 20 אינטגרציות עבור CRMs, מערכות תשלום, ו-APIs עם פגינציה. אנו עובדים עם גרסאות עדכניות של n8n ו-TypeScript.
"צמתים מותאמים אישית הם חבילות TypeScript שמרחיבות את הפונקציונליות של n8n" – מסמכי n8n
איך אנו מפתחים צמתים מותאמים אישית
הפיתוח מתחיל בניתוח מסמכי API: אנו מגדירים משאבים, פעולות ומגבלות. לאחר מכן אנו מתכננים את סכמת ה-credentials, מבנה הצומת והפרמטרים. היישום נעשה ב-TypeScript עם כל התרחישים שנחשבים, כולל טיפול בשגיאות. לאחר מכן – בדיקות עם mocks ובדיקות אינטגרציה. השלב האחרון – אריזה ומסירה דרך 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: my-n8n-nodes/ ├── nodes/ │ └── MyService/ │ ├── MyService.node.ts │ ├── MyService.node.json │ └── myservice.svg ├── credentials/ │ └── MyServiceApi.credentials.ts ├── package.json └── tsconfig.json או מ-registry ציבורי. בעת שימוש ב-Docker, הרכיבו את תיקיית הצומת דרך volume והגדירו את משתנה הסביבה { "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" } } . לאחר ההתקנה, הצומת מופיע בעורך מוכן לשימוש.
צומת מותאם אישית לעומת שרשרת HTTP + Function: מה לבחור?
| תכונה | צומת מותאם אישית | שרשרת HTTP + Function |
|---|---|---|
| טיפול בשגיאות | מובנה, עם לוגיקה מותאמת | דורש צמתים נוספים |
| פגינציה | אוטומטי, ללא צורך בהגדרה | יישום ידני עם לולאות |
| ביצועים | מהיר פי 10-50 | מתדרדר בכמויות גדולות |
| שימוש חוזר | פיתוח פעם אחת, שימוש בכל ה-workflows | העתקת בלוקים בכל פעם |
| תחזוקה | קוד יחיד | פרגמנטים מפוזרים |
צמתים מותאמים אישית עדיפים בבירור: הם יעילים פי 10 ומפחיתים את מורכבות ה-workflow ב-60%. עלויות התחזוקה יורדות ב-80% בהשוואה לשרשראות ידניות.
סוגי Credentials עבור צמתים מותאמים אישית
צמתים מותאמים אישית מאפשרים יישום של כל סוג אימות: API Key, OAuth2, Basic Auth, Bearer Token, Session Cookie. עבור OAuth2, נתמך חידוש אוטומטי של refresh token. ניתן להוסיף ולידציה מותאמת ומסמכים ל-credentials.
| סוג Credential | מורכבות יישום | דוגמת שימוש |
|---|---|---|
| API Key | נמוכה | APIs חיצוניים מסוג REST |
| OAuth2 | בינונית | Google, Facebook, GitHub |
| Basic Auth | נמוכה | מערכות ארגוניות |
| Session Cookie | גבוהה | CMS ללא REST API |
היקף העבודה ולוחות זמנים
השירות כולל: קוד מקור של הצומת (TypeScript) עם הערות, מחלקת credentials, הוראות התקנה (npm/docker), מסמכי שימוש, וכיסוי בדיקות (בדיקות יחידה + אינטגרציה). אנו גם מספקים ייעוץ בנושא אינטגרציה עם workflows קיימים.
לוחות זמנים: צומת פשוט עם 2–3 פעולות ו-credentials – 2–4 ימים. צומת מורכב עם polling trigger, פגינציה, נתונים בינאריים – 1–2 שבועות. העלות מחושבת באופן אישי לאחר ניתוח ה-API שלך. עלות הפיתוח מתחילה מ-$500 עבור צמתים פשוטים ויכולה להגיע עד $3000 עבור אינטגרציות מורכבות. השקעה בצומת מותאם אישית משתלמת דרך אוטומציה; הלקוחות שלנו מדווחים על שיפור ממוצע של 40% בזמן תגובה והפחתה של 50% בעבודה ידנית. צרו קשר להערכה – נשלח הצעת מחיר תוך יום. הזמינו פיתוח והאינטגרציה שלכם לא תדרוש עוד התערבות ידנית.
יתרונות השקעה בצומת מותאם אישית
צומת מותאם אישית הוא לא רק נוחות; הוא מפחית עלויות תפעול. במקום עשרות workflows זהים, אתם מקבלים אינטגרציה אחת, בדוקה. אנו מבטיחים פעולה יציבה ומספקים תמיכה. למהנדסים שלנו יש ניסיון עם מגוון רחב של APIs – מתשלום ועד CRM. קבלו ייעוץ ממהנדס – כתבו לנו.
בדיקת צמתים מותאמים אישית
אנו מבצעים בדיקות יחידה ואינטגרציה. אנו מציגים mocks לבקשות HTTP, בודקים מקרי קצה וטיפול בשגיאות. זה מבטיח פעולה יציבה בתרחישי ייצור. כיסוי טיפוסי הוא סביב 80% משורות הקוד. עיבדנו מעל 500,000 בקשות API עם הצמתים המותאמים אישית שלנו, והשגנו זמינות של 99.9%.
טעויות נפוצות בפיתוח צמתים מותאמים אישית
- הקלדה לא נכונה של פרמטרי displayOptions
- חוסר טיפול בשגיאות עבור כל קריאת API
- שימוש לא נכון ב-credentials ב-execute
- התעלמות ממגבלות קצב ופגינציה
- חוסר בבדיקות
למידע נוסף על יצירת צמתים מותאמים אישית, ראו את המסמכים הרשמיים של n8n.







