n8nを使って会計freeeのデータをSlackに流してみる、ほぼほぼノンプログラミングで。

# n8nとは

フリーでオープンな自動ワークフローツール、だそうです。

https://n8n.io/
https://github.com/n8n-io/n8n

※ JP1を思い出します

# 手っ取り早く動かす

手元のnodeのバージョンは12.8.0でした。

```bash
$ node --version
v12.8.0
$ npx n8n
n8n ready on 0.0.0.0, port 5678
Version: 0.73.1

Editor is now accessible via:
http://localhost:5678/

Press "o" to open in Browser.
```

ここまで来たら http://localhost:5678/ にアクセスします（もしくは o を押します）

![n8nの画面](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13469/c36bf869-d471-6aba-f5ac-8ab59c31e59e.png)


## Company情報の取得

APIで会計freeeを使うにはcompany_idを取得する必要があります。
さくっとOAuth2認証をしてCompany情報を取得してみます。


### OAuth2認証

右上の Create Node から

![Create Node](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13469/f5b6604a-247e-605d-94f4-2ae45067782a.png)

`http` を検索し、 HTTP Requestを選択します。

![HTTP Request](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13469/512c2a44-c02d-8dff-3218-1edf0e6c4caa.png)

Authentication は OAuth2 を選択して、 Create New で新しく作ります。

![OAuth2](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13469/2a537e49-4086-9baa-8053-300c99899d37.png)


必要な情報を埋めていきます。

| 項目名                     | 入力値                                                    | 備考                    |
|---------------------------|----------------------------------------------------------|------------------------|
| Credentials Name          | freee                                                    | ラベルなのでなんでも良い    |
| Authorization URL         | https://accounts.secure.freee.co.jp/public_api/authorize |                        |
| Access Token URL          | https://accounts.secure.freee.co.jp/public_api/token     |                        |
| Client ID                 | xxxxxxxxxxxxxxxxxxxxxxxxxx                               | ご自身のClient ID        |
| Client Secret             | xxxxxxxxxxxxxxxxxxxxxxxxxx                               | ご自身のClient Secret    |
| Scope                     |                                                          | 入れなくてもOK            |
| Auth URI Query Parameters |                                                          | 入れなくてOK             |
| Authentication            | Body                                                     | Headerだと認証で失敗します |



![OAuth2 Setting](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13469/c052475a-f0ec-f153-7318-5176672f8486.png)


アプリストア側のcallback uriは http://localhost:5678/rest/oauth2-credential/callback を指定します。
（OAuth Callback URLに書いてある）

![アプリストアの設定](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13469/4b2f4f1e-720e-7fee-a167-909e1c3f96ec.png)

ここまで来たら、 `->]` みたいなボタンを押して接続してみましょう。
うまくいくとこんなウィンドウが出てくるので許可します。

![アプリ連携の開始](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13469/7571f146-ac9f-c6f3-f770-84c8b14ab955.png)


ウィンドウに　`Got connected. The window can be closed now.` と出ればOKです。
ウィンドウを閉じて、Credentialの設定を保存します。

### Company情報の取得

URLに `https://api.freee.co.jp/api/1/companies` と入れて、右上の　`Execute Node` を押します。

companyの情報が出てきます。
今後はここで取得したcompany_idを使っていきます。

<img width="1322" alt="HTTP Request Result" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13469/2a6d3622-4571-0a41-65af-4a2bb0d8ab34.png">

## 取引情報の取得

今日の取引データを取得してみます。

指定するパラメータは以下のとおりです。

| 項目 | 値 | 備考 |
|-----|---|---|
| Request Method | GET | |
| URL            | https://api.freee.co.jp/api/1/deals | |
| Response Format | JSON | |

Query Parameter

| Name | Value | 備考 |
|------|-------|------|
| company_id | xxxxxx | 先程取得したcompany_id |
| start_issue_date | 2020-07-10 | 発生日。いったん固定で指定する |
| end_issue_date | 2020-07-10 | こちらもいったん固定 |

ここまで指定したら実行します。
データがあればJSON形式で落ちてきます。

<img width="1323" alt="Deal Result" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13469/aece1898-465e-41ca-249a-cb73d50cc8dc.png">


### 必要なデータだけ取る

#### 収入

https://developer.freee.co.jp/docs/accounting/reference#/Deals/get_deals
API仕様を見ると取引の一覧を取得するのにもいろいろな条件を指定できます。
ここでは収入だけ取得してニヤニヤしようと思います。

Query Parameterに `type` `income` を追加します。


| Name | Value | 備考 |
|------|-------|------|
| company_id | xxxxxx | 先程取得したcompany_id |
| start_issue_date | 2020-07-10 | 発生日。いったん固定で指定する |
| end_issue_date | 2020-07-10 | こちらもいったん固定 |
| type | income | 収入 |


