見出し画像

【GAS】Google フォームの回答通知をSlackに送ってみる(手こずりポイント2つ)

こんにちは、なみきです。

今回はGASを使って、SlackのチャンネルにGoogleフォームの回答通知を送信する機能を実装したのでシェアします。

ノーコードで今回のゴールを実現するサービスはありそうですが、今回はあえてGASをしっかりと書いていきます。

GASとは?

Google Apps Script(GAS)というGoogleが提供するJavaScript由来のプログラミング言語を用いて今回は実装していきます。

GASを使うことによって、GoogleフォームやGoogleスプレッドシートなどのGoogle提供のサービスを低い学習コストでカスタムすることができます。

私も以前にGoogleフォームの自動返信メールを作成するためにGASで実装した経験はありますが、今回は久しぶりのGASを実装なのでいろんなサイトを真似して実装しました。

ゴール

今回のゴールはGoogleフォームで回答があった場合に、その回答内容をSlackのチャンネルに通知することです。

私は研究室で運営している商店(アイスやお菓子を研究室メンバー向けに販売)の管理係をやっており、研究室メンバーからの商品リクエストの募集はGoogleフォームで行っています。

定期的に回答結果のスプレッドシートを見にいくのはめんどくさいので、Googleフォームに回答があった場合は、商店係のSlackチャンネルに通知が届くようにしました。

手順

①事前にGoogleフォームの作成と回答先のスプレッドシートの準備を行います。

今回は商店の商品リクエストのフォームを以下のように作成しました。

スクリーンショット 2021-04-25 10.55.59

そして、回答結果が送信されるスプレッドシートは以下です。管理用に設問以外にカラムの順番を入れ替えたり、追加のカラム(列)を入れいています。(これが後に手こずった原因となる...)

スクリーンショット 2021-04-25 11.00.57

②SlackのIncoming Webhook URLを取得

以下のサイトを参考にして、通知先のチャンネルを指定するためのURLの取得や通知するアカウント(bot)の設定を行います。

ちなみにbot(Internet bot)はrobotの " bot " であり、インターネット上で自動でタスクを実行するアプリケーションのことをいいます。Twitterのbotなど馴染み深いかもしれませんね。

③フォームの回答結果が集約されるGoogleスプレッドシートのスクリプトエディタに実装

以下のYousufulのGAS講師こうだいさんの動画を参考に実装しました。

記事によってはGoogleフォームからスクリプトエディタを開けるという記事もありましたが、2021年4月現在はスプレッドシートからしかスクリプトエディタを開けませんでした。

googleのスクリプトエディタは頻繁にUIも含め更新されている印象があるので、もしかしたら古い記事は参考にならない場合もありそうです。

スクリーンショット 2021-04-25 11.03.58


③トリガーの設定を行う。

最後にこうだいさんの動画の通りにトリガーを設定します。

そして、実行された結果が以下になります。研究室の商店係用のSlackチャンネルにbot通知が届きます。(例 ニックネーム : namiki、商品:あんぱん、コメント:テスト)

スクリーンショット 2021-04-25 11.19.23

コード

仕様は以下の通りです。

図31

図12

// 回答結果の読み込み関数
function autoSlack(e) {
 var values = e.values ;
 // 通知項目(シート左から0〜)
 // 注意設問に含まれないカラムはカウントされない
 var nickname = values[3] ;
 var product = values[1] ;
 var number = values[2] ;
 var productlink = values[5] 
 var comment = values[4] ;
 var spreadLink = "<https://docs.google.com/spreadsheets/~~~sample~~~~|リクエスト結果スプレッドシートリンク>"; //埋め込みリンク

 //任意回答部分表示の条件分布
 var body2 = "";
 var body3 = "";
 var body4 = "";
 if(values[2]){
   body2 = "数量:" + number + "\n" ;
 }
 if(values[5]){
   var body3 = "商品リンク:" + productlink + "\n";
 }
 if(values[4]){
   var body4 = "コメント:" + comment + "\n";
 }
 
 //Slack通知内容
 notifySlack(nickname + "が" + product + "を欲しいらしいです...\n\n"
 + body2 + body3 + body4 + "\n"+spreadLink);
}


// Slackの関数
function notifySlack(message){
 //  slack設定
 var postUrl = "https://hooks.slack.com/services/~~~sample~~~~";//ここはIncoming Webhook URL
   var payloadObj = {
     text : message
   }

 var payloadJson = JSON.stringify(payloadObj);

 var option ={
   method:"post",
   contentType:"application/json",
   payload : payloadJson
 }

 UrlFetchApp.fetch(postUrl,option) ;
}

