Small tweaks to node creator docs (#4239)

Co-authored-by: Kartik Balasubramanian <22399046+HumanistSerif@users.noreply.github.com>
This commit is contained in:
Jon
2026-02-19 09:41:18 +00:00
committed by GitHub
parent ccee86a929
commit 150fee0000
9 changed files with 106 additions and 71 deletions

View File

@@ -19,6 +19,10 @@ Developing with the [`n8n-node` tool](/integrations/creating-nodes/build/n8n-nod
## Submit your node for verification by n8n
/// note | Upcoming Changes
From May 1st 2026 you must publish **ALL** community nodes using a GitHub action and include a [provenance statement](https://docs.npmjs.com/generating-provenance-statements)
///
n8n vets verified community nodes. Users can discover and install verified community nodes from the nodes panel in n8n. These nodes need to adhere to certain technical and UX standards and constraints.
Before submitting your node for review by n8n, you must:

View File

@@ -41,10 +41,10 @@ Clone the repository and navigate into the directory:
The starter contains example nodes and credentials. Delete the following directories and files:
* `nodes/ExampleNode`
* `nodes/HTTPBin`
* `credentials/ExampleCredentials.credentials.ts`
* `credentials/HttpBinApi.credentials.ts`
* `nodes/Example`
* `nodes/GithubIssues`
* `credentials/GithubIssuesApi.credentials.ts`
* `credentials/GithubIssuesOAuth2Api.credentials.ts`
Now create the following directories and files:
@@ -80,7 +80,8 @@ In this example, the file is `NasaPics.node.ts`. To keep this tutorial short, yo
Start by adding the import statements:
```typescript
import { INodeType, INodeTypeDescription } from 'n8n-workflow';
import { NodeConnectionTypes } from 'n8n-workflow';
import type { INodeType, INodeTypeDescription } from 'n8n-workflow';
```
#### Step 3.2: Create the main class
@@ -116,8 +117,9 @@ description: 'Get data from NASAs API',
defaults: {
name: 'NASA Pics',
},
inputs: ['main'],
outputs: ['main'],
usableAsTool: true,
inputs: [ NodeConnectionTypes.Main ],
outputs: [ NodeConnectionTypes.Main ],
credentials: [
{
name: 'NasaPicsApi',
@@ -328,15 +330,16 @@ For this tutorial, you'll add one additional field, to allow users to pick a dat
```
### Step 4: Set up authentication
### Step 4: Set up authentication and a credential test
The NASA API requires users to authenticate with an API key.
The NASA API requires users to authenticate with an API key. You can also send a request to check that the API key works.
Add the following to `nasaPicsApi.credentials.ts`:
```typescript
import {
IAuthenticateGeneric,
ICredentialTestRequest,
ICredentialType,
INodeProperties,
} from 'n8n-workflow';
@@ -355,14 +358,20 @@ export class NasaPicsApi implements ICredentialType {
default: '',
},
];
authenticate = {
authenticate: IAuthenticateGeneric = {
type: 'generic',
properties: {
qs: {
'api_key': '={{$credentials.apiKey}}'
}
},
} as IAuthenticateGeneric;
};
test: ICredentialTestRequest = {
request: {
baseURL: 'https://api.nasa.gov',
url: '/apod',
},
};
}
```

View File

@@ -10,7 +10,7 @@ This document lists the essential dependencies for developing a node, as well as
To build and test a node, you need:
* Node.js and npm. Minimum version Node 18.17.0. You can find instructions on how to install both using nvm (Node Version Manager) for Linux, Mac, and WSL (Windows Subsystem for Linux) [here](https://github.com/nvm-sh/nvm). For Windows users, refer to Microsoft's guide to [Install NodeJS on Windows](https://docs.microsoft.com/en-us/windows/dev-environment/javascript/nodejs-on-windows).
* Node.js and npm. Minimum version Node 22.22.0. You can find instructions on how to install both using nvm (Node Version Manager) for Linux, Mac, and WSL (Windows Subsystem for Linux) [here](https://github.com/nvm-sh/nvm). For Windows users, refer to Microsoft's guide to [Install NodeJS on Windows](https://docs.microsoft.com/en-us/windows/dev-environment/javascript/nodejs-on-windows).
* A local instance of n8n. You can install n8n with `npm install n8n -g`, then follow the steps in [Run your node locally](/integrations/creating-nodes/test/run-node-locally.md) to test your node.
* When [building verified community nodes](/integrations/community-nodes/build-community-nodes.md), you must use the [`n8n-node` tool](/integrations/creating-nodes/build/n8n-node.md) to create and test your node.

View File

@@ -42,10 +42,10 @@ Clone the repository and navigate into the directory:
The starter contains example nodes and credentials. Delete the following directories and files:
* `nodes/ExampleNode`
* `nodes/HTTPBin`
* `credentials/ExampleCredentials.credentials.ts`
* `credentials/HttpBinApi.credentials.ts`
* `nodes/Example`
* `nodes/GithubIssues`
* `credentials/GithubIssuesApi.credentials.ts`
* `credentials/GithubIssuesOAuth2Api.credentials.ts`
Now create the following directories and files:
@@ -81,21 +81,15 @@ In this example, the file is `FriendGrid.node.ts`. To keep this tutorial short,
Start by adding the import statements:
```typescript
import {
IExecuteFunctions,
} from 'n8n-core';
import {
import type {
IDataObject,
IExecuteFunctions,
IHttpRequestOptions,
INodeExecutionData,
INodeType,
INodeTypeDescription,
NodeConnectionType
} from 'n8n-workflow';
import {
OptionsWithUri,
} from 'request';
import { NodeConnectionTypes } from 'n8n-workflow';
```
#### Step 3.2: Create the main class
@@ -133,8 +127,9 @@ description: 'Consume SendGrid API',
defaults: {
name: 'FriendGrid',
},
inputs: [NodeConnectionType.Main],
outputs: [NodeConnectionType.Main],
inputs: [NodeConnectionTypes.Main],
outputs: [NodeConnectionTypes.Main],
usableAsTool: true,
credentials: [
{
name: 'friendGridApi',
@@ -273,45 +268,61 @@ Add the following the `execute` method in the `FriendGrid.node.ts`:
// 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;
const returnData: INodeExecutionData[] = [];
const resource = this.getNodeParameter('resource', 0);
const operation = this.getNodeParameter('operation', 0);
// 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,
};
try {
if (resource === 'contact') {
if (operation === 'create') {
// Get email input
const email = this.getNodeParameter('email', i);
// Get additional fields input
const additionalFields = this.getNodeParameter('additionalFields', i);
const data: IDataObject = {
email,
};
Object.assign(data, additionalFields);
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);
// Make HTTP request according to https://sendgrid.com/docs/api-reference/
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;
}
}
// Map data to n8n data structure
return [this.helpers.returnJsonArray(returnData)];
return [returnData];
```
Note the following lines of this code:
@@ -321,7 +332,7 @@ const items = this.getInputData();
...
for (let i = 0; i < items.length; i++) {
...
const email = this.getNodeParameter('email', i) as string;
const email = this.getNodeParameter('email', i);
...
}
```

View File

@@ -10,9 +10,9 @@ Following defined code standards when building your node makes your code more re
The n8n node linter provides automatic checking for many of the node-building standards. You should ensure your node passes the linter's checks before publishing it. Refer to the [n8n node linter](/integrations/creating-nodes/test/node-linter.md) documentation for more information.
## Use the starter
## Use the n8n-node tool
The n8n node starter project includes a recommended setup, dependencies (including the linter), and examples to help you get started. Begin new projects with the [starter](https://github.com/n8n-io/n8n-nodes-starter).
n8n recommends using the [`n8n-node` CLI tool](/integrations/creating-nodes/build/n8n-node.md) to build and test your node. In particular, this is important if you plan on [submitting your node for verification](/integrations/creating-nodes/deploy/submit-community-nodes.md#submit-your-node-for-verification-by-n8n). This ensures that your node has the correct structure and follows community node requirements. It also simplifies linting and testing.
## Write in TypeScript

View File

@@ -31,7 +31,7 @@ For basic API request failures, catch the error and wrap it in `NodeApiError`:
```typescript
try {
const response = await this.helpers.requestWithAuthentication.call(
const response = await this.helpers.httpRequestWithAuthentication.call(
this,
credentialType,
options
@@ -46,7 +46,7 @@ Handle specific HTTP status codes with custom messages:
```typescript
try {
const response = await this.helpers.requestWithAuthentication.call(
const response = await this.helpers.httpRequestWithAuthentication.call(
this,
credentialType,
options
@@ -54,7 +54,7 @@ try {
return response;
} catch (error) {
if (error.httpCode === "404") {
const resource = this.getNodeParameter("resource", 0) as string;
const resource = this.getNodeParameter("resource", 0);
const errorOptions = {
message: `${
resource.charAt(0).toUpperCase() + resource.slice(1)
@@ -103,7 +103,7 @@ new NodeOperationError(node: INode, error: Error | string | JsonObject, options?
Use `NodeOperationError` for validating user inputs:
```typescript
const email = this.getNodeParameter("email", itemIndex) as string;
const email = this.getNodeParameter("email", itemIndex);
if (email.indexOf("@") === -1) {
const description = `The email address '${email}' in the 'email' field isn't valid`;

View File

@@ -4,7 +4,7 @@ contentType: reference
# Node codex files
The codex file contains metadata about your node. This file is the JSON file at the root of your node. For example, the [`HttpBin.node.json`](https://github.com/n8n-io/n8n-nodes-starter/blob/master/nodes/HttpBin/HttpBin.node.json) file in the n8n starter.
The codex file contains metadata about your node. This file is the JSON file at the root of your node. For example, the [`GithubIssues.node.json`](https://github.com/n8n-io/n8n-nodes-starter/blob/master/nodes/GithubIssues/GithubIssues.node.json) file in the n8n starter.
The codex filename must match the node base filename. For example, given a node base file named `MyNode.node.ts`, the codex would be named `MyNode.node.json`.

View File

@@ -31,7 +31,7 @@ Your node must include:
You can choose whether to place all your node's functionality in one file, or split it out into a base file and other modules, which the base file then imports. Unless your node is very simple, it's a best practice to split it out.
<!-- vale on -->
A basic pattern is to separate out operations. Refer to the [HttpBin starter node](https://github.com/n8n-io/n8n-nodes-starter/tree/master/nodes/HttpBin) for an example of this.
A basic pattern is to separate out operations. Refer to the [GithubIssues starter node](https://github.com/n8n-io/n8n-nodes-starter/tree/master/nodes/GithubIssues) for an example of this.
For more complex nodes, n8n recommends a directory structure. Refer to the [Airtable node](https://github.com/n8n-io/n8n/tree/master/packages/nodes-base/nodes/Airtable) or [Microsoft Outlook node](https://github.com/n8n-io/n8n/tree/master/packages/nodes-base/nodes/Microsoft/Outlook) as examples.

View File

@@ -5,25 +5,36 @@ contentType: reference
# Community node verification guidelines
/// note | Do you want n8n to verify your node?
Consider following these guidelines while building your node if you want to submit it for verification by n8n. Any user with verified community nodes enabled can discover and install verified nodes from n8n's nodes panel across all deployment types (self-hosted and n8n Cloud).
Follow these guidelines while building your node if you want to submit it for verification by n8n. Any user with verified community nodes enabled can discover and install verified nodes from n8n's nodes panel across all deployment types (self-hosted and n8n Cloud).
///
/// note | Upcoming Changes
From May 1st 2026 you must publish **ALL** community nodes using a GitHub action and include a [provenance statement](https://docs.npmjs.com/generating-provenance-statements)
///
## Use the n8n-node tool
All verified community node authors should strongly consider using the [`n8n-node` tool](/integrations/creating-nodes/build/n8n-node.md) to create and check their package. This helps n8n ensure quality and consistency by:
All verified community node authors should use the [`n8n-node` tool](/integrations/creating-nodes/build/n8n-node.md) to create and check their package. This helps n8n ensure quality and consistency by:
* Generating the expected package file structure
* Adding the required metadata and configuration to the `package.json` file
* Making it easy to lint your code against n8n's standards
* Allowing you to load your node in a local n8n instance for testing
## Node Types
* The node **MUST** not be an existing node, If your node is an iteration on an existing node create a pull request instead.
* n8n isn't accepting Logic or Flow control nodes at the moment.
## Package source verification
* Verify that your npm package repository URL matches the expected GitHub (or other platform) repository.
* Verify that your npm package repository URL matches the expected GitHub repository.
* Confirm that the package author / maintainer matches between npm and the repository.
* Confirm that the git link in npm works and that the repository is public.
* Make sure your package has proper documentation (README, usage examples, etc.).
* Make sure your package license is MIT.
* Packages should be published from a GitHub action and include [provenance](https://docs.npmjs.com/generating-provenance-statements)
## No external dependencies