Skip to content

Extending with custom N8N nodes

What is n8n or an integration hub?

Don't know yet what n8n is or what an integration hub does? Find more information on that on our blog.

If you want to start your own n8n, here is a tutorial on how to do that.

If you want to create your own nodes in n8n, there are 2 ways to do this.

  • Complex nodes (with external dependancies and extra files).

  • Simple nodes (no external dependencies)

COMPLEX NODES

For this you can not run your n8n in a docker setup.

SIMPLE NODES

Create node

Let’s create a node that consumes Odata (SAP / Microsoft Dynamics for example)

Installation of n8n-node-dev
npm install n8n-node-dev -g
Create folder/repo for your custom node 
cd to the folder.
Create your typescript file
import { IExecuteFunctions } from 'n8n-core';
import {
    INodeExecutionData,
    INodeType,
    INodeTypeDescription,
} from 'n8n-workflow';


export class Odata implements INodeType {
    description: INodeTypeDescription = {
        displayName: 'Odata Node',
        name: 'Odata',
        group: ['transform'],
        version: 1,
        description: 'Fetch a specific reource from a Odata API',
        defaults: {
            name: 'Odata Node',
            color: '#772244',
        },
        inputs: ['main'],
        outputs: ['main'],
        credentials: [
            {
                name: 'httpBasicAuth',
                required: true,
                displayOptions: {
                    show: {
                        authentication: [
                            'basicAuth',
                        ],
                    },
                },
            },
            {
                name: 'httpHeaderAuth',
                required: true,
                displayOptions: {
                    show: {
                        authentication: [
                            'headerAuth',
                        ],
                    },
                },
            },
            {
                name: 'OdataOAuth2Api',
                required: false,
                displayOptions: {
                    show: {
                        authentication: [
                            'oAuth2',
                        ],
                    },
                },
            },
        ],
        properties: [
            {
                displayName: 'Authentication',
                name: 'authentication',
                type: 'options',
                options: [
                    {
                        name: 'Basic Auth',
                        value: 'basicAuth',
                    },
                    {
                        name: 'Header Auth',
                        value: 'headerAuth',
                    },
                    {
                        name: 'None',
                        value: 'none',
                    },
                ],
                default: 'none',
                description: 'The way to authenticate.',
            },
            // Node properties which the user gets displayed and
            // can change on the node.
            {
                displayName: 'odata base url',
                name: 'baseUrl',
                type: 'string',
                default: '',
                placeholder: 'https://username:password@localhost/path/to/service/',
                description: 'The base url of the Odata service',
            }
        ]
    };


    async execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {

        const items = this.getInputData();

        let item: INodeExecutionData;
        let baseUrl: string;

        // Itterates over all input items and add the key "baseUrl" with the
        // value the parameter "baseUrl" resolves to.
        // (This could be a different value for each item in case it contains an expression)
        for (let itemIndex = 0; itemIndex < items.length; itemIndex++) {
            baseUrl = this.getNodeParameter('baseUrl', itemIndex, '') as string;
            item = items[itemIndex];

            item.json['baseUrl'] = baseUrl;
        }

        return this.prepareOutputData(items);

    }
}

Build the typescript

1
n8n-node-dev build

This will generate the code into your home folder.

Move the build node

Move it into your n8n custom folder (you might need to create this first)

You can find the location in your docker-compose.yml file

n8n

This first part is the location on your filesystem, the last part is in the n8n image. The first part uses the variable DATA_FOLDER from the .env file.

1
Create {DATA_FOLDER_FROM_ENV}/.n8n/custom

Restart your n8n

If you’re using docker-composer:

1
docker-compose kill n8n && docker-compose up -d

There it is

n8n

Check the code here.

Example Odata Function invocation

n8n

Odata Get person

n8n

Odata Get Property on person

n8n

Example Flows

Regularly sync odata accounts

n8n

On Drupal account CREATE, push to external system

n8n

n8n

On drupal account UPDATE, propagate to external system

n8n

Data Transformations

Functions

Alter the data to enrich/cleanup your data in the flow.

n8n

Conditionals

n8n

n8n

n8n