Skip to content

Build a declarative-style node#

tutorial นี้จะพาไปดูวิธีสร้าง node แบบ declarative-style ก่อนเริ่ม แนะนำให้แน่ใจว่านี่คือ style ที่คุณต้องการใช้ ดูรายละเอียดเพิ่มเติมได้ที่ Choose your node building approach

Prerequisites#

คุณต้องติดตั้งสิ่งเหล่านี้ในเครื่องสำหรับพัฒนา:

  • git
  • Node.js และ npm เวอร์ชันขั้นต่ำ Node 18.17.0 คุณสามารถดูคำแนะนำเกี่ยวกับวิธีการติดตั้งทั้งสองอย่างโดยใช้ nvm (Node Version Manager) สำหรับ Linux, Mac และ WSL ได้ ที่นี่ สำหรับผู้ใช้ Windows โปรดดูคู่มือของ Microsoft เกี่ยวกับ Install NodeJS on Windows

คุณควรมีความเข้าใจพื้นฐานเกี่ยวกับ:

  • JavaScript/TypeScript
  • REST APIs
  • git

Build your node#

ในส่วนนี้ คุณจะ clone node starter repository ของ n8n และสร้าง node ที่เชื่อมต่อกับ NASA API โดยจะสร้าง node ที่ใช้บริการของ NASA สองตัวคือ APOD (Astronomy Picture of the Day) และ Mars Rover Photos เพื่อให้ตัวอย่างโค้ดสั้น node นี้จะไม่ได้ implement ทุก option ของ Mars Rover Photos endpoint

Existing node

n8n มี NASA node ที่ built-in มาอยู่แล้ว เพื่อไม่ให้ชนกับ node เดิม คุณจะต้องตั้งชื่อ node ของคุณให้ต่างออกไป

Step 1: Set up the project#

n8n มี starter repository สำหรับพัฒนา node การใช้ starter จะช่วยให้คุณมี dependencies ที่จำเป็นครบ และมี linter ให้ด้วย

Clone repository แล้วเข้าไปใน directory:

  1. Generate a new repository จาก template repository
  2. Clone repository ใหม่ของคุณ:
    1
    2
    git clone https://github.com/<your-organization>/<your-repo-name>.git n8n-nodes-nasa-pics
    cd n8n-nodes-nasa-pics
    

starter จะมีตัวอย่าง node และ credentials มาให้ ลบ directory และไฟล์เหล่านี้ออก:

  • nodes/ExampleNode
  • nodes/HTTPBin
  • credentials/ExampleCredentials.credentials.ts
  • credentials/HttpBinApi.credentials.ts

จากนั้นสร้าง directory และไฟล์เหล่านี้:

nodes/NasaPics
nodes/NasaPics/NasaPics.node.json
nodes/NasaPics/NasaPics.node.ts
credentials/NasaPicsApi.credentials.ts

ไฟล์เหล่านี้คือไฟล์หลักที่ node ทุกตัวต้องมี ดูรายละเอียดเพิ่มเติมได้ที่ Node file structure

ติดตั้ง dependencies ของโปรเจกต์:

1
npm i

Step 2: Add an icon#

เซฟโลโก้ NASA แบบ SVG จาก ที่นี่ แล้วตั้งชื่อว่า nasapics.svg ไว้ใน nodes/NasaPics/

n8n แนะนำให้ใช้ SVG สำหรับไอคอน node ของคุณ แต่คุณสามารถใช้ PNG ได้เช่นกัน หากใช้ PNG ความละเอียดของไอคอนควรเป็น 60x60px ไอคอน Node ควรมีอัตราส่วนภาพสี่เหลี่ยมจัตุรัสหรือเกือบสี่เหลี่ยมจัตุรัส

อย่าอ้างอิง Font Awesome

หากคุณต้องการใช้ไอคอน Font Awesome ใน node ของคุณ ให้ดาวน์โหลดและฝังรูปภาพนั้น

Step 3: Create the node#

node ทุกตัวต้องมี base file ดูรายละเอียด parameter ของ base file ได้ที่ Node base file

ในตัวอย่างนี้ใช้ไฟล์ NasaPics.node.ts เพื่อให้ง่ายจะใส่โค้ดทุกอย่างไว้ในไฟล์เดียว ถ้า node ซับซ้อนกว่านี้ควรแยก module ดูรายละเอียดที่ Node file structure

