Node-RED: API != Programing

#はじめに
この記事はシスコの同志による Advent Calendar の一部として投稿しています
- 2017年版: https://qiita.com/advent-calendar/2017/cisco
- 2018年版: https://qiita.com/advent-calendar/2018/cisco
- 2019年版: https://qiita.com/advent-calendar/2019/cisco
- 2020年版: https://qiita.com/advent-calendar/2020/cisco
- 2020年版(2枚目): https://qiita.com/advent-calendar/2020/cisco2
- 2021年版: https://qiita.com/advent-calendar/2021/cisco
- 2021年半(2枚目): https://qiita.com/advent-calendar/2021/cisco2

本記事は2021年版Advent Calendarの２２日目の投稿です。私個人としては初めての投稿になります。

#Node-REDとは
Node-JSベースのローコードプログラミングツールで、フローチャートのような図を描いてロジックを実装していくことができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2319569/e1f57b19-bbc4-b410-09f6-925f7b557994.png)

#Node-REDの良いところ

1. <details><summary>プログラミングの知識がなくても使える</summary>ネットワーク機器のコマンドだったら慣れているけど、プログラミングは未経験という方は多いと思います。基礎的なプログラミングはOSPFやBGPなどのオプションを全て覚えるのに比べると簡単だと思いますが、慣れていないから分からない・近寄りたくないという方にとっても気軽に始められる点で非常に優れているツールであると思います。</details>

1. <details><summary>ネットワークにまつわるAPIで必要な入出力が完備されている</summary>HTTPのI N/OUTが標準装備で、ngrokモジュールも公開されたものがありますので、固定のグローバルIPアドレスがなくてもWebhookを受信する子もできます。また、私が所属するMeraki関連ではMQTTのPublisher/Subscriberにもなれますので、これ一つでMeraki関連のAPIを扱うことができます。</details>

1. <details><summary>作ったプログラムを簡単に共有できる</summary>作成したプログラムはフローと呼びますが、JSON形式で簡単にエクスポートして他の人と共有できるほか、GitHubを経由して公開することも可能です。</details>

#Node-REDを使ってみる
##インストール
Node-REDはNode.jsというサーバサイドJavaScriptで動きますので、色々な環境で利用することができます。私は手元のMacBookで動かすことにしましたので、以下の手順でインストールしました。

```:ターミナル
＃Node.jsのインストール
brew install node

#Node-Redのインストール
sudo npm install -g --unsafe-perm node-red

#Node-Redの実行
node-red
```
Windowsやラズパイで動かすこともできますが、インストールの仕方はオフィシャルサイトをご覧いただくかググってみてください。

##Node-REDのエディタにアクセスする
デフォルトではtcp/1880で動作しますので、ブラウザに http://localhost:1880/ と入力してアクセスすると白紙のキャンバスが見えてきます。

##Hello World!!してみる
まず、この図のように[HTTP IN]-[CHANGE]-[HTTP RESPONSE]の順に並べてワイヤで繋ぎます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2319569/3bbb9c37-3766-f312-3d94-931246ed7560.png)

次に一番左のHTTP INをダブルクックしてプロフパティを開きます。ここではアクセス先のパスを指定する必要がありますので、なんでも良いのですが /hello としてみました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2319569/d4b0ca1e-c1d1-7eb1-c460-af57358f590e.png)

次に真ん中のCHANGEノードをダブルクリックして、表示させたい"Hello World!!"を入力します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2319569/79afaacb-c594-cfc8-f0f7-68a8f5b89d38.png)

最後に画面右上のDeployボタンをクリックして完了です。このボタンが赤いときは変更が反映されていませんので、変更した後には必ずクリックしてから動かすようにしましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2319569/2734d28a-cc24-636e-904b-6463ecb83a18.png)

動作確認としてブラウザでアクセスしてみます。
http://localhost:1880/hello
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2319569/f62b2858-8d82-40ba-b51e-53efc6f8aeb0.png)

Hello World!!できました。

##少し解説
何気なくぽちぽちノードを並べて繋げただけで、簡単なアプリケーションが出来上がりました。ここで一つ理解しておいた方が良い重要なことが起きていました。それはノードとノードを繋いでいるワイヤが何をしてくれているのか？ということです。答えから先に書くと、このワイヤは msg という変数をノード間で受け渡しています。HTTP INとHTTP RESPONSEは必ずセットで使う必要があるのですが、アクセスがあったときに返す値をmsg.payloadという部分から取り出してきます。msg.payloadは本当によく使うのですが、 msg というオブジェクト型変数の一部になります。

