n8nでConfluenceのページを投稿するテスト

職場では日々「効率化」とか「自動化」が叫ばれているのだが、「Flowは使ってはいけません」という謎の御触れが出ていている時代錯誤な状況になっている。セキュリティを考えると仕方がないのだが、なんだか変だなと思う今日この頃。自前でなんとかできないかと色々調べていたらところ、最近「[n8n.io](https://n8n.io/)」という、MicrosoftのFlowのような仕組みが手軽に作れる(らしい)ツールがあることを知った。

n8n.ioでは、以下のようなブラウザ上で動くGUIを使ってノードをつなぎ、JSONやバイナリデータを生成・加工しながら渡していくことで、HTTPリクエストやその他サービス(GitとかGoogle Driveとか)、ローカルPCの処理をつなぐことができるようになっているらしい。こう書くと「Jenkinsと何が違うのだろう」と考えてしまうのだが、n8n.ioではFunctionというノードでデータを加工できるので、ただのタスク制御に留まらず、業務/作業をn8n.io上でプログラムできてしまうという嬉しさがあるように思えた。(まだ触ったばかりで良く分かっていない)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296170/72b433a1-982c-4a45-3cdb-59382dbffd66.png)

もちろん、NestJSやAngularを使って、まとまった機能(というより、複雑なビジネスロジックが必要なこと)を提供するアプリを作れたら便利な場面があると思うが、小さな機能をつなぎ合わせて単純な流れ作業を簡単に作れるのも、職場では結構役に立つかなと思う。(多分、前者はプロセスやルールの順守に役立ち、後者はちょっとしたレポート作成や発注作業をするのに役立つと思う。職場ではほぼ手作業だけど)

# とりあえず導入してみる
[Node.jsとnpm](https://nodejs.org/ja/)をインストール済みであれば、n8n.ioの [Setup](https://docs.n8n.io/#/setup)の通り、インストールをすれば導入完了。(ここに書くまでもない…1行のコマンドで終わり)

# とりあえず動かしてみる
ConfluenceやJiraでチケットをたくさん作るとか、お知らせページを作るということがある。こうした作業に役立つよう、汎用的なHTTP Requestノードを使って、ConfluenceのREST APIからページを作るWorkflowを作成してみる。(設定にミスすると 400 bad request を連発するので気を付けること)

ここでは、指定したページに子ページを追加していく。はじめて動かすので、親ページやページの内容は固定とする。実際に活用するときはFunctionノードを使って外部から取得したデータを使ってページの本文を作るなどすれば、色々な使い方ができる。ページの作成は以下の3ステップで実現できる。

* ページを作るためのデータを用意する(これはREST APIを使うときは必須)
* ページを作るためのデータを出力するノードを作る(Functionノード)
* ConfluenceのREST APIにデータを渡すノードを作る(HTTP Requestノード) 

## ページを作るためのデータを用意する
ConfluenceのREST APIから、ページを作るためのエンドポイント[api/contentのCreate content](https://docs.atlassian.com/ConfluenceServer/rest/7.2.1/#api/content-createContent)」や、REST APIを使ったページ投稿の記事(Ricksoft「[REST APIでConfluenceのページを作成](https://www.ricksoft.jp/blog/archives/2984/)」)を参考に、ページを作るためのデータを用意する。

資料によれば、REST APIのPOSTメソッドで、Bodyパラメータに以下のようなデータを渡してあげれば、ページが作れるとわかる。ここでは、タイトル「n8n POST Test」で、本文は「This is a new page」、親ページにID 9371651のページを指定している。(指定しない場合は、spaceの設定が必要となる。その他データに不備があればConfluenceが400 bad request何がいけないかを教えてくれる)

```json
{ 
  type: "page", 
  title: "n8n POST Test",
  body: {
    storage: {
      value: "<p>This is <br/> a new page</p>",
      representation: "storage"
    }
  },
  ancestors: [ { id: "9371651" } ]
}
```

## ページを作るためのデータを出力するノードを作る(Functionノード)
上記データ(固定値)を生成するFunctionノードと、
画面右の「+」ボタンを押して「Function」ノードを選択し、編集画面に追加する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296170/1f652857-4d70-258d-1d60-b836d75131a3.png)

Functionノードをダブルクリックするか、編集ボタンを押すと、編集画面が表示される。Functionのテキストボックスを選択すると、このFunctionノードで実行するJavascriptのコードを書くことができる。ここでは、固定値を返すだけだが、戻り値には注意が必要。[n8n.io Data Structure](https://docs.n8n.io/#/data-structure)によると、ノードの出力形式は以下のように決まっている。

```json
[ {
  json: { オブジェクトなんでもOK },  ← 必須
  binary: {　← 任意
    キー: {
       data: 'Base64のデータ',  ←必須
       mimeType: 'image/pngのようなMIMEタイプ', 
       fileExtention: 'pngの様な拡張子'
       fileName: '拡張子を含むファイル名'
    }
  }
} ]
```

ここでは以下のように、`page`キーにページを作る情報を載せてあげることにした。

```javascript:Functionの中身
const data = { 
  type: "page", 
  title: "n8n POST Test",
  body: {
    storage: {
      value: "<p>This is <br/> a new page</p>",
      representation: "storage"
    }
  },
  space: { key: 'TEST' },
  ancestors: [ { id: "9371651" } ]
};

return [ { json: { page: page } } ]
```

## ConfluenceのREST APIにデータを渡すノードを作る(HTTP Requestノード)
今度はHTTPリクエストノードを作成する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296170/f09d6826-1a59-77d6-c278-df235aa35b06.png)

HTTPリクエストノードの編集画面を開くと、いくつか設定項目が表示される。それぞれ、以下のように設定する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296170/6e215d1c-995a-0012-548e-da9f548b791c.png)
設定項目は以下のように決めた。

