N8N中文教程
集成节点/Creating_nodes/Build_your_node

构建声明式风格节点#

本教程将逐步指导如何构建声明式风格节点。开始前,请确认这是您需要的节点构建方式。更多信息请参考选择节点构建方法

前置要求#

您的开发环境需要安装以下组件:

  • git
  • Node.js 和 npm。最低版本要求 Node 18.17.0。Linux、Mac 和 WSL 用户可参考此指南使用 nvm(Node版本管理器)安装。Windows 用户请参阅微软的在Windows上安装NodeJS指南。

需要掌握以下知识:

  • JavaScript/TypeScript
  • REST API
  • git

构建节点#

本节将指导您克隆 n8n 节点入门仓库,并构建一个集成NASA API的节点。您将创建一个使用NASA两项服务的节点:APOD(每日天文图)和火星探测器照片。为保持代码示例简洁,该节点不会实现火星探测器照片端点的所有可用选项。

现有节点说明: n8n 已内置NASA节点。为避免与现有节点冲突,您需要为新版本节点设置不同名称。

步骤1:项目设置#

n8n 提供了节点开发的入门仓库。使用该入门模板可确保您获得所有必要的依赖项,同时还提供了代码检查工具。

克隆仓库并进入目录:

  1. 从模板仓库生成新仓库
  2. 克隆您的新仓库:
1
2

| ``` gitcd


---|---

入门模板包含示例节点和凭据文件。请删除以下目录和文件:
  * `nodes/ExampleNode`
  * `nodes/HTTPBin`
  * `credentials/ExampleCredentials.credentials.ts`
  * `credentials/HttpBinApi.credentials.ts`

现在创建以下目录和文件:
`nodes/NasaPics`
`nodes/NasaPics/NasaPics.node.json`
`nodes/NasaPics/NasaPics.node.ts`
`credentials/NasaPicsApi.credentials.ts`
这些是任何节点所需的关键文件。有关必需文件和推荐组织结构的更多信息,请参阅[节点文件结构](https://docs.n8n.io/integrations/creating-nodes/build/reference/node-file-structure/)。
现在安装项目依赖:

1

| ```
npm

---|---

步骤 2:添加图标#

从此处下载 NASA SVG 徽标,并将其保存为 nodes/NasaPics/ 目录下的 nasapics.svg。 n8n 推荐使用 SVG 格式作为节点图标,但也可以使用 PNG 格式。如果使用 PNG,图标分辨率应为 60x60 像素。节点图标应具有正方形或接近正方形的宽高比。 不要引用 Font Awesome 如果要在节点中使用 Font Awesome 图标,请下载并嵌入该图像。

步骤 3:创建节点#

每个节点都必须有一个基础文件。有关基础文件参数的详细信息,请参阅节点基础文件。 在本示例中,文件是 NasaPics.node.ts。为简化本教程,您将把所有节点功能都放在这个文件中。构建更复杂的节点时,应考虑将功能拆分到不同的模块中。更多信息请参阅节点文件结构

步骤 3.1:导入#

首先添加导入语句:

1

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


---|---
#### 步骤 3.2:创建主类[#](https://docs.n8n.io/integrations/creating-nodes/build/declarative-style-node/#step-32-create-the-main-class "永久链接")
节点必须导出一个实现 INodeType 的接口。此接口必须包含 `description` 接口,而该接口又包含 `properties` 数组。
类名和文件名
确保类名和文件名匹配。例如,如果类名为 `NasaPics`,则文件名必须为 `NasaPics.node.ts`。

1 2 3 4 5 6 7 8

| ```
exportclassNasaPicsimplementsINodeType{
description:INodeTypeDescription={
// 基础节点详细信息将放在这里
properties:[
// 资源和操作将放在这里
]
};
}

---|---
#### 步骤 3.3:添加节点详情[#](https://docs.n8n.io/integrations/creating-nodes/build/declarative-style-node/#step-33-add-node-details "永久链接")
所有节点都需要一些基本参数,例如显示名称、图标以及使用节点发起请求的基本信息。请将以下内容添加到 `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 使用在 description 中设置的部分属性来在编辑器界面中渲染节点。这些属性包括 displayNameicondescriptionsubtitle