Step 3.1: Imports#

เริ่มจาก import module ที่ต้องใช้:

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

Step 3.2: Create the main class#

node ต้อง export interface ที่ implements INodeType ซึ่งต้องมี description interface และ properties array

Class names and file names

ชื่อ class กับชื่อไฟล์ต้องตรงกัน เช่น class NasaPics ไฟล์ต้องชื่อ NasaPics.node.ts

1
2
3
4
5
6
7
8
export class NasaPics implements INodeType {
	description: INodeTypeDescription = {
		// Basic node details will go here
		properties: [
		// Resources and operations will go here
		]
	};
}

Step 3.3: Add node details#

node ทุกตัวต้องมี parameter พื้นฐาน เช่น display name, icon และข้อมูลพื้นฐานสำหรับ request เพิ่มโค้ดนี้ใน description:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
displayName: 'NASA Pics',
name: 'NasaPics',
icon: 'file:nasapics.svg',
group: ['transform'],
version: 1,
subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}',
description: 'Get data from NASAs API',
defaults: {
	name: 'NASA Pics',
},
inputs: ['main'],
outputs: ['main'],
credentials: [
	{
		name: 'NasaPicsApi',
		required: true,
	},
],
requestDefaults: {
	baseURL: 'https://api.nasa.gov',
	headers: {
		Accept: 'application/json',
		'Content-Type': 'application/json',
	},
},

n8n จะใช้ property ใน description บางตัว เช่น displayName, icon, description, subtitle เพื่อแสดง node ใน Editor UI

Step 3.4: Add resources#

resource object จะกำหนดว่า node นี้ใช้ API resource อะไร ในตัวอย่างนี้จะใช้ endpoint planetary/apod และ mars-photos ของ NASA ให้เพิ่ม resource options สองตัวใน NasaPics.node.ts อัปเดต properties array ด้วย resource object:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
properties: [
	{
		displayName: 'Resource',
		name: 'resource',
		type: 'options',
		noDataExpression: true,
		options: [
			{
				name: 'Astronomy Picture of the Day',
				value: 'astronomyPictureOfTheDay',
			},
			{
				name: 'Mars Rover Photos',
				value: 'marsRoverPhotos',
			},
		],
		default: 'astronomyPictureOfTheDay',
	},
	// Operations will go here

]

type จะกำหนดว่า UI ของ n8n จะแสดง element แบบไหน และบอก n8n ว่าควรรับข้อมูลแบบไหนจาก user options จะทำให้มี dropdown ให้เลือก ดูรายละเอียดที่ Node UI elements

Step 3.5: Add operations#

operations object จะกำหนด operation ที่ใช้กับ resource ได้

ใน declarative-style node, operations object จะมี routing (ใน options array) เพื่อกำหนดรายละเอียด API call

เพิ่มโค้ดนี้ใน properties array หลัง resource object:

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
{
	displayName: 'Operation',
	name: 'operation',
	type: 'options',
	noDataExpression: true,
	displayOptions: {
		show: {
			resource: [
				'astronomyPictureOfTheDay',
			],
		},
	},
	options: [
		{
			name: 'Get',
			value: 'get',
			action: 'Get the APOD',
			description: 'Get the Astronomy Picture of the day',
			routing: {
				request: {
					method: 'GET',
					url: '/planetary/apod',
				},
			},
		},
	],
	default: 'get',
},
{
	displayName: 'Operation',
	name: 'operation',
	type: 'options',
	noDataExpression: true,
	displayOptions: {
		show: {
			resource: [
				'marsRoverPhotos',
			],
		},
	},
	options: [
		{
			name: 'Get',
			value: 'get',
			action: 'Get Mars Rover photos',
			description: 'Get photos from the Mars Rover',
			routing: {
				request: {
					method: 'GET',
				},
			},
		},
	],
	default: 'get',
},
{
	displayName: 'Rover name',
	description: 'Choose which Mars Rover to get a photo from',
	required: true,
	name: 'roverName',
	type: 'options',
	options: [
		{name: 'Curiosity', value: 'curiosity'},
		{name: 'Opportunity', value: 'opportunity'},
		{name: 'Perseverance', value: 'perseverance'},
		{name: 'Spirit', value: 'spirit'},
	],
	routing: {
		request: {
			url: '=/mars-photos/api/v1/rovers/{{$value}}/photos',
		},
	},
	default: 'curiosity',
	displayOptions: {
		show: {
			resource: [
				'marsRoverPhotos',
			],
		},
	},
},
{
	displayName: 'Date',
	description: 'Earth date',
	required: true,
	name: 'marsRoverDate',
	type: 'dateTime',
	default:'',
	displayOptions: {
		show: {
			resource: [
				'marsRoverPhotos',
			],
		},
	},
	routing: {
		request: {
			// You've already set up the URL. qs appends the value of the field as a query string
			qs: {
				earth_date: '={{ new Date($value).toISOString().substr(0,10) }}',
			},
		},
	},
},
// Optional/additional fields will go here

