調べもの

n8n.io ノードを作る(マニュアル)

n8n.io でノードを作る方法を適当に訳してみたもの。試したところ、ノードをビルドするコマンドはうまく動かないようだった直し方は分かったので、当座はリンク先の暫定的な対処で何とかなると思う。と知らせたらv0.6.0で直してくれたので、今後使う人は大丈夫。

ノードを作成する

n8nでは自身でノードを作るのはとても簡単で、3つのことを定義すればよい。

  1. 名前や説明、アイコンなどの全般情報
  2. ユーザがノードを操作・設定するためのパラメータ
  3. ノードが実行されたときに行う処理

n8n.ioでは開発工程を簡単にするため、ボイラプレートコードの生成と、ノードのビルド(Typescriptで書かれているため)と適切な場所にコピーするための基本的なCLIを提供している。

初めてのノード作成

  1. n8n-node-dev CLIをインストールする: npm install -g n8n-node-dev
  2. ノードのコードを書きたいフォルダを作成する
  3. 作成したフォルダ内でCLIを使ってノードのボイラプレートコードを作成する: n8n-node-dev new
  4. CLIからの質問に回答する(ちなみに、大抵はExecuteタイプのノードを作ることになる)。これができたら、コードがフォルダ内に生成される。
  5. プログラムを書き、ノードに機能を追加する。
  6. ノードをビルドし、正しい場所にコピーする: n8n-node-dev build。このコマンドにより、TypescriptのコードからJavascriptのコードが生成され、カスタムノードを読み出すフォルダ~/.n8n/custom/にコピーされる。
  7. n8nを再起動し画面を表示すれば、新しいノードが表示される。

ノードモジュールを作成する

以下のような性質の複数のカスタムノードを作成する場合、別々にインストール可能なn8n-nodes-moduleノードモジュールを作成すると良い。

  • 自分または自社専用
  • 一部の限られた人向け
  • 互いに依存関係をもつ

n8n-nodes-module は、n8nが起動時に自動的に見つけてロードすることのできる、ノード群を含むシンプルなnpm パッケージである。

こうしたモジュールを作る場合、n8nが自動的にノード群を見つけられるよう、以下の規則に従う必要がある。

  • モジュール名は n8n-nodes- から始まること
  • package.json が、n8n キーにノードや資格情報へのパスを含むこと。
  • モジュールはn8nと共にインストールされること

訳注: ノードを複数作って、package.jsonと一緒に置いておくだけなので、モジュールを作るための特別な手続きはない模様。

資格情報(Credentials)とは?

サンプル: n8n-nodes-starterを見たところ、資格情報=ノードの設定画面に表示する、ノードが必要とするユーザ名やアクセストークンといった設定項目の情報を指していた)。

import {
	ICredentialType,
	NodePropertyTypes,
} from 'n8n-workflow';


export class ExampleCredentials implements ICredentialType {
	name = 'exampleCredentials';
	displayName = 'Example Credentials';
	properties = [
		// The credentials to get from user and save encrypted.
		// Properties can be defined exactly in the same way
		// as node properties.
		{
			displayName: 'User',
			name: 'user',
			type: 'string' as NodePropertyTypes,
			default: '',
		},
		{
			displayName: 'Access Token',
			name: 'accessToken',
			type: 'string' as NodePropertyTypes,
			default: '',
		},
	];
}

n8n-nodes-modulesを使う

カスタム n8n-nodes-modules を使うには、以下のようにn8nとモジュールを一緒にインストールする。

# n8nをインストールするフォルダを作る
mkdir my-n8n
cd my-n8n

# n8nをインストールする
npm install n8n

# カスタムn8n-nodes-modulesをインストールする(ローカルのモジュールでも可かと思う)
npm install n8n-nodes-my-custom-nodes

# n8nを起動する
n8n

# 訳注
# n8nだけだとグローバルインストール(npm install -g)のn8nを指す。
# ローカルインストールした場合 node_modules\n8n\bin\n8n で起動する。

n8n-nodes-moduleの開発とテスト

一般的な npmモジュールと同様。n8n-nodes-module をインストールしたフォルダで、以下を実行すればよい。