案外シンプルなコードでできちゃいますね。

postUrlの部分には通知先のSlackチャンネルのIncoming Webhook URLをしていしてください。

てこずった所

さあ、今回の実装では自分の知識不足が原因で、実装にてこずった部分を2点シェアします。

(これぐらいのことで手こずっていて本当に情報系の学生なのかというツッコミはさて置き....)

1つ目は、
スプレッドシートの値を格納する際に使用するvalues[ ]のカラム指定(配列式)です。

こうだいさんの動画では、スプレッドシートの一番左のカラム(列)から順に0, 1, 2,...と順にナンバーが割り当てられると述べられています。

スクリーンショット 2021-04-25 11.59.29

しかし、実はこれは前提条件があるのです。

それは、Googleフォームにより作成された回答結果のスプレッドシートのカラムの順番等をいじっていないということです。

私の場合は、フォームの設問の順番が
ニックネーム欲しい物希望数量商品リンクコメント
であるのに対し、

スプレッドシートのカラムの順番は
「タイムスタンプ、採用・不採用、購入日、欲しい物希望数量ニックネームコメント商品リンク
となっております。

つまり、カラムがフォームの設問の順番と違うし、設問がないカラム(採用・不採用、購入日)も入っています。

そして、この状態で単純にスプレッドシートからvalues[ ]のカラム指定を行うと失敗します。

例えば、values[3](左から0, 1, 2 ,3のカラム)は欲しい物なのですが、ニックネームの値(左から0, 1, 2 ,3, 4, 5のカラム)が格納されてしまいます。

図111

では、どうやったら正しく目的のカラムの値をvalues[ ]に格納できるのか?

そのためには、以下のルールを知っている必要があります

フォームにない設問のカラム(自分でスプレッドシートに追加したカラム)はカウントしない

つまり、今回は「採用・不採用、購入日」のカラムはvalues[ ]のカウントに入れてはいけないのです。

図20

そして、先程の欲しい物の例の場合では、values[1]を指定する必要があったのです。

ということで、該当する部分のコードはこのようになります。

 var nickname = values[3] ;
 var product = values[1] ;
 var number = values[2] ;
 var productlink = values[5] 
 var comment = values[4] ;

そして、2つ目は、
Slack通知での埋め込みリンクの有効化です。

スクリーンショット 2021-04-25 11.19.23

作成した通知の一番下の「リクエスト結果スプレッドシート」はスプレッドシートのリンクになっているのですが、これに少してこずってしまいました。

先に正解を出してしまうと、

<https://~~~sample~~~~|表示名>

で実装すればうまくできます。

最初はHTMLのハイパーリンクの記法やmarkdownのハイパーリンクの記法( [表示名](URL))でうまくいくかなと思っていましたが、だめでした。

最終的には、以下のように実装しています。(関連部分のみ抽出)

 var spreadLink = "<https://docs.google.com/spreadsheets/~~~sample~~~~|リクエスト結果スプレッドシートリンク>"; //埋め込みリンク
 ~~~~~省略~~~~~~
  //Slack通知内容
 notifySlack(nickname + "が" + product + "を欲しいらしいです...\n\n"
 + body2 + body3 + body4 + "\n"+spreadLink);
}

たまたまミスっただけかもしれませんが、notifySlack()の中に直接<https://~~~sample~~~~|表示名>を記述してもうまくいかなかったので、関数を宣言して、代入しました。

まとめ

今回はGASを使ってGoogleフォームからSlackへの通知botを実装しました。

本来はGASを使わずにノーコードのサービスを利用することがプログラマーのあるべき姿だとは思いますが、今回は学習の意味も込めてあえてGASを使ってみました。

学習コストは低く便利な機能を実装することがGASのいいところですね。

ただ、GASやスクリプトエディタのUIは更新頻度が早いので、久しぶりにGASを触ると戸惑うところが多かったです。

所属している研究室は情報系なので、研究室Slackには学生たちが趣味で作ったbotがたくさん動いています。
たとえば、ミーティングがスタートしたらzoomリンクを通知してくれるbotなど。

今後も生活を少しでも楽ちんにできるようなサービスにチャレンジしてみたいと思います。

最近はできていませんが、Alexaアプリの実装を企んでたりします。

それではまた!

「徹底的な目的意識」



この記事が気に入ったらサポートをしてみませんか?