โค้ดนี้จะสร้าง operation สองตัว: ตัวหนึ่งสำหรับดึง APOD ของวันนี้ และอีกตัวสำหรับดึงรูปจาก Mars Rover โดย object ชื่อ roverName จะให้ user เลือกว่าจะเอารูปจาก Rover ตัวไหน routing object ใน Mars Rover operation จะใช้ค่านี้สร้าง URL สำหรับ API call

Step 3.6: Optional fields#

API ส่วนใหญ่รวมถึง NASA API จะมี field เสริมที่ไม่บังคับ เพื่อให้ user ไม่งง n8n จะซ่อน field เหล่านี้ไว้ใน Additional Fields ใน UI

ในตัวอย่างนี้จะเพิ่ม field เสริมให้ user เลือกวันที่สำหรับ APOD endpoint เพิ่มโค้ดนี้ใน properties array:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
{
	displayName: 'Additional Fields',
	name: 'additionalFields',
	type: 'collection',
	default: {},
	placeholder: 'Add Field',
	displayOptions: {
		show: {
			resource: [
				'astronomyPictureOfTheDay',
			],
			operation: [
				'get',
			],
		},
	},
	options: [
		{
			displayName: 'Date',
			name: 'apodDate',
			type: 'dateTime',
			default: '',
			routing: {
				request: {
					// You've already set up the URL. qs appends the value of the field as a query string
					qs: {
						date: '={{ new Date($value).toISOString().substr(0,10) }}',
					},
				},
			},
		},
	],									
}

Step 4: Set up authentication#

NASA API ต้องใช้ API key ในการ auth

เพิ่มโค้ดนี้ใน nasaPicsApi.credentials.ts:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import {
	IAuthenticateGeneric,
	ICredentialType,
	INodeProperties,
} from 'n8n-workflow';

export class NasaPicsApi implements ICredentialType {
	name = 'NasaPicsApi';
	displayName = 'NASA Pics API';
	// Uses the link to this tutorial as an example
	// Replace with your own docs links when building your own nodes
	documentationUrl = 'https://docs.n8n.io/integrations/creating-nodes/build/declarative-style-node/';
	properties: INodeProperties[] = [
		{
			displayName: 'API Key',
			name: 'apiKey',
			type: 'string',
			default: '',
		},
	];
	authenticate = {
		type: 'generic',
		properties: {
			qs: {
				'api_key': '={{$credentials.apiKey}}'
			}
		},
	} as IAuthenticateGeneric;
}

ดูรายละเอียดเกี่ยวกับ credentials file และ options ได้ที่ Credentials file

Step 5: Add node metadata#

metadata ของ node จะอยู่ในไฟล์ JSON ที่ root ของ node n8n เรียกไฟล์นี้ว่า codex file ในตัวอย่างนี้คือ NasaPics.node.json

เพิ่มโค้ดนี้ในไฟล์ JSON:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
{
	"node": "n8n-nodes-base.NasaPics",
	"nodeVersion": "1.0",
	"codexVersion": "1.0",
	"categories": [
		"Miscellaneous"
	],
	"resources": {
		"credentialDocumentation": [
			{
				"url": ""
			}
		],
		"primaryDocumentation": [
			{
				"url": ""
			}
		]
	}
}