# ビルド
npm run build

# ローカルにパッケージを発行
npm link

そして n8nがインストールされているフォルダで、以下を実行する。

# 上記でローカルに発行したパッケージをインストールする
npm link n8n-nodes-my-custom-nodes

# n8nを起動する
n8n

# 訳注
# n8nだけだとグローバルインストール(npm install -g)のn8nを指す。
# ローカルインストールした場合 node_modules\n8n\bin\n8n で起動する。

ノード開発のガイドライン

入力されるデータを変更してはならない

ノードが受信するデータ(this.getInputData()で取得できる)は、他のノードと共有されるので変更してはならない。データを追加・変更・削除する必要がある場合、クローンした新しいデータに対して追加・変更・削除すること。そうしないと、兄弟ノード(訳注:同じデータを受け取るはずのノード)で、後で実行されるノードでは、変更された後の入力データを処理してしまう。

しかし、常にデータをクローンする必要はない。例えば、バイナリデータだけ変更するだけなら、JSONデータの部分に元のJSONデータへの参照を与えても良い。その例を ReadBinaryFile-Node で見ることができる。

訳注: n8nでは、ノード間のやりとりを「Data Structure」の章に書かれている {json: { key1: オブジェクト, key2: オブジェクト, ...}, binary: { key: バイナリ1, key2: バイナリ2,...} } のようなデータで行っている。binaryキー以下を変更する分には、json キーにクローンを与えず、古い json キーのオブジェクトへの参照を与えても良いということらしい。

ノードをTypescriptで書く

n8nのすべてのコードはTypescriptで書かれているので、ノードもそうあるべきである。これにより、開発がより簡単で速くなり、いくらかはバグを回避できるようになる。

ビルトインのリクエストライブラリを使う

いくつかのサードパーティのサービスではnpmでライブラリが提供され、利用しやすくなっている場合がある。これは非常に使いたくなってしまうのだが、依存関係が生じると、更に依存関係が派生していってしまう問題が生じる。これにより、より多くのコードが追加され、ロード量が増加し、脆弱性やバグを導入してしまう可能性も生じる。だから、以下のようなビルトインモジュールを使ってほしい。

const response = await this.helpers.request(options);

これは、npmパッケージのrequest-promise-nativeという、基本的なnpmパッケージであるrequest モジュールをPromise化しただけのシンプルなモジュールである。optionについては request のドキュメントを参照のこと。

パラメータ名を再利用すること

ノードが、ある種のエンティティに編集や削除などの複数の操作を行える場合、いずれの操作でもentityIdのような情報が必要となる。こうした情報は、editIdとかdeleteIdのように呼び方を変えず、一貫してid と呼ぶこと。

n8nでは同名のパラメータが複数あっても、可視であるものが1つであれば問題なく扱うことができる。パラメータ名が同じであれば、ユーザは値を保ったまま、操作(例えば edit と delete)を切り替えることができるようになる。

訳注: REST APIではリソースに対して取得・更新・削除が行えるので、ノードではoperationのようなパラメータで操作を選択できるようにする場合がある。この時、処理対象を指定するためのIDをパラメータとして持たせるかと思うが、その際に「編集対象ID」とか「削除対象ID」のように分けない方が良い。操作を切り替えた時にまたIDを設定し直すのは面倒だから。

optionsパラメータにまとめる

いくつかのノードはたくさんのオプションを必要とするかもしれない。その場合、重要なオプションだけをトップレベルに置き、その他は options 以下にまとめると、インターフェースがすっきりしてユーザを不必要に混乱させずにすむ。その良い例がXMLノードである。

既存のパラメータ命名ガイドラインに従う

というほどガイドラインはないのだが、複数のことが行えるノードにおいて、振る舞いを決めるパラメータであれば mode (MergeやXMLノードなど)や、operation (その他多くのノード) と呼ぶと良い。また、操作の対象となるリソースを選択するのであれば resource パラメータと呼ぶと良い。

ノードのアイコン

自作する前に、既存のアイコンをチェックすること。アイコンの解像度は60x60px以上であり、PNG形式であること。

コメントを残す