msg をやりとりしてプログラムが成立するというのは本当に大切なことなので、もう少し深掘りしてみたいと思います。まず、debugノードをこのように配置して、Deployします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2319569/936d9cf2-86fc-ef3e-e571-e0a4acd62d2f.png)

その後もう一度Hello World!!の画面をリロードしてみます。先ほどと同じようにHello World!!と表示されるだけですが、その後Node-REDの画面に戻ってきて、画面右上の虫さんマークをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2319569/082f5c4b-383b-8596-0d81-35d1129af8f4.png)

そうすると、HTTP INでは値がない状態でしたがCHANGEノードを通過することによってHello World!!に書き換えられたことがわかります。今度はこのDEBUGノードでmsg全体を見てみます。ノードをダブルクリックしてdebugの対象をmsg全体に広げます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2319569/c2619ecc-810a-22bd-19a9-f0c686cc2c9b.png)

両方ともを変更して、忘れずにDeployをクリックした後に、再度Hello World!!を読み込んでみると、Node-REDのdebugには次にような表示が出ることかと思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2319569/50b96294-1e05-3fd1-10e1-46847eb70901.png)

実は表示しているメッセージだけではなく、セッションのIDとかリクエスト・レスポンスのパラメータなんかも持ち運ばれていたことがわかってきます。

まずはmsgというNode-RED独特の変数が使われることと、この変数にはPayload以外の属性も含まれているということを理解しておくと後々悩むことが減る思いますので、少し長くなりましたが解説してみました。

#Meraki APIでやりとりをしてみる
##Webhookの受信
クラウドサービスのsyslogと思えば良いかと思いますが、Webサービスで何かイベントが起きた時の通知の手段です。

インターネットからメッセージが飛んできますので、家庭やオフィスで利用しているPCが受信できるようにngrokを利用します。ngrokを単体で利用しても良いのですが、便利なノードがありましたので使ってみました。

右上のメニューからManage paletteをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2319569/c14a1a0d-5f69-92e4-fc60-eecebdd80cb2.png)

Installタブでnode-red-contrib-ngrokを検索してインストールします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2319569/d6451a9a-dbf3-ab51-70a2-a9c24f62ea65.png)

今回は受信するだけですのでこのようにフローを作りました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2319569/d0d63129-dbeb-ec54-63ab-295369af7335.png)

まず、ngrokを有効にします。ノードの左側にある薄緑のところをクリックすると有効になり、debugのところにアクセス先となるURLが表示されると思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2319569/7543731a-49ca-1a10-2c01-8f39c32ce89d.png)

このURLをコピーして、MerakiダッシュボードでWebhookの設定を行います。［ネットワーク全体］→［アラート］のページの下ほうにWebhookの設定はあります。URLの部分にはngrokで生成されたホスト名にノードで指定しているパス（この例では/webhook）を追加してあげる必要があります。共有パスワードはなんでも良いのですが、cisco123としてみました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2319569/3ff3f255-1496-365b-6274-abec5fd87ebe.png)

テストWebhookを送信というボタンをクリックするとテストメッセージが受信できると思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2319569/ec767f3a-7d95-af66-ab11-dd1a3ddfffbc.png)

syslogみたいなものと例えましたが、メッセージの中身はsyslogよりも充実してそうですね。

ここで少しセキュリティ対策を施します。Webhookの送り先は言ってみればただのWebサーバですから、基本的には誰でもアクセス可能です。もし悪意のある人がこの宛先を知って、偽のメッセージを投げてこられたら困りますよね？実際には起きてない障害が起きたことになって、バタバタするかもしれません。このような事態を回避するために共有パスワードを受信時にチェックして、信頼できる送信元かどうかをチェックすることができます。この例ではすでにcisco123とセットしてありますから、チェックする仕組みをフローに組み込みます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2319569/7cb47e97-ea68-51ff-5bb7-56faf0aa1a85.png)

今回利用するのはスイッチノードです。HTTP INとHTTP RESPONSEの間にドロップすると自動的にワイヤも再接続してくれます。賢いやつですね。プロパティはこのようにmsg.payload.sharedSecretがcisco123と完全一致しているかどうかを定義して、他のものであったら捨てます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2319569/aa8856a2-407d-9fa2-515c-2db9e399e6c8.png)

これで再度テストする際にcisco１２３４などと少しでも変更すると、エラーになると思います。このように条件分岐する際にはスイッチノードを使います。