#### 発生日

発生日を毎回手で書き換えるのは面倒なので、現在の日付を取得して指定するようにします。

発生日は Function を使います。（ほぼノンプログラミング

![Create Node](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13469/83adb77a-52de-a0e0-bc81-89293098ef6a.png)

こんな感じで、`YYYY-MM-DD`形式の日付を取得します。

```javascript
const today = new Date();
const yyyy = today.getFullYear();
const mm = ('' + (today.getMonth() + 1)).padStart(2, '0');
const dd = ('' + today.getDate()).padStart(2, '0');

items[0].json.today = [yyyy, mm, dd].join('-');
return items;
```

Execute Node すると、大丈夫そうな感じです。


![日付の取得](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13469/b77f945e-ad00-2862-d37b-043accee80c2.png)


つぎに、 Function から HTTP Request に線を引きます。

![Function→HTTP Request](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13469/68ee148f-9b7e-54d0-b6af-07875a8a5eae.png)


HTTP Requestのパラメータ `start_issue_date` と `end_issue_date` の値をNodeからの返り値に指定します。

![日付の指定](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13469/30c24d52-9a74-0943-2906-c299af31fdb9.png)


もう一度 Execute Node を押して動くか確認しておくと良いでしょう。

これで、「本日発生した収入」を取得することができました。


## Slackに連携

SlackのほうはサクッとOAuth2で接続します。

Execute Nodeをして、n8nからSlackに行けばokです。

![Slackの連携](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13469/4efacd76-6419-79ce-89ba-73ba08cfb70d.png)


### 合計値の計算

収入が複数ある場合はそれを合算した値を知りたいので、freeeからの出力した値を合計します。

ここでは Function を使ってさくっとやります（ほぼノンプログラミング

![HTTP Requestの出力結果を計算](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13469/5ab4c841-963d-a405-cb0a-0a73282c9a24.png)

freeeの後続にFunctionを追加し、そこで計算します。

```javascript
items[0].json.total_amount = items[0].json.deals.reduce((x, y) => x.amount + y.amount);

return items;
```

例によってExecute Nodeをすると合計値が表示されます。

![計算結果](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13469/3884b2b3-4b4c-1eac-fbf1-421ad4712134.png)


### Slackに喋らせる

合計を計算したFunctionとSlackをつないで、 SlackのTextを先程の結果にします。
歯車を押して Add Expression でやると簡単に指定できます。

![Add Expression](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13469/c4b6da82-58bb-6a52-4d57-978f1951de25.png)

Current Nodeからたどって、出力したい値を指定し、喋らせたい文字と合わせます。

![80マンエン](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13469/6dc88c78-7e37-3616-99d8-15cd7aadcb05.png)


## 結果

Startからつなで、下の Execute Workflow を押すと実行されます。

![workflow result](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13469/3be12576-ee2a-04bb-a4a9-605aba65ac26.png)

Slack側はこうなります。

![slack result](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13469/66372425-ec6a-b8e0-8a13-c84e432e1dd1.png)


## 発展

毎回Execute Workflowを押すのはかっこよくないので、時間が来たら勝手に起動するようにしたいです。

TriggerからCronを選択します。

![TriggerからCronを選択](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13469/42515d12-ee85-c838-eeed-1ad0162b8cee.png)


あとは実行時刻を指定して、

![実行時刻の指定](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13469/446a5f44-2c3b-4d5f-8cc7-1feb0c66c231.png)


Cronとつないで、

![Cronと接続](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13469/e64895f5-f104-2268-d380-7ecbaf7cbf0a.png)

右上の Active を有効にすればOKです！

![Active化](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13469/84fe12fe-c472-48b2-354e-cd4cf5f7e711.png)


あ、ひとつ設定がありました。
Settingから

![Setting](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13469/cc46bc65-d5d2-305c-eeba-f3a877d6c4b6.png)

Timezoneを正しく指定しないとCronで指定した時刻に起動しなくなります :sweat_drops: 

![Timezoneの設定](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13469/500884c4-5e1a-558a-5f99-bf30d58d4d2f.png)


# いかがでしたか？

いかがでしたか？
freeeAPIを使うのって結構面倒かなと思うのですが、n8nをつかうことで比較的簡単にデータ連携ができました。
HTTP Requestを受け取れてOAuth2等で認証できるサービスであれば、n8nで連携できるのでぜひいろいろな連携を試していただければと思います。



# 裏話

こんな感じのfreee用のNodeを作っていたんですが、標準のHTTP Requestで行けそうと気が付いてしまいました。。。

![作り途中のやつ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13469/4e4fc500-cd34-ec90-4d9c-16b20c96683d.png)

コードはこちら
https://github.com/tamurashingo/n8n/tree/feature/freee