| 項目 | 試した際の設定値 | 設定の仕方 |
|:--|:--|:--|
|Credentials | ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296170/153d4582-fdc2-10ec-93b9-ee871f4501cb.png) | 認証情報を作成するか、保存済みの認証情報をアサインする。なければ作成する。 |
| Authentication | (自動) | Credentials を選べば、認証情報から自動で設定される。 |
| Request Method | POST | Confluencenのページ作成に使うメソッドより。|
| URL | http://localhost:8090/confluence/rest/api/content | *BaseUrl*/rest/api/contentであればOK |
| Ignore SSL Issues | OFF | 不明…デフォルトのまま |
| Response Format | JSON | Confluenceの応答形式より。 |
| JSON/RAW Parameters | ON | Functionブロックのオブジェクトをそのままパラメータに使うため。 |
| MIME TYPE | application/json | REST APIに渡すデータはJSONのため。 |
| Send Binary Data | OFF | 普通のJSONなので。 |
| Body Parameters | Add Expressionボタンを押してエディタを開き、![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296170/b5b08029-8f36-e874-3ad5-1b928491c552.png) 入力データの`page`オブジェクトのRaw Valueを選ぶ。![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296170/58bb52f7-a5e6-466f-e0f0-74af9774647f.png)|ノードに与えられたデータや、ノード自身の情報からデータを作成する。|
| Headers | 指定なし | 認証方法次第では追加する。 |
| Query Parameters | 指定なし | 必要ならREST APIの仕様に従い設定する。 |

## 試してみる
以下の画面で、「Execute Workflow」を押すと、初めからノードが動き出す。(ノードだけ実行というのもできるが、そうすると入力データは古いままになる)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296170/72b433a1-982c-4a45-3cdb-59382dbffd66.png)

成功したら、以下のようにConfluenceからの応答がResultsに表示される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296170/abb9ddcf-f008-8454-f42b-f65e56b2e60f.png)

Confluenceで確認してみると、以下のように、親ページ(id: 9371651, タイトル: n8n root)の下に、ページが作られていることが分かる。(タイトルは何度か試したので「n8n POST Test3」になっている)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296170/317ffc0d-788f-f1b6-19bb-95d272309ac9.png)

# まとめ
Flowみたいなフリーのツールn8n.ioを使って、Confluenceのページを作ってみた。サンプルでは固定ページだったが、n8n.ioのWebhookノード(トリガ?)を使うなどすれば、取得したデータをConfluenceページに投稿するとか、別のデータを取りに行ってページに反映するとか、色々な活用の仕方ができそうだった。

# 2020/01/18追記: 気を付けること
独自機能のノードは「[Create Node](https://docs.n8n.io/#/create-node)」や、その適当訳「[n8n.io ノードを作る(マニュアル)](https://torimemoblog.wordpress.com/2020/01/17/n8n-io-%e3%83%8e%e3%83%bc%e3%83%89%e3%82%92%e4%bd%9c%e3%82%8b%e3%83%9e%e3%83%8b%e3%83%a5%e3%82%a2%e3%83%ab/)」を参考にすると作れる。ノードと言っても、入力データを加工して出力するような、関数に毛が生えた程度のものなので、実は割と簡単に作れる。

~~ただ、投稿時点ではノードの作成を助けてくれるCLIツール「n8n-node-dev」がWindowsでビルドができないという問題がある。わずかな修正で解決するので、「[Not able to create custom node (error TS18003)](https://community.n8n.io/t/not-able-to-create-custom-node-error-ts18003/343/5?u=stm32p103)」を参考に直して使うと良い。~~

追記した直後に、[作成者からver0.6.0で修正したと回答](https://community.n8n.io/t/not-able-to-create-custom-node-error-ts18003/343/6?u=stm32p103)があった。バージョンアップ後にエラーは起きなくなったので、今後インストールする人は大丈夫だと思う。