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中的表达式

构建节点#

本节将指导您克隆 n8n 节点入门仓库,并构建一个集成 SendGrid 的节点。您将创建一个实现 SendGrid 单一步骤功能的节点:创建联系人。

注意事项: n8n 已内置 SendGrid 节点。为避免与现有节点冲突,您需要为新版本节点设置不同名称。

步骤1:项目设置#

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

克隆仓库并进入目录:

  1. 从模板仓库生成新仓库
  2. 克隆您的新仓库:
git clone <您的仓库地址>
cd <您的仓库目录>

入门模板包含示例节点和凭据文件,请删除以下目录和文件:

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

现在创建以下目录和文件: nodes/FriendGrid nodes/FriendGrid/FriendGrid.node.json nodes/FriendGrid/FriendGrid.node.ts credentials/FriendGridApi.credentials.ts 这些是任何节点所需的关键文件。有关必需文件和推荐组织结构的更多信息,请参阅节点文件结构

现在安装项目依赖:

npm install

第二步:添加图标#

从此处获取SendGrid SVG 图标,另存为 friendGrid.svgnodes/FriendGrid/ 目录中。

n8n 推荐使用 SVG 格式作为节点图标,但也可以使用 PNG 格式。如果使用 PNG,图标分辨率应为 60x60 像素。节点图标应保持正方形或接近正方形的宽高比。

不要引用 Font Awesome 如果要在节点中使用 Font Awesome 图标,请下载并嵌入图像。

第三步:在基础文件中定义节点#

每个节点都必须有一个基础文件。有关基础文件参数的详细信息,请参阅节点基础文件

在本示例中,文件是 FriendGrid.node.ts。为保持本教程简洁,我们将把所有节点功能都放在这个文件中。构建更复杂的节点时,应考虑将功能拆分到不同模块中。更多信息请参考节点文件结构

第三步.1:导入语句#

首先添加导入语句:

import {
  IExecuteFunctions,
} from 'n8n-core'

import {
  IDataObject,
  INodeExecutionData,
  INodeType,
  INodeTypeDescription,
  NodeConnectionType
} from 'n8n-workflow'

import {
  OptionsWithUri,
} from 'request'

---|---

步骤 3.2:创建主类#

节点必须导出一个实现 INodeType 的接口。该接口必须包含 description 接口,而该接口又包含 properties 数组。 类名与文件名 请确保类名与文件名匹配。例如,给定类名 FriendGrid,则文件名必须为 FriendGrid.node.ts

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11

| ``` exportclassFriendGridimplementsINodeType{ description:INodeTypeDescription={ // 基础节点详情将放置于此 properties:[ // 资源和操作将放置于此 ], }; // execute 方法将放置于此 asyncexecute(this:IExecuteFunctions):Promise<INodeExecutionData[][]>{ } }


---|---
#### 步骤 3.3:添加节点详情[#](https://docs.n8n.io/integrations/creating-nodes/build/programmatic-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

| ```
displayName:'FriendGrid',
name:'friendGrid',
icon:'file:friendGrid.svg',
group:['transform'],
version:1,
description:'使用 SendGrid API',
defaults:{
name:'FriendGrid',
},
inputs:[NodeConnectionType.Main],
outputs:[NodeConnectionType.Main],
credentials:[
{
name:'friendGridApi',
required:true,
},
],

---|--- n8n 使用在 description 中设置的部分属性在编辑器 UI 中渲染节点。这些属性包括 displayNameicondescription

步骤 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:'资源', name:'resource', type:'options', options:[ { name:'联系人', value:'contact', }, ], default:'contact', noDataExpression:true, required:true, description:'创建新联系人', },

type 控制 n8n 为资源显示的 UI 元素类型,并告知 n8n 预期从用户处获取的数据类型。options 会使 n8n 添加一个下拉菜单,允许用户选择其中一个选项。更多信息请参阅节点 UI 元素

步骤 3.5:添加操作#

操作对象定义了可以对资源执行的操作。它通常与 REST API 动词(GET、POST 等)相关联。本教程中有一个操作:创建联系人。该操作有一个必填字段,即用户创建的联系人的电子邮件地址。

resource 对象之后,将以下内容添加到 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
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:'name@email.com', description:'Primary email for the contact', },


#### 步骤 3.6:添加可选字段[#](https://docs.n8n.io/integrations/creating-nodes/build/programmatic-style-node/#step-36-add-optional-fields "永久链接")
大多数 API(包括本示例中使用的 SendGrid API)都包含可选字段,可用于优化查询。

