跳到主要内容

构建声明式节点

本教程逐步介绍如何构建声明式节点。开始前,请确认这正是所需的开发方式,更多信息请参阅选择节点开发方式。

前提条件 ​

开发机器需要安装以下工具:

  • Git
  • Node.js 和 npm,Node 最低版本为 18.17.0。在 Linux、Mac 和 WSL 中,可按照 nvm 安装说明,使用 nvm(Node Version Manager)安装两者。Windows 用户请参阅微软的 Windows 上安装 NodeJS指南。

译注:此共用片段仍列 Node 18.17.0,而同一版本“设置开发环境”页面要求最低 Node 22.22.0。此处保留两处原文并提示差异,不据此推断所用 n8n 或开发工具版本的实际兼容范围。

还需要了解:

  • JavaScript/TypeScript
  • REST API
  • Git

构建节点 ​

本节将克隆 n8n 节点入门仓库,构建集成 NASA API 的节点,使用 NASA 的 APOD(每日天文图片)和 Mars Rover Photos(火星车照片)两项服务。为缩短代码示例,不会实现火星车照片端点的全部选项。

信息

已有节点

n8n 已内置 NASA 节点。为避免冲突,本教程的版本将使用不同名称。

第一步:设置项目 ​

n8n 提供节点开发入门仓库,确保包含所需的全部依赖,并提供 linter。

克隆仓库并进入目录:

  1. 根据模板仓库生成新仓库。
  2. 克隆新仓库: shell git clone https://github.com/<your-organization>/<your-repo-name>.git n8n-nodes-nasa-pics cd n8n-nodes-nasa-pics

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

  • nodes/Example
  • nodes/GithubIssues
  • credentials/GithubIssuesApi.credentials.ts
  • credentials/GithubIssuesOAuth2Api.credentials.ts

然后创建以下目录和文件:

nodes/NasaPics
nodes/NasaPics/NasaPics.node.json
nodes/NasaPics/NasaPics.node.ts
credentials/NasaPicsApi.credentials.ts

这些是所有节点必需的关键文件。必需文件和推荐组织方式的更多说明,请参阅节点文件结构。

现在安装项目依赖:

npm i

第二步:添加图标 ​

将 NASA SVG 标志另存为 nasapics.svg,放入 nodes/NasaPics/。

n8n 建议使用 SVG 作为节点图标,也可使用 PNG。如果使用 PNG,分辨率应为 60×60 像素。节点图标的宽高比应为正方形或接近正方形。

信息

不要直接引用 Font Awesome

如果希望在节点中使用 Font Awesome 图标,请下载图片并嵌入。不要设置 defaults.color:它仅用于为 Font Awesome 图标着色,n8n 3.0 会将其移除。

第三步:创建节点 ​

每个节点都必须有基础文件,参数详情请参阅节点基础文件。

此示例使用 NasaPics.node.ts 文件。为简化教程,节点全部功能都放在这一个文件中。构建更复杂的节点时,应考虑按模块拆分功能。更多信息请参阅节点文件结构。

第 3.1 步:导入 ​

先添加导入语句:

import { NodeConnectionTypes } from 'n8n-workflow';
import type { INodeType, INodeTypeDescription } from 'n8n-workflow';

第 3.2 步:创建主类 ​

节点必须导出一个实现 INodeType 的类。类的 description 配置对象必须包含 properties 数组。

信息

类名与文件名

请确保类名与文件名匹配。例如,类名为 NasaPics 时,文件名必须为 NasaPics.node.ts。

export class NasaPics implements INodeType {
description: INodeTypeDescription = {
// Basic node details will go here
properties: [
// Resources and operations will go here
]
};
}

第 3.3 步:添加节点详情 ​

所有节点都需要显示名称、图标及请求基本信息等参数。将以下内容添加到 description:

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',
},
usableAsTool: true,
inputs: [ NodeConnectionTypes.Main ],
outputs: [ NodeConnectionTypes.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 数组:

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',
},
// Operations will go here

]

type 控制 n8n 为资源显示哪种界面元素,并指定用户应输入的数据类型。options 会添加一个供用户单选的下拉菜单。更多信息请参阅节点界面元素。

第 3.5 步:添加操作 ​

操作对象定义可对资源执行哪些操作。

声明式节点的操作对象包含 routing,位于 options 数组中,用于配置 API 调用详情。

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

{
displayName: 'Operation',
name: 'operation',
type: 'options',
noDataExpression: true,
displayOptions: {
show: {
resource: [
'astronomyPictureOfTheDay',
],
},
},
options: [
{
name: 'Get',
value: 'get',
action: 'Get the APOD',
description: 'Get the Astronomy Picture of the day',
routing: {
request: {
method: 'GET',
url: '/planetary/apod',
},
},
},
],
default: 'get',
},
{
displayName: 'Operation',
name: 'operation',
type: 'options',
noDataExpression: true,
displayOptions: {
show: {
resource: [
'marsRoverPhotos',
],
},
},
options: [
{
name: 'Get',
value: 'get',
action: 'Get Mars Rover photos',
description: 'Get photos from the Mars Rover',
routing: {
request: {
method: 'GET',
},
},
},
],
default: 'get',
},
{
displayName: 'Rover name',
description: 'Choose which Mars Rover to get a photo from',
required: true,
name: 'roverName',
type: 'options',
options: [
{name: 'Curiosity', value: 'curiosity'},
{name: 'Opportunity', value: 'opportunity'},
{name: 'Perseverance', value: 'perseverance'},
{name: 'Spirit', value: 'spirit'},
],
routing: {
request: {
url: '=/mars-photos/api/v1/rovers/{{$value}}/photos',
},
},
default: 'curiosity',
displayOptions: {
show: {
resource: [
'marsRoverPhotos',
],
},
},
},
{
displayName: 'Date',
description: 'Earth date',
required: true,
name: 'marsRoverDate',
type: 'dateTime',
default:'',
displayOptions: {
show: {
resource: [
'marsRoverPhotos',
],
},
},
routing: {
request: {
// You've already set up the URL. qs appends the value of the field as a query string
qs: {
earth_date: '={{ new Date($value).toISOString().substr(0,10) }}',
},
},
},
},
// Optional/additional fields will go here