ดูรายละเอียด parameter เหล่านี้ได้ที่ Node codex files

Step 6: Update the npm package details#

รายละเอียด npm package จะอยู่ใน package.json ที่ root ของโปรเจกต์ ต้องใส่ object n8n ที่ลิงก์ไปยัง credentials และ base node file อัปเดตไฟล์นี้ให้มีข้อมูลแบบนี้:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
{
	// All node names must start with "n8n-nodes-"
	"name": "n8n-nodes-nasapics",
	"version": "0.1.0",
	"description": "n8n node to call NASA's APOD and Mars Rover Photo services.",
	"keywords": [
		// This keyword is required for community nodes
		"n8n-community-node-package"
	],
	"license": "MIT",
	"homepage": "https://n8n.io",
	"author": {
		"name": "Test",
		"email": "[email protected]"
	},
	"repository": {
		"type": "git",
		// Change the git remote to your own repository
		// Add the new URL here
		"url": "git+<your-repo-url>"
	},
	"main": "index.js",
	"scripts": {
		// don't change
	},
	"files": [
		"dist"
	],
	// Link the credentials and node
	"n8n": {
		"n8nNodesApiVersion": 1,
		"credentials": [
			"dist/credentials/NasaPicsApi.credentials.js"
		],
		"nodes": [
			"dist/nodes/NasaPics/NasaPics.node.js"
		]
	},
	"devDependencies": {
		// don't change
	},
	"peerDependencies": {
		// don't change
	}
}

คุณต้องอัปเดต package.json ให้มีข้อมูลของคุณเอง เช่น ชื่อและ repository URL ดูรายละเอียดเพิ่มเติมเกี่ยวกับไฟล์ package.json ได้ที่ npm's package.json documentation

Test your node#

คุณสามารถทดสอบ node ของคุณในขณะที่สร้างได้โดยการรันใน n8n instance บนเครื่องของคุณ

  1. ติดตั้ง n8n โดยใช้ npm:
    1
    npm install n8n -g
    
  2. เมื่อคุณพร้อมที่จะทดสอบ node ของคุณ ให้ publish มันในเครื่อง:
    1
    2
    3
    # ในไดเรกทอรี node ของคุณ
    npm run build
    npm link
    
  3. ติดตั้ง node ลงใน n8n instance บนเครื่องของคุณ:

    1
    2
    3
    # ในไดเรกทอรี nodes ภายในการติดตั้ง n8n ของคุณ
    # node-package-name คือชื่อจาก package.json
    npm link <node-package-name>
    

    ตรวจสอบไดเรกทอรีของคุณ

    ตรวจสอบให้แน่ใจว่าคุณรัน npm link <node-name> ในไดเรกทอรี nodes ภายในการติดตั้ง n8n ของคุณ ซึ่งอาจเป็น:

    • ~/.n8n/custom/
    • ~/.n8n/<your-custom-name>: หากการติดตั้ง n8n ของคุณตั้งชื่ออื่นโดยใช้ N8N_CUSTOM_EXTENSIONS
  4. เริ่ม n8n:

    1
    n8n start
    

  5. เปิด n8n ในเบราว์เซอร์ของคุณ คุณควรเห็น nodes ของคุณเมื่อคุณค้นหาในแผง nodes

    ชื่อ Node

    ตรวจสอบให้แน่ใจว่าคุณค้นหาโดยใช้ชื่อ node ไม่ใช่ชื่อ package ตัวอย่างเช่น หากชื่อ npm package ของคุณคือ n8n-nodes-weather-nodes และ package นั้นมี nodes ชื่อ rain, sun, snow คุณควรค้นหา rain ไม่ใช่ weather-nodes

การแก้ไขปัญหา#

  • ไม่มีไดเรกทอรี custom ในการติดตั้ง ~/.n8n บนเครื่อง

คุณต้องสร้างไดเรกทอรี custom ด้วยตนเองและรัน npm init

1
2
3
4
# ในไดเรกทอรี ~/.n8n รันคำสั่ง
mkdir custom
cd custom
npm init

Next steps#

  • Deploy your node
  • ดูตัวอย่าง declarative node: n8n's Brevo node (main node เป็น declarative, trigger node เป็น programmatic)
  • ศึกษาเรื่อง node versioning