步骤 3.4:添加资源#

资源对象定义了节点使用的 API 资源。在本教程中,您将创建一个用于访问 NASA 两个 API 端点(planetary/apodmars-photos)的节点。这意味着您需要在 NasaPics.node.ts 中定义两个资源选项。请使用资源对象更新 properties 数组:

 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', }, // 操作将在此处添加


`type` 控制 n8n 为资源显示的 UI 元素类型,并告知 n8n 预期从用户处获取的数据类型。`options` 会使 n8n 添加一个下拉菜单,允许用户选择选项。更多信息请参阅[节点 UI 元素](https://docs.n8n.io/integrations/creating-nodes/build/reference/ui-elements/)。
#### 步骤 3.5:添加操作[#](https://docs.n8n.io/integrations/creating-nodes/build/declarative-style-node/#step-35-add-operations "永久链接")
操作对象定义了资源可用的操作。
在声明式节点中,操作对象包含 `routing`(位于 `options` 数组内)。该配置用于设置 API 调用的详细信息。
在 `resource` 对象之后,将以下内容添加到 `properties` 数组中:
```json
  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:'操作',
	name:'operation',
	type:'options',
	noDataExpression:true,
	displayOptions:{
		show:{
			resource:[
				'astronomyPictureOfTheDay',
			],
		},
	},
	options:[
		{
			name:'获取',
			value:'get',
			action:'获取APOD',
			description:'获取当日天文图片',
			routing:{
				request:{
					method:'GET',
					url:'/planetary/apod',
				},
			},
		},
	],
	default:'get',
},
{
	displayName:'操作',
	name:'operation',
	type:'options',
	noDataExpression:true,
	displayOptions:{
		show:{
			resource:[
				'marsRoverPhotos',
			],
		},
	},
	options:[
		{
			name:'获取',
			value:'get',
			action:'获取火星车照片',
			description:'从火星车获取照片',
			routing:{
				request:{
					method:'GET',
				},
			},
		},
	],
	default:'get',
},
{
	displayName:'火星车名称',
	description:'选择从哪个火星车获取照片',
	required:true,
	name:'roverName',
	type:'options',
	options:[
		{name:'好奇号',value:'curiosity'},
		{name:'机遇号',value:'opportunity'},
		{name:'毅力号',value:'perseverance'},
		{name:'勇气号',value:'spirit'},
	],
	routing:{
		request:{
			url:'=/mars-photos/api/v1/rovers/{{$value}}/photos',
		},
	},
	default:'curiosity',
	displayOptions:{
		show:{
			resource:[
				'marsRoverPhotos',
			],
		},
	},
},
{
	displayName:'日期',
	description:'地球日期',
	required:true,
	name:'marsRoverDate',
	type:'dateTime',
	default:'',
	displayOptions:{
		show:{
			resource:[
				'marsRoverPhotos',
			],
		},
	},
	routing:{
		request:{
			// 已设置URL。qs将字段值作为查询字符串附加
			qs:{
				earth_date:'={{ new Date($value).toISOString().substr(0,10) }}',
			},
		},
	},
},
// 可选/附加字段将在此处添加

---|---
这段代码创建了两个操作:一个用于获取今天的每日天文图(APOD),另一个用于向火星车请求照片数据。名为 `roverName` 的对象需要用户选择要从哪个火星车获取照片。火星车操作中的 `routing` 对象通过引用该参数来构建 API 调用的 URL。
#### 步骤 3.6:可选字段[#](https://docs.n8n.io/integrations/creating-nodes/build/declarative-style-node/#step-36-optional-fields "Permanent link")
大多数 API(包括本示例中使用的 NASA API)都包含可用于优化查询的可选字段。
为避免用户界面过于复杂,n8n 在界面中将这类字段归类在 **Additional Fields** 下方显示。
本教程将添加一个额外字段,允许用户为 APOD 端点选择特定日期。请将以下代码添加到属性数组:

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:{
// 已设置基础 URL。qs 会将字段值作为查询字符串附加
qs:{
date:'={{ new Date($value).toISOString().substr(0,10) }}',
},
},
},
},
],}

---|---

步骤 4:设置认证#

NASA API 要求用户使用 API 密钥进行身份验证。 将以下代码添加到 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';

exportclassNasaPicsApiimplementsICredentialType{ name='NasaPicsApi'; displayName='NASA Pics API'; // 使用本教程链接作为示例 // 构建自有节点时请替换为实际文档链接 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}}' } }, }asIAuthenticateGeneric; }


---|---
有关凭据文件和选项的更多信息,请参阅[凭据文件](https://docs.n8n.io/integrations/creating-nodes/build/reference/credentials-files/)。
### 步骤5:添加节点元数据[#](https://docs.n8n.io/integrations/creating-nodes/build/declarative-style-node/#step-5-add-node-metadata "永久链接")
节点的元数据存放在节点根目录的 JSON 文件中。n8n 将此文件称为 codex 文件。本示例中的文件为 `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":""
}
]
}
}