此代码创建两个操作:获取当天的 APOD 图片,以及发送 GET 请求以获取某辆火星车的照片。名为 roverName 的对象要求用户选择哪辆火星车,火星车操作中的 routing 对象再引用此值来构建 API 调用 URL。

第 3.6 步:可选字段 ​

多数 API 都有用于细化查询的可选字段,本示例的 NASA API 也不例外。

为避免一次显示过多选项,n8n 将这些字段放在界面的 Additional Fields(附加字段)中。

本教程将添加一个附加字段,让用户选择 APOD 端点使用的日期。将以下内容添加到 properties 数组:

{
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: {
// You've already set up the URL. qs appends the value of the field as a query string
qs: {
date: '={{ new Date($value).toISOString().substr(0,10) }}',
},
},
},
},
],
}

第四步:设置身份验证和凭据测试 ​

NASA API 要求使用 API 密钥进行身份验证,也可通过发送请求检查密钥是否有效。

将以下内容添加到 nasaPicsApi.credentials.ts:

import {
IAuthenticateGeneric,
ICredentialTestRequest,
ICredentialType,
INodeProperties,
} from 'n8n-workflow';

export class NasaPicsApi implements ICredentialType {
name = 'NasaPicsApi';
displayName = 'NASA Pics API';
// Uses the link to this tutorial as an example
// Replace with your own docs links when building your own nodes
documentationUrl = 'https://docs.n8n.io/integrations/creating-nodes/build/declarative-style-node/';
properties: INodeProperties[] = [
{
displayName: 'API Key',
name: 'apiKey',
type: 'string',
default: '',
},
];
authenticate: IAuthenticateGeneric = {
type: 'generic',
properties: {
qs: {
'api_key': '={{$credentials.apiKey}}'
}
},
};
test: ICredentialTestRequest = {
request: {
baseURL: 'https://api.nasa.gov',
url: '/apod',
},
};
}

凭据文件和选项的更多信息,请参阅凭据文件。

第五步:添加节点元数据 ​

节点元数据保存在节点根目录的 JSON 文件中,n8n 将其称为 codex 文件。此示例的文件为 NasaPics.node.json。

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

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

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

第六步:更新 npm 软件包信息 ​

npm 软件包信息位于项目根目录的 package.json 中,必须包含 n8n 对象,并指向凭据文件和节点基础文件。请更新该文件,加入以下信息:

{
// All node names must start with "n8n-nodes-"
"name": "n8n-nodes-nasapics",
"version": "0.1.0",
"description": "n8n node to call NASA's APOD and Mars Rover Photo services.",
"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/NasaPicsApi.credentials.js"
],
"nodes": [
"dist/nodes/NasaPics/NasaPics.node.js"
]
},
"devDependencies": {
// don't change
},
"peerDependencies": {
// don't change
}
}

请更新 package.json,填入自己的姓名、仓库 URL 等信息。npm package.json 文件的更多说明,请参阅 npm 的 package.json 文档。

测试节点 ​

可通过 n8n-node 工具,在本地 n8n 实例中运行节点,边开发边测试。n8n-node 包含 n8n,因此无需全局安装 n8n。

  1. 在项目根目录运行 dev 命令:

    npm run dev

    此命令运行 n8n-node dev,构建节点并将其链接到 n8n 自定义节点目录,随后启动加载该节点的本地 n8n 实例,并在文件更改时重建节点。

信息
**自定义节点目录**

`n8n-node dev` 使用独立的 n8n 用户目录 `.n8n-node-cli`,不会影响已有的 n8n 安装。默认位置取决于操作系统:
- Windows:`C:\Users\<username>\.n8n-node-cli\.n8n\custom`
- Linux:`/home/<username>/.n8n-node-cli/.n8n/custom`
- macOS:`/Users/<username>/.n8n-node-cli/.n8n/custom`

要针对自己运行的 n8n 实例测试,请传入 `--external-n8n`,并将 `--custom-user-folder <path>` 设为该实例的用户目录,即其 `.n8n` 目录的父目录。在该实例中设置 `N8N_DEV_RELOAD=true`,使其加载更改。

注意:`.n8n-node-cli` 和 `.n8n` 为隐藏目录,文件浏览器可能不显示它们。
  1. 在浏览器中打开 http://localhost:5678,登录 n8n 实例。
  2. 打开工作流,在节点面板中搜索你的节点。
信息
**节点名称**

请使用节点名称搜索,而不是软件包名称。例如,npm 软件包名为 `n8n-nodes-weather-nodes`,其中包含 `rain`、`sun`、`snow` 三个节点时,应搜索 `rain`,而非 `weather-nodes`。

将节点添加到工作流,在开发过程中测试。要停止 n8n,请按 ctrl + c。

后续步骤 ​

相关资源 ​

本文为社区中文翻译。查看对应英文原文