Node-REDを使ってみる その2(Googleフォーム、Googleスプレッドシート)
はじめに
今回はNode-REDとGoogleフォーム、Googleスプレッドシートを連携させてみました。
Googleフォームで入力した内容をGoogleスプレッドシートにリンクし、Node-REDで取得するという流れです。最近行われた大阪24時間AIハッカソンのときに使ったのですが、実用的に使えそうでした。
入力がGoogleフォームなので、OSやデバイスによる違いも勝手になんとかしてくれるのがありがたいですね。共有して共同で作業するのも楽でした。
▼以前の記事はこちら
Googleフォームの準備
まずはGoogleフォームを作成します。
▼Googleドライブで右クリックし、Googleフォームを選択します。今回はテンプレートから作成します。

▼連絡先情報のテンプレートを使ってみます。

▼開くとこんな感じ。質問項目の設定などができます。

▼質問項目は必須にしたり、記入式や選択式にしたり、ファイルのアップロードを要求したりできます。


▼右上にある送信ボタンから、回答フォームのリンクを発行することができます。


▼PCでもスマートフォンでも入力することができます。

また、テスト用のデータを入力するにあたって、設定の「回答を1回に制限する」という選択肢はOFFにしておきましょう。
▼ONにしていると、1つのGoogleアカウントで1回しか回答できません。

Googleスプレッドシートとのリンク
Googleフォームの回答の欄から、「スプレッドシートにリンク」を選択します。
▼新しいスプレッドシートを作成します。


▼スプレッドシートが作成されました。回答内容はここにも保存されます。

▼適当に7人分入力しました。

Googleスプレッドシートのデータを取得する
APIキーやIDの設定
いつも参考にしている記事があるので、詳細はそちらをご覧ください。Node-REDの環境は構築している前提ですが、クラウド上で実行できるenebularでも利用できるようです。
▼こちらの記事を参考にしています。
https://qiita.com/tatsuya1970/items/1fd593306334bdfbf509
https://blog.enebular.com/nodes/letsuse-google-spreadsheet-node
ノードに必要なものは主に以下の2つです。
- Google Cloud Platformで発行されるJSON形式の鍵
- スプレッドシートのID
スプレッドシートは編集可能な状態で共有しておきます。
Node-REDで値を取得する
まずはノードを追加します。
▼Node-REDのパレットの管理から追加できます。

▼今回はnode-red-contrib-google-sheetsを使います。

このgoogle-sheetsノードを使って、1行目の入力項目名を取得してみます。
▼以下のようなフローを作成します。

▼ノードにJSON形式の鍵と、スプレッドシートのIDを入力してください。

▼シート名は「フォームの回答 1」になっています。Sheet1ではないのでご注意ください。

適切に設定されていれば、1行目のデータを取得できます。
▼デバッグウィンドウに表示されました。arrayに入っていますね。

changeノードを使って、この配列から要素を取得してみます。
▼changeノードについては、こちらに非常に詳しく書かれています。
https://qiita.com/utaani/items/185343988f8ae86ba1ba

▼0番目の配列の、1番目の要素をmsg.payloadに渡して、デバッグウィンドウで見てみます。

▼「名前」を取得できました。

次はB列の名前の要素を取得してみます。
▼フローはそのままコピーして、B2からB100の要素を取得してみます。

▼これもarrayに入っていますが、先程とは要素の入れ方が違いますね。

changeノードで、3つ目の「太田」という名前を取得してみます。
▼msg.payload[3][0]の要素を代入すると、取得できました。

templateノードで文字列に入れてみる
Googleスプレッドシートから取得した値をもとに、一つの文字列にしてみます。
▼以下のフローのように、templateノードを追加しました。

▼ノードですでに用意されているように、変数を文字列に入れることができます。

mustache記法というものに基づいており、よくあるプログラミング言語で配列から要素を取得する場合とは書き方が違うのでご注意ください。
▼mustache.jsについてはこちら
https://github.com/janl/mustache.js
▼payload[0][0]だと取得できず、payload.0.0だと取得できています。


ダッシュボードでデータを表示する
最後にUIノードで、Node-REDのダッシュボード画面を作成してみます。
▼先程と同じく、パレットの管理からnode-red-dashboardを追加します。

▼いろいろありますが、今回はdropdownノードとtextノードを使います。

まずはdropdownノードでGoogleスプレッドシートに入力された名前を表示します。
▼ヘルプに書かれていますが、msg.optionsにlabelとvalueのペアを渡すことで、ドロップダウンの選択肢として表示されます。

▼フローはこんな感じ。

google-sheetsノードで取得した値を、functionノードで加工し、dropdownノードに渡します。
▼一番始めのinjectノードで、起動時に一度実行するように設定しています。

▼functionノード内にはJavaScriptのコードを書けます。

▼コードはこちら。
let options = []
let dict = {}
for(let i=0; i<msg.payload.length; i++) {
dict = {[msg.payload[i][0]]: i+2}
options[i] = dict
}
msg.options = options
return msg;
▼連想配列のkeyとvalueに変数を入れる方法は、こちらの記事を参考にしました。
https://note.com/aki85/n/ndb0f911a2bca
これでダッシュボードを開くと、画面が表示されます。
▼Dashboardのウィンドウで、右にある外部URLを開くアイコンを入力すると、アクセスできます。


▼ドロップダウンを選択すると、名前を選択できるようになっています。


名前を選択すると、その名前があった行番号をmsg.payloadに渡すようになっています。
さらにその行にあるタイムスタンプを取得してみます。
▼全体のフローはこんな感じ。

▼templateノードでセルを渡します。

▼google-sheetsノードのヘルプに書かれているのですが、msg.cellsにセルを渡します。templateノードからchangeノードで代入します。


セルの値が渡されたgoogle-sheetsノードは、再度セルの値を配列に入れてmsg.payloadに渡します。
その値をchangeノードで配列から出して、最後にtextノードに渡します。
▼textノードはGroupを設定しただけです。


▼名前を選択すると、タイムスタンプが表示されます。

最後に
GoogleフォームとGoogleスプレッドシートの連携、Node-REDとの連携ができました。フローだけ見ても、何が起きているか分かりにくいかもしれませんね。
実際にフローを作成して、デバッグウィンドウで値を見ながら調整すると、慣れてくると思います。他のNode-REDのノードを使うときにも活かせそうです。