构建编程式节点
本教程介绍如何构建编程式节点。在开始之前,请确保这是您需要的节点样式。参考选择您的节点构建方法 了解更多信息。
前置条件
您需要在开发机器上安装以下内容:
git
Node.js 和 npm。最低版本 Node 18.17.0。您可以在这里 找到使用 nvm(Node 版本管理器)为 Linux、Mac 和 WSL 安装两者的说明。对于 Windows 用户,请参考 Microsoft 的在 Windows 上安装 NodeJS 指南。
您需要对以下内容有一定了解:
JavaScript/TypeScript
REST API
git
n8n 中的表达式
构建您的节点
在本节中,您将克隆 n8n 的节点启动器仓库,并构建一个集成 SendGrid 的节点。您将创建一个实现 SendGrid 功能的节点:创建联系人。
现有节点
n8n 有一个内置的 SendGrid 节点。为了避免与现有节点冲突,您将为您的版本提供不同的名称。
步骤 1:设置项目
n8n 为节点开发提供了一个启动器仓库。使用启动器确保您拥有所有必要的依赖项。它还提供了一个检查器。
克隆仓库并导航到目录:
从模板仓库生成新仓库 。
克隆您的新仓库:
git clone https://github.com/<your-organization>/<your-repo-name>.git n8n-nodes-friendgrid
cd n8n-nodes-friendgrid
启动器包含示例节点和凭据。删除以下目录和文件:
nodes/Example
nodes/GithubIssues
credentials/GithubIssuesApi.credentials.ts
credentials/GithubIssuesOAuth2Api.credentials.ts
现在创建以下目录和文件:
nodes/FriendGrid
nodes/FriendGrid/FriendGrid.node.json
nodes/FriendGrid/FriendGrid.node.ts
credentials/FriendGridApi.credentials.ts
这些是任何节点所需的关键文件。参考节点文件结构 了解更多关于必需文件和推荐组织的信息。
现在安装项目依赖项:
步骤 2:添加图标
从这里 保存 SendGrid SVG 徽标,作为 friendGrid.svg 保存在 nodes/FriendGrid/ 中。
n8n 建议为您的节点图标使用 SVG 格式,但您也可以使用 PNG。如果使用 PNG,图标分辨率应为 60x60px。节点图标应具有正方形或接近正方形的宽高比。
不要引用 Font Awesome
如果您想在节点中使用 Font Awesome 图标,请下载并嵌入图像。
步骤 3:在基础文件中定义节点
每个节点都必须有一个基础文件。参考节点基础文件 了解基础文件参数的详细信息。
在这个示例中,文件是 FriendGrid.node.ts。为了保持本教程简短,您将把所有节点功能放在这一个文件中。在构建更复杂的节点时,您应该考虑将功能拆分到模块中。参考节点文件结构 了解更多信息。
步骤 3.1:导入
首先添加导入语句:
import type {
IDataObject ,
IExecuteFunctions ,
IHttpRequestOptions ,
INodeExecutionData ,
INodeType ,
INodeTypeDescription ,
} from 'n8n-workflow' ;
import { NodeConnectionTypes } from 'n8n-workflow' ;
步骤 3.2:创建主类
节点必须导出一个实现 INodeType 的接口。此接口必须包含一个 description 接口,该接口又包含 properties 数组。
类名和文件名
确保类名和文件名匹配。例如,给定类 FriendGrid,文件名必须是 FriendGrid.node.ts。
export class FriendGrid implements INodeType {
description : INodeTypeDescription = {
// 基本节点详细信息将放在这里
properties : [
// 资源和操作将放在这里
],
};
// 执行方法将放在这里
async execute ( this : IExecuteFunctions ) : Promise < INodeExecutionData [][] > {
}
}
步骤 3.3:添加节点详细信息
所有编程式节点都需要一些基本参数,如显示名称和图标。将以下内容添加到 description 中:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 displayName : 'FriendGrid' ,
name : 'friendGrid' ,
icon : 'file:friendGrid.svg' ,
group : [ 'transform' ],
version : 1 ,
description : 'Consume SendGrid API' ,
defaults : {
name : 'FriendGrid' ,
},
inputs : [ NodeConnectionTypes . Main ],
outputs : [ NodeConnectionTypes . Main ],
usableAsTool : true ,
credentials : [
{
name : 'friendGridApi' ,
required : true ,
},
],
n8n 使用 description 中设置的一些属性在编辑器 UI 中渲染节点。这些属性是 displayName、icon 和 description。
步骤 3.4:添加资源
资源对象定义节点使用的 API 资源。在本教程中,您正在创建一个节点来访问 SendGrid 的 API 端点之一:/v3/marketing/contacts。这意味着您需要为此端点定义一个资源。使用资源对象更新 properties 数组:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 {
displayName : 'Resource' ,
name : 'resource' ,
type : 'options' ,
options : [
{
name : 'Contact' ,
value : 'contact' ,
},
],
default : 'contact' ,
noDataExpression : true ,
required : true ,
description : 'Create a new contact' ,
},
type 控制 n8n 为资源显示哪个 UI 元素,并告诉 n8n 期望用户提供什么类型的数据。options 导致 n8n 添加一个允许用户选择一个选项的下拉菜单。参考节点 UI 元素 了解更多信息。
步骤 3.5:添加操作
操作对象定义您可以对资源执行的操作。它通常与 REST API 动词(GET、POST 等)相关。在本教程中,有一个操作:创建联系人。它有一个必需字段,即用户创建的联系人的电子邮件地址。
将以下内容添加到 properties 数组中,在 resource 对象之后:
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 {
displayName : 'Operation' ,
name : 'operation' ,
type : 'options' ,
displayOptions : {
show : {
resource : [
'contact' ,
],
},
},
options : [
{
name : 'Create' ,
value : 'create' ,
description : 'Create a contact' ,
action : 'Create a contact' ,
},
],
default : 'create' ,
noDataExpression : true ,
},
{
displayName : 'Email' ,
name : 'email' ,
type : 'string' ,
required : true ,
displayOptions : {
show : {
operation : [
'create' ,
],
resource : [
'contact' ,
],
},
},
default : '' ,
placeholder : '[email protected] ' ,
description : 'Primary email for the contact' ,
},
步骤 3.6:添加可选字段
大多数 API,包括您在此示例中使用的 SendGrid API,都有可选字段,您可以使用这些字段来优化查询。
为了避免让用户感到不知所措,n8n 在 UI 中的附加字段 下显示这些字段。
对于本教程,您将添加两个附加字段,以允许用户输入联系人的名字和姓氏。将以下内容添加到 properties 数组:
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 {
displayName : 'Additional Fields' ,
name : 'additionalFields' ,
type : 'collection' ,
placeholder : 'Add Field' ,
default : {},
displayOptions : {
show : {
resource : [
'contact' ,
],
operation : [
'create' ,
],
},
},
options : [
{
displayName : 'First Name' ,
name : 'firstName' ,
type : 'string' ,
default : '' ,
},
{
displayName : 'Last Name' ,
name : 'lastName' ,
type : 'string' ,
default : '' ,
},
],
},
步骤 4:添加执行方法
您已经设置了节点 UI 和基本信息。现在是时候将节点 UI 映射到 API 请求,并让节点实际执行某些操作了。
execute 方法在每次节点运行时运行。在此方法中,您可以访问输入项目和用户在 UI 中设置的参数,包括凭据。
将以下内容添加到 FriendGrid.node.ts 中的 execute 方法:
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 // 处理来自前一个节点的数据
const items = this . getInputData ();
let responseData ;
const returnData : INodeExecutionData [] = [];
const resource = this . getNodeParameter ( 'resource' , 0 );
const operation = this . getNodeParameter ( 'operation' , 0 );
// 对于每个项目,进行 API 调用以创建联系人
for ( let i = 0 ; i < items . length ; i ++ ) {
try {
if ( resource === 'contact' ) {
if ( operation === 'create' ) {
// 获取电子邮件输入
const email = this . getNodeParameter ( 'email' , i );
// 获取附加字段输入
const additionalFields = this . getNodeParameter ( 'additionalFields' , i );
const data : IDataObject = {
email ,
};
Object . assign ( data , additionalFields );
// 根据 https://sendgrid.com/docs/api-reference/ 进行 HTTP 请求
const options : IHttpRequestOptions = {
headers : {
'Accept' : 'application/json' ,
},
method : 'PUT' ,
body : {
contacts : [
data ,
],
},
url : 'https://api.sendgrid.com/v3/marketing/contacts' ,
json : true ,
};
responseData = await this . helpers . httpRequestWithAuthentication . call ( this , 'friendGridApi' , options );
const executionData = this . helpers . constructExecutionMetaData (
this . helpers . returnJsonArray ( responseData as IDataObject ),
{ itemData : { item : i } },
);
returnData . push . apply ( returnData , executionData );
}
}
} catch ( error ) {
if ( this . continueOnFail ()) {
const executionData = this . helpers . constructExecutionMetaData (
this . helpers . returnJsonArray ({ error : error.message }),
{ itemData : { item : i } },
);
returnData . push . apply ( returnData , executionData );
continue ;
}
throw error ;
}
}
return [ returnData ];
注意此代码的以下行:
const items = this . getInputData ();
...
for ( let i = 0 ; i < items . length ; i ++ ) {
...
const email = this . getNodeParameter ( 'email' , i );
...
}
用户可以通过两种方式提供数据:
直接在节点字段中输入
通过映射工作流中早期节点的数据
getInputData() 和随后的循环允许节点处理数据来自前一个节点的情况。这包括支持多个输入。这意味着,例如,如果前一个节点输出五个人的联系信息,您的 FriendGrid 节点可以创建五个联系人。
步骤 5:设置身份验证
SendGrid API 要求用户使用 API 密钥进行身份验证。
将以下内容添加到 FriendGridApi.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
30
31
32
33
34
35 import {
IAuthenticateGeneric ,
ICredentialTestRequest ,
ICredentialType ,
INodeProperties ,
} from 'n8n-workflow' ;
export class FriendGridApi implements ICredentialType {
name = 'friendGridApi' ;
displayName = 'FriendGrid API' ;
properties : INodeProperties [] = [
{
displayName : 'API Key' ,
name : 'apiKey' ,
type : 'string' ,
default : '' ,
},
];
authenticate : IAuthenticateGeneric = {
type : 'generic' ,
properties : {
headers : {
Authorization : '=Bearer {{$credentials.apiKey}}' ,
},
},
};
test : ICredentialTestRequest = {
request : {
baseURL : 'https://api.sendgrid.com/v3' ,
url : '/marketing/contacts' ,
},
};
}
有关凭据文件和选项的更多信息,请参考凭据文件 。
步骤 6:添加节点元数据
关于您节点的元数据放在节点根目录的 JSON 文件中。n8n 将此称为代码库文件。在此示例中,文件是 FriendGrid.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.FriendGrid" ,
"nodeVersion" : "1.0" ,
"codexVersion" : "1.0" ,
"categories" : [
"Miscellaneous"
],
"resources" : {
"credentialDocumentation" : [
{
"url" : ""
}
],
"primaryDocumentation" : [
{
"url" : ""
}
]
}
}
有关这些参数的更多信息,请参考节点代码库文件 。
步骤 7:更新 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-friendgrid" ,
"version" : "0.1.0" ,
"description" : "n8n node to create contacts in SendGrid" ,
"keywords" : [
// 社区节点需要此关键字
"n8n-community-node-package"
],
"license" : "MIT" ,
"homepage" : "https://n8n.io" ,
"author" : {
"name" : "Test" ,
"email" : "[email protected] "
},
"repository" : {
"type" : "git" ,
// 将 git 远程更改为您自己的仓库
// 在此添加新 URL
"url" : "git+<your-repo-url>"
},
"main" : "index.js" ,
"scripts" : {
// 不要更改
},
"files" : [
"dist"
],
// 链接凭据和节点
"n8n" : {
"n8nNodesApiVersion" : 1 ,
"credentials" : [
"dist/credentials/FriendGridApi.credentials.js"
],
"nodes" : [
"dist/nodes/FriendGrid/FriendGrid.node.js"
]
},
"devDependencies" : {
// 不要更改
},
"peerDependencies" : {
// 不要更改
}
}
您需要更新 package.json 以包含您自己的信息,如您的姓名和仓库 URL。有关 npm package.json 文件的更多信息,请参考 npm 的 package.json 文档 。
测试您的节点
您可以通过在本地 n8n 实例中运行来测试正在构建的节点。
使用 npm 安装 n8n:
当您准备测试节点时,在本地发布它:
# 在您的节点目录中
npm run build
npm link
将节点安装到您的本地 n8n 实例中:
# 在您的 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 设置了不同的名称。
启动 n8n:
在浏览器中打开 n8n。当您在节点面板中搜索时,应该能看到您的节点。
节点名称
确保您使用节点名称搜索,而不是包名称。例如,如果您的 npm 包名称是 n8n-nodes-weather-nodes,并且包含名为 rain、sun、snow 的节点,您应该搜索 rain,而不是 weather-nodes。
故障排除
如果在 ~/.n8n 本地安装中没有 custom 目录,您需要手动创建 custom 目录并运行 npm init:
# 在 ~/.n8n 目录中运行
mkdir custom
cd custom
npm init
下一步