オンラインでアンケートや回答フォームを作りたい・・・
そのような場面でGoogleフォームはよく使用されます。簡単に回答用のフォームを作成することができ、とても便利です。
さらに、Googleフォームには回答内容をスプレッドシートに自動転記する機能もあり、数字を集計する際にも役立ちます。
しかしながら、回答内容を見るためには都度フォームの回答欄やスプレッドシートを開かなければなりません。毎回開くのは少々大変です。
そのような時、回答内容をSlackに表示させることで毎回フォームの回答欄やスプレッドシートを開く手間を省くことができます。
本記事ではその方法を紹介します。
作成した背景
私と妻の間では毎日スマートフォンのアプリで100マス計算を実施しています。
100マス計算に要した時間を紙で記録するのは効率が悪いため、スマホからGoogleフォームで回答することとしました。
しかし、フォームで回答してもこれまでの実績や変化を確認するためには都度フォームの回答欄を開く必要があります。
手間が掛かるため、家庭内Slackに通知させることに決めました。
難易度
★★★☆☆
要件(仕様)
今回の要件は次の通りです。
- フォームに回答されたらSlackの指定したチャンネルに通知される
- その際、フォームに回答された内容が反映される
フォームはこちら!
SlackでのUI
Slackに通知された内容は次のように表示させます。
準備
今回もSlackのIncoming Webhookを使用します。
準備方法はこちらをご覧ください!
ソースコード
まずは全体のソースコードを紹介します。
function sendToSlack(body, channel) { var url = "WebhookのURL"; var data = { "channel" : channel, "username" : "今日の100マス計算の結果", "text" : body}; var payload = JSON.stringify(data); var options = { "method" : "POST", "contentType" : "application/json", "payload" : payload }; var response = UrlFetchApp.fetch(url, options); } function test() { sendToSlack("テスト通知確認です", "#チャンネル名"); } function formSubmit(e){ var body = "100マス計算の結果が報告されました\n"; var itemResponse = e.response.getItemResponses(); for (var i = 0; i < itemResponse.length; i++){ var formData = itemResponse[i]; var title = formData.getItem().getTitle(); var answer = formData.getResponse(); switch (title) { case "名前": name = answer; break; case "実施した項目": menu = answer; break; case "時間(秒)": time = answer; break; default: break; } } var bodyPublic = body + "\n *名前* \n" + name + "\n\n *実施した項目* \n" + menu + "\n\n *時間(秒)* \n" + time sendToSlack(bodyPublic, "#チャンネル名"); }
読み込みの順番
①:formSubmit関数
②:sendToSlack関数
なお、testNotification関数はtestしたい時に使用します。
それぞれの関数について解説します。
formSubmit関数でフォームに回答された内容をキャッチする
この関数の主な役割はフォームに回答された内容をキャッチし、Slackに送信する準備を行うことです。本プログラムの中で最も重要な処理を担います。
関数を定義する
まずは関数を定義します。今回はフォームが投稿された際にイベントを発火させるため、「formSubmit」と命名しました。
引数(e)はイベントを意味しています。
function formSubmit(e){ var body = "100マス計算の結果が報告されました\n"; var itemResponse = e.response.getItemResponses(); }
そして、Slackの本文に表示させるメッセージを変数bodyに代入しておきます。
その次に、フォームで回答された内容を変数itemResponseに代入します。
フォームに投稿された内容を取り出す方法
GASの公式リファレンスで紹介されています。今回参考にしたのはこちらです。
こちらを読むと、メソッド「getItemResponses( )」を使用するとフォームに投稿された内容全てを取り出すことができることが分かります。
今回はイベント(e)を利用しているため、イベントの中にあるresponseの中身を取り出します。
従って、「e.response.getItemResponses();」と記述しています。取り出した内容は変数itemResponseに代入します。
なお、この取り出した回答内容は次のような構造をしています。
[{"名前": "回答内容"},{"実施した項目": "回答内容"},{"時間(秒)": "回答内容"}]
配列の中にハッシュが質問の個数分格納されています。
ハッシュの中身は質問項目がキーに、回答内容がバリューとなっています。”回答内容”の部分にはユーザが記入した内容が入ります。
ハッシュを展開するためのループ処理を記述する
ハッシュの形のままではSlackに表示させることができません。そのため、ハッシュを展開するためにループ処理を行います。
for (var i = 0; i < itemResponse.length; i++){ var formData = itemResponse[i]; var title = formData.getItem().getTitle(); var answer = formData.getResponse(); switch (title) { case "名前": name = answer; break; case "実施した項目": menu = answer; break; case "時間(秒)": time = answer; break; default: break; } }
それぞれを解説していきます。
基本の形を用意する
for (var i = 0; i < itemResponse.length; i++){ }
ループ処理の記述です。
変数itemResponseの要素数分、ループさせます。インデックスは0から開始し、ループ処理を終えたら1ずつ加えます。
GAS、JavaScriptの基本的なfor文の書き方と同じですね!
ループ処理の中での処理を記述する
var formData = itemResponse[i]; var title = formData.getItem().getTitle(); var answer = formData.getResponse();
こちらではループ処理の中での処理を記述しています。ハッシュの中にあるフォームで投稿された情報を分解していきます。
var formData = itemResponse[i];
こちらで配列内のインデックスを取得します。ループ処理中に現在処理を実行しているインデックスを用いるため、itemResponse[i]と記述しています。
var title = formData.getItem().getTitle();
フォームのタイトルを取り出しています。getItem( )メソッドで回答全体を、getTitle( )メソッドでその中にあるタイトルを取り出すことができます。
タイトルは前述の通り、ハッシュのキーとなっています。
var answer = formData.getResponse();
同様にフォームに記述された回答内容を取り出します。
ここまでできたら、switch文で条件分岐させます。
質問項目別に回答を変数に代入する
ここからは質問項目別に回答を変数に代入し、Slackに送信できるようにします。Switch文を使用して条件分岐をすると分かりやすいです。
switch (title) { case "名前": name = answer; break; case "実施した項目": menu = answer; break; case "時間(秒)": time = answer; break; default: break; }
前の行で取得したタイトル(質問項目)を式で使用しています。残りはそれぞれの式に応じた処理を記述します。こちらもGASやJavaScriptにおけるswitch文の基本的な書き方と同じですね!
Slackで表示させる形に整える
ここまで来たらSlackで表示させたい形に整えます。
var bodyPublic = body + "\n *名前* \n" + name + "\n\n *実施した項目* \n" + menu + "\n\n *時間(秒)* \n" + time sendToSlack(bodyPublic, "#チャンネル名");
作成したら適当な変数に代入し、slackに通知させる関数へ飛ばします。
sendToSlack関数でSlackへ通知させる
ここまで来たらSlackに通知させるのみです。
function sendToSlack(body, channel) { var url = "WebhookのURL"; var data = { "channel" : channel, "username" : "今日の100マス計算の結果", "text" : body}; var payload = JSON.stringify(data); var options = { "method" : "POST", "contentType" : "application/json", "payload" : payload }; var response = UrlFetchApp.fetch(url, options); }
この関数はIncoming Webhockを使用してSlackに通知させる際に使い回し可能です。
本関数についてのコードの説明はこちらの記事にありますので参照ください!
1度書いたコードは使い回し可能ですので、とっておくと良いでしょう。
GoogleフォームとSlackの連携は意外と簡単
今回はGoogleフォームに投稿された内容をSlackに表示させる方法を紹介しました。
複雑に見えますが、使用している技術はそこまで難しいものではありません。GASは初めてでもJavaScriptの基本が分かれば簡単に作成することができます。
この方法はアンケート回収時などに応用可能です。是非、日常業務の効率化等にお役立てください!
最後までご覧いただきありがとうございました!