---|--- 有关这些参数的更多信息,请参阅节点 codex 文件

步骤6:更新 npm 包详细信息#

npm 包的详细信息位于项目根目录的 package.json 文件中。必须包含带有凭据和基础节点文件链接的 n8n 对象。更新此文件以包含以下信息:

 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

| ``` { // 所有节点名称必须以 "n8n-nodes-" 开头 "name":"n8n-nodes-nasapics", "version":"0.1.0", "description":"用于调用 NASA APOD 和火星探测器照片服务的 n8n 节点", "keywords":[ // 此关键词为社区节点必需项 "n8n-community-node-package" ], "license":"MIT", "homepage":"https://n8n.io", "author":{ "name":"Test", "email":"test@example.com" }, "repository":{ "type":"git", // 将 git 远程仓库更改为您自己的仓库 // 在此处添加新的 URL "url":"git+" }, "main":"index.js", "scripts":{ // 无需更改 }, "files":[ "dist" ], // 链接凭据和节点 "n8n":{ "n8nNodesApiVersion":1, "credentials":[ "dist/credentials/NasaPicsApi.credentials.js" ], "nodes":[ "dist/nodes/NasaPics/NasaPics.node.js" ] }, "devDependencies":{ // 无需更改 }, "peerDependencies":{ // 无需更改 } }


---|---
你需要更新 `package.json` 文件以包含自己的信息,例如姓名和代码库 URL。有关 npm `package.json` 文件的更多信息,请参阅 [npm 的 package.json 文档](https://docs.npmjs.com/cli/v8/configuring-npm/package-json)。

## 测试节点[#](https://docs.n8n.io/integrations/creating-nodes/build/declarative-style-node/#test-your-node "固定链接")
你可以通过在本地 n8n 实例中运行节点来边开发边测试。
  1. 使用 npm 安装 n8n:

1

| ```
npm install -g n8n

---|--- 2. 准备好测试节点时,在本地发布它:

1
2
3

| ```

在你的节点目录中

npm link


---|---
  3. 将节点安装到本地 n8n 实例中:

1 2 3

| ```
# 在 n8n 安装目录的 nodes 文件夹内
# node-package-name 是 package.json 中的名称
npm link <node-package-name>

---|--- 检查目录 请确保在 n8n 安装目录的 nodes 文件夹内运行 npm link <node-name>。可能的路径包括: _ ~/.n8n/custom/ _ ~/.n8n/<your-custom-name>:如果你的 n8n 安装时使用 N8N_CUSTOM_EXTENSIONS 设置了不同名称。4. 启动 n8n:

1

| ``` n8n start


---|---
  5. 在浏览器中打开 n8n。在节点面板中搜索时,你应该能看到自己的节点。
节点命名
请确保使用节点名称而非包名称进行搜索。例如,如果你的 npm 包名为 `n8n-nodes-weather-nodes`,而该包包含名为 `rain`、`sun`、`snow` 的节点,你应该搜索 `rain` 而非 `weather-nodes`。

### 故障排除[#](https://docs.n8n.io/integrations/creating-nodes/build/declarative-style-node/#troubleshooting "固定链接")
如果 `~/.n8n` 本地安装目录中没有 `custom` 文件夹,你需要手动创建 `custom` 目录并运行 `npm init`:

1 2 3 4

| ```
# 在 ~/.n8n 目录中运行
mkdir custom
cd custom
npm init -y

---|---

后续步骤#