为避免给用户带来过多信息,n8n 在用户界面中将这些字段显示在**附加字段**下方。

在本教程中,您将添加两个额外字段,允许用户输入联系人的名字和姓氏。将以下内容添加到 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:添加 execute 方法[#](https://docs.n8n.io/integrations/creating-nodes/build/programmatic-style-node/#step-4-add-the-execute-method "Permanent link")
您已经完成了节点界面和基础信息的设置。现在需要将节点界面与 API 请求进行映射,让节点真正执行具体操作。

`execute` 方法在节点每次运行时都会执行。在该方法中,您可以访问输入项和用户在界面中设置的参数(包括凭据信息)。

在 `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

| ```
// Handle data coming from previous nodes
constitems=this.getInputData();
letresponseData;
constreturnData=[];
constresource=this.getNodeParameter('resource',0)asstring;
constoperation=this.getNodeParameter('operation',0)asstring;

// For each item, make an API call to create a contact
for(leti=0;i<items.length;i++){
if(resource==='contact'){
if(operation==='create'){
// Get email input
constemail=this.getNodeParameter('email',i)asstring;
// Get additional fields input
constadditionalFields=this.getNodeParameter('additionalFields',i)asIDataObject;
constdata:IDataObject={
email,
};

Object.assign(data,additionalFields);

// Make HTTP request according to https://sendgrid.com/docs/api-reference/
constoptions:OptionsWithUri={
headers:{
'Accept':'application/json',
},
method:'PUT',
body:{
contacts:[
data,
],
},
uri:`https://api.sendgrid.com/v3/marketing/contacts`,
json:true,
};
responseData=awaitthis.helpers.requestWithAuthentication.call(this,'friendGridApi',options);
returnData.push(responseData);
}
}
}
// Map data to n8n data structure
return[this.helpers.returnJsonArray(returnData)];

---|--- 注意以下代码段:

1
2
3
4
5
6
7

| ``` constitems=this.getInputData(); ...for(leti=0;i<items.length;i++){ ... constemail=this.getNodeParameter('email',i)asstring; ... }


---|---
用户可以通过两种方式提供数据:
  * 直接在节点字段中输入
  * 通过映射工作流中先前节点的数据

`getInputData()` 及后续循环允许节点处理来自前序节点的数据,包括支持多输入场景。这意味着如果前序节点输出了五个联系人的信息,您的 FriendGrid 节点就能创建五个联系人。

### 步骤 5:设置身份验证[#](https://docs.n8n.io/integrations/creating-nodes/build/programmatic-style-node/#step-5-set-up-authentication "Permanent link")
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';

```typescript
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 将此文件称为 codex 文件。在此示例中,文件为 FriendGrid.node.json

将以下代码添加到 JSON 文件中:

{
	"node": "n8n-nodes-base.FriendGrid",
	"nodeVersion": "1.0",
	"codexVersion": "1.0",
	"categories": [
		"Miscellaneous"
	],
	"resources": {
		"credentialDocumentation": [
			{
				"url": ""
			}
		],
		"primaryDocumentation": [
			{
				"url": ""
			}
		]
	}
}

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

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

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

{
  // 所有节点名称必须以 "n8n-nodes-" 开头
  "name": "n8n-nodes-friendgrid",
  "version": "0.1.0",
  "description": "用于在 SendGrid 中创建联系人的 n8n 节点",
  "keywords": [
    // 此关键词是社区节点所必需的
    "n8n-community-node-package"
  ],
  "license": "MIT",
  "homepage": "https://n8n.io",
  "author": {
    "name": "Test",
    "email": "test@example.com"
  },
  "repository": {
    "type": "git",
    // 将 git remote 更改为您自己的仓库
    // 在此处添加新的 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 文档](https://docs.npmjs.com/cli/v8/configuring-npm/package-json)。

## 测试节点[#](https://docs.n8n.io/integrations/creating-nodes/build/programmatic-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 <节点名称>。该目录可能是: _ ~/.n8n/custom/ _ ~/.n8n/<你的自定义名称>:如果你的 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/programmatic-style-node/#troubleshooting "永久链接")
如果 `~/.n8n` 本地安装目录中没有 `custom` 文件夹,你需要手动创建 `custom` 目录并运行 `npm init`:

1 2 3 4

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

---|---

后续步骤#