跳到主要内容

构建编程风格节点#

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

前置要求#

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

  • 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 https://github.com/<your-organization>/<your-repo-name>.git 
n8n-nodes-friendgrid cd n8n-nodes-friendgrid

该启动器包含示例节点和凭据。请删除以下目录和文件:

  • 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 i

步骤2:添加图标#

此处 的 SendGrid SVG 徽标另存为 nodes/FriendGrid/ 目录下的 friendGrid.svg 文件。

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

禁止直接引用 Font Awesome

如需在节点中使用 Font Awesome 图标,请下载图像并嵌入本地文件。

步骤3:在基础文件中定义节点#

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

本示例中的文件为 FriendGrid.node.ts。为简化教程,所有节点功能将集中在此单一文件中。构建复杂节点时,建议将功能拆分至不同模块。更多信息请参阅节点文件结构

步骤3.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

export class FriendGrid implements INodeType {
description: INodeTypeDescription = {
// Basic node details will go here
properties: [
// Resources and operations will go here
],
};
// The execute method will go here
async execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {
}
}

步骤 3.3:添加节点详情#

所有可编程节点都需要一些基本参数,例如显示名称和图标。请将以下内容添加到 description 中:

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

n8n 使用 description 中设置的某些属性在编辑器界面中渲染节点。这些属性包括 displayNameicondescription

步骤 3.4:添加资源#

资源对象定义了节点所使用的 API 资源。在本教程中,您将创建一个用于访问 SendGrid 某个 API 端点 /v3/marketing/contacts 的节点。这意味着您需要为此端点定义资源。请使用资源对象更新 properties 数组:

{
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 等)。本教程包含一个操作:创建联系人。其中包含一个必填字段,即用户创建联系人时使用的电子邮件地址。

resource 对象之后,将以下内容添加到 properties 数组中:

{
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:添加可选字段#

大多数 API(包括本示例中使用的 SendGrid API)都包含可用于优化查询的可选字段。

为避免信息过载,n8n 在界面中将这类字段归类在其他字段区域显示。

本教程将添加两个额外字段,允许用户输入联系人的名和姓。请将以下内容添加至属性数组:

{
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:添加执行方法#

您已完成节点界面与基础信息的配置。现在需要将节点界面与API请求进行映射,使节点真正实现功能。

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

请在FriendGrid.node.ts文件中添加以下execute方法:

// Handle data coming from previous nodes
const items = this.getInputData();
let responseData;
const returnData = [];
const resource = this.getNodeParameter('resource', 0) as string;
const operation = this.getNodeParameter('operation', 0) as string;

// For each item, make an API call to create a contact
for (let i = 0; i < items.length; i++) {
if (resource === 'contact') {
if (operation === 'create') {
// Get email input
const email = this.getNodeParameter('email', i) as string;
// Get additional fields input
const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject;
const data: IDataObject = {
email,
};

Object.assign(data, additionalFields);

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

请注意此代码中的以下几行:

const items = this.getInputData();
...
for (let i = 0; i < items.length; i++) {
...
const email = this.getNodeParameter('email', i) as string;
...
}

用户可通过两种方式提供数据:

  • 直接在节点字段中输入
  • 通过映射工作流中先前节点的数据

getInputData()及后续循环使节点能够处理来自前序节点的数据,包括支持多输入场景。例如若前序节点输出五位联系人的信息,您的FriendGrid节点即可创建五个联系人。

步骤5:设置认证#

SendGrid API要求用户使用API密钥进行身份验证。

请将以下内容添加至FriendGridApi.credentials.ts文件:

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文件:

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

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

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

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

{
// All node names must start with "n8n-nodes-"
"name": "n8n-nodes-friendgrid",
"version": "0.1.0",
"description": "n8n node to create contacts in SendGrid",
"keywords": [
// This keyword is required for community nodes
"n8n-community-node-package"
],
"license": "MIT",
"homepage": "https://n8n.io",
"author": {
"name": "Test",
"email": "test@example.com"
},
"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/FriendGridApi.credentials.js"
],
"nodes": [
"dist/nodes/FriendGrid/FriendGrid.node.js"
]
},
"devDependencies": {
// don't change
},
"peerDependencies": {
// don't change
}
}

您需要更新 package.json 文件以包含您自己的信息,例如您的姓名和代码库URL。有关 npm package.json 文件的更多信息,请参阅 npm 的 package.json 文档

测试您的节点#

您可以通过在本地 n8n 实例中运行来边构建边测试您的节点。

  1. 使用 npm 安装 n8n:

npm install n8n -g

  1. 当您准备好测试节点时,请将其在本地发布:
# In your node directory 
npm run build
npm link
  1. 将节点安装到本地 n8n 实例中:
# In the nodes directory within your n8n installation 
# node-package-name is the name from the package.json
npm link <node-package-name>

检查目录

确保在您的 n8n 安装目录中的 nodes 文件夹下运行 npm link <node-name>。该目录可能是:

  • ~/.n8n/custom/
  • ~/.n8n/<your-custom-name>:如果您的 n8n 安装通过 N8N_CUSTOM_EXTENSIONS 设置了不同名称。
  1. 启动 n8n:

n8n start

  1. 在浏览器中打开 n8n。在节点面板中搜索时,您应该能看到自定义节点。

    节点名称说明

    请确保使用节点名称(而非软件包名称)进行搜索。例如:若您的 npm 软件包名为 n8n-nodes-weather-nodes,且包含名为 rainsunsnow 的节点,则应搜索 rain 而非 weather-nodes

故障排除#

若本地安装的 ~/.n8n 目录中不存在 custom 文件夹,您需要手动创建 custom 目录并执行 npm init 命令:

# In ~/.n8n directory 
run mkdir custom
cd custom
npm init

后续步骤#