##Dashboard APIをコールしてみる
Dashboard APIは文字通りダッシュボード上で行う設定だったりステータスの確認等をREST　API経由で行うものです。作成するフローはこのようになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2319569/0203dda7-acc8-e0cf-6d11-46b5dd1e0ede.png)

WebhookやHello World!!ではWebアクセスによってその後のフローが動作していましたが、今回は手動でフローを開始する必要がありますので、インジェクトノードを最初に置きます。その後ろにHTTP REQUESTを置いて完了ですが、動作確認のためのDebugを最後に置いています。HTTP REQUESTは、URLの設定だけですが今回はオーガナイゼーション一覧を取得するためのURLを指定しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2319569/f67dcc59-4327-2227-0799-af60e7443ff8.png)

認証に使うAPIキーの設定などはインジェクトノードの中で行なっています。CHANGEノードと同じように値のセットを行うことができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2319569/86e6b77e-bf34-e076-ea07-025a744d7f74.png)

準備としてDashboard APIを受け付けるようにオーガナイゼーションの設定を行うことと、Meraki Dashboardアカウントに対するAPIキーの生成が必要になります。

［オーガナイゼーション］→［設定］
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2319569/e9a4d891-6c34-3c19-8c95-1757d43f5107.png)

［画面右上のメールアドレス］→［プロファイル］
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2319569/f9788761-c4c9-99e5-6b60-605a415746fb.png)

なお、最新のDashboard APIに関するドキュメントはこちらで確認できます。
https://developer.cisco.com/meraki/api-v1/

これでインジェクトノードの左にあるボタンをクリックすることで実行でき、応答をdebugで確認できるかと思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2319569/12f00fde-3e2b-5708-6934-f89407a3f3ff.png)

ただ、ここで気がつく方もいるかもしれませんが、JSONの形式で表記された文字列として取り扱われています。このため、この先の処理をしやすくするために少し工夫をします。HTTP REQUESTノードのプロパティを開き、JSON Parseするように変更します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2319569/75b92056-475f-9c28-f371-9ed59f722cec.png)

もしくはこのようにJSON Parseのノードを挟みます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2319569/73b44410-bf40-6021-ac59-13322b626b75.png)

これによりdebugが次のように変化し、後で扱いやすくなります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2319569/336721d6-4c95-066c-70c0-f655b887db97.png)

##便利なパレット
ここまででAPIに触れることができ、同じような方法でMeraki以外のAPIも触れることができるようになると思います。Merakiでは簡単にAPIをご利用いただくためにいくつか専用のパレットを準備しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2319569/13e1ad0e-ade3-8aa0-8037-e6e595824816.png)

node-red-contrib-meraki-cmxはSanning APIという無線アクセスポイントで検出したMACアドレスの位置情報を取得するためのノードになります。今回は使いません。

node-red-contrib-meraki-dashboard-api-v1を入れておくと、先ほどのDashboard APIへのアクセスもより簡単になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2319569/6b3fb965-e2a4-9958-0710-7a58adfab6ca.png)

DashboardノードのプロパティからAPIエンドポイントの一覧を探すことができますので、ドキュメントを読まなくもダッシュボードの操作に慣れている方でしたら探していくことができるようになっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2319569/44250eca-63d2-3713-99fc-3606f81f91fa.png)

以下のようなフローにすることでHTTP REQUESTノードで作った時と同じように動きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2319569/361db9b8-489b-6660-c251-b6682ee21029.png)

#おわりに
今までプログラミングが苦手でAPIな話題には耳を塞いでいた方も、Node-REDを利用すれば自分でもできるんじゃないかな？と思われたのではないでしょうか？実際、私の同僚の数名はNode-REDを知ることでAPIを使ったプログラムを作り始めました。Node-REDは今日紹介したこと以外にもLINEに通知を出すためのパレットなども備えていますので、実用的なアプリケーションを作るために便利な要素が詰まっています。また、子供向けのプログラミング学習で電子工作キットなどでも利用されていて、仕事の場面以外でも役に立つと思います。この記事がきっかけで、少しでもプログラミングアレルギーをお持ちの方が減ると嬉しいです。

#免責事項
本サイトおよび対応するコメントにおいて表明される意見は、投稿者本人の個人的意見であり、シスコの意見ではありません。本サイトの内容は、情報の提供のみを目的として掲載されており、シスコや他の関係者による推奨や表明を目的としたものではありません。各利用者は、本 Web サイトへの掲載により、投稿、リンクその他の方法でアップロードした全ての情報の内容に対して全責任を負い、本 Web サイトの利用に関するあらゆる責任からシスコを免責することに同意したものとします。