跳到主要内容

构建声明式节点#

本教程将指导您构建一个声明式节点。开始之前,请确认这是您需要的节点样式。更多信息请参考选择节点构建方法

前置要求#

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

需要具备以下知识基础:

  • JavaScript/TypeScript
  • REST API
  • git

构建节点#

本节将指导您克隆n8n节点入门仓库,并构建一个集成NASA API的节点。您将创建使用NASA两项服务的节点:APOD(每日天文图)和火星探测器照片服务。为保持代码示例简洁,该节点不会实现火星探测器照片端点的所有可用选项。

现有节点说明

n8n已内置NASA节点。为避免与现有节点冲突,您需要为新版本指定不同名称。

步骤1:项目设置#

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

克隆仓库并进入目录:

  1. 基于模板仓库生成新仓库
  2. 克隆您的新仓库:

git clone https://github.com/<your-organization>/<your-repo-name>.git n8n-nodes-nasa-pics cd n8n-nodes-nasa-pics

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

  • 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

这些是任何节点所需的关键文件。有关必需文件和推荐组织的更多信息,请参阅节点文件结构

现在安装项目依赖项:

npm i

步骤2:添加图标#

将NASA SVG徽标从此处另存为 nasapics.svgnodes/NasaPics/ 目录。

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

禁止引用Font Awesome

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

步骤3:创建节点#

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

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

步骤3.1:导入声明#

首先添加导入声明:

import { 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',
},
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 中设置的某些属性在编辑器界面中渲染节点。这些属性包括 displayNameicondescriptionsubtitle

步骤 3.4:添加资源#

资源对象定义了节点所使用的 API 资源。在本教程中,您将创建一个用于访问 NASA 两个 API 端点(planetary/apodmars-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 为资源显示的 UI 元素类型,并告知 n8n 预期从用户处获取的数据类型。options 会使 n8n 添加下拉菜单,允许用户选择选项。更多信息请参阅节点 UI 元素

步骤 3.5:添加操作#

操作对象定义了资源可用的操作。

在声明式节点中,操作对象包含位于 options 数组内的 routing 配置。该配置用于设置 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在界面中将这类字段归类在附加字段区域显示。

在本教程中,您将添加一个附加字段,允许用户为APOD接口选择特定日期。请将以下内容添加到属性数组中:

{
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) }}',
},
},
},
},
],
}

步骤4:设置身份验证#

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

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

import {
IAuthenticateGeneric,
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 = {
type: 'generic',
properties: {
qs: {
'api_key': '={{$credentials.apiKey}}'
}
},
} as IAuthenticateGeneric;
}

有关凭据文件及其选项的更多信息,请参阅凭据文件

步骤5:添加节点元数据#

节点元数据存放于根目录的JSON文件中,n8n将其称为法典文件。本示例中的文件为NasaPics.node.json

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

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

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

步骤6:更新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实例中运行节点来边开发边测试。

  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

后续步骤#