构建声明式风格节点#
本教程将逐步指导如何构建声明式风格节点。开始前,请确认这是您需要的节点构建方式。更多信息请参考选择节点构建方法。
前置要求#
您的开发环境需要安装以下组件:
- 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| ``` 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 中设置的部分属性来在编辑器界面中渲染节点。这些属性包括 displayName、icon、description 和 subtitle。
步骤 3.4:添加资源#
资源对象定义了节点使用的 API 资源。在本教程中,您将创建一个用于访问 NASA 两个 API 端点(planetary/apod 和 mars-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---|---