前置き長くなってます...飛ばす方は「できること」まで
きっかけ
2022年10月,K研究室のロボ班に所属していた僕はTA業務に追われてました.
そう,「知能ロボット制御論」です.
簡単に説明しますと,前半5週でLegoでのライントレース,後半5週でKHRでのモーション作成をする,演習形式の講義です.どちらも最終回にはタイムや芸術性,得点を競う競技会をします.
ちょうど昨日,Legoの方の競技会が終わったところでした.今年は例年よりレベルが高くて面白かったなあ.
そんなことはさておき,「知能ロボット制御論」とは切っても切り離せない仕組みがあります.それは...「時間外貸し出し」です.
時間外貸し出しは,どう考えても5回(競技会除けば4回)という短い期間ではできない課題のために,我々TAがボランティアで演習室を貸し出す仕組みです.
話は戻るのですが,2022年度は僕が初めてこの講義のTAになった年で,なぜか受講者数が前年度のほぼ4倍になっていました.
演習室は人であふれかえり,Lego本体も足りないし,あちこちで起きる不具合への対処...も~大変でした
第一回の講義を終えた僕はさらなる絶望を感じました.そう,時間外貸し出しです
というのも,前年度までは時間外貸し出しの予約を受講生からのメールで受け,それを整理して紙にシフトを書いてやりくりしていたというのを聞いていたので,この人数でそれやるの...と思ったのです
そこでI先輩に助言を求めたところ「Googleフォームならスプレッドシートと連携出来ていいよ」と教えてくださり,奮起した僕はもっともっとと最適化の旅に出かけたのでした.
出来ること
- Googleフォームの回答がスプレッドシートに保存される
- スプレッドシートの回答を並び替える(おまけ)
- Slackの特定のチャンネルに回答内容が通知される
やること
簡単で
す!
まず初めにGoogleフォームを作ります.誰でもできますね.
そうしたら「回答」タブの「スプレッドシートにリンク」をクリックすれば,作成したシートに自動で回答をセルに書き込んでくれるようになります.一つ目終わり.
ここからSlackへの通知のための準備をしていきます.
流れとしては
- SlackチャンネルのURLを取得
- フォームのスクリプトエディタでSlackに通知する関数をコーディング
- 関数を実行させるタイミングをトリガーで設定
こんなかんじです.
1. SlackチャンネルのURLを取得
実際に必要なのは「Incoming Webhook URL」です.どういうものかというと,通常のURLが「ショッピングモールの入り口」だとしたら,「荷物受け取り専用の受付口」になるそうです(ChatGPTくん調べ).わかりにくいですね.
まずSlackapiのページ↗にアクセスします.
次にCreate New App → From scratchの順にクリックします.するとこんなポップアップが.
App Nameに適当な名前をいれ(表示名は後からでも変えられます),2つ目でURLを取得したいワークスペースを選びます.
そしてできたアプリを開くとこんな画面に
ここでFeaturesタブの「Incoming Webhooks」で右上のスイッチでアクティベートさせます.
FeaturesのApp HomeからApp Display NameをEditで変更できます.
(SettingのBasic Informationでアプリアイコンとかも変更できますよ!)
ようやく本題です.
Features → Incoming Webhooksで一番下にスクロールすると,「Add New Webhook to Workspace」とあるのでクリックします.すると以下の画面に.
ここでチャンネルを選択して許可すれば,先ほど「Add New Webhook to Workspace」を押した上でURLがコピーできると思います.お疲れさまです.
ちなみに,今回紹介したのはSlackappを作成する方法ですが,もとからSlackの用意したアプリ(Slack marketplaceのIncoming Webhook)を使う方法もあります.ですが,公式から非推奨と言われてるみたいです.
2. フォームのスクリプトエディタでSlackに通知する関数をコーディング
満を持してフォームに帰りましょう.設定の「スクリプトエディタ」を開きます.
いわゆるGAS(Google Apps Script)が立ち上がります.GASでは,コードに関数を書き,トリガーを設定することで好きなタイミングで関数を実行することができます.
とりあえず以下のコードをコピペしましょう.コードはほぼ他の方のコピーです.ありがとうございます.
function autoSlack(e) {
/* ステップ1: フォームのデータを取得する */
//すべての質問と回答を取得する
let itemResponses = e.response.getItemResponses();
/* ステップ2: 必要なデータを抽出する */
//個々の質問と回答を格納するための空配列を宣言する
let questionAndAnswers = [];
//for文(ループ)で変数itemResponsesから個々の質問と回答を取得する
for(let i = 0; i < itemResponses.length; i++) {
//質問のタイトルを取得する
let questionTitle = itemResponses[i].getItem().getTitle();
//回答を取得する
let answer = itemResponses[i].getResponse();
//未回答の質問かどうかで送信文章を調整する
if(!answer) {
questionAndAnswers.push(questionTitle + ": 未回答");
} else {
questionAndAnswers.push(questionTitle + ":" + answer);
}
}
/* ステップ3: 宛先、本文を決める */
//Slackの宛先 (チャンネル)
//★★★SlackのIncoming Webhook URLを入力してください★★★
let url = "入力してね!自分で!";
//Slackの本文
//★★★お好きな本文に変更ください★★★
let body = "\nロボ演フォームの回答を受信しました。\n"
+ "\n"
//一次元配列questionAndAnswersに対してjoinメソッドを使って文字列を作成する
//区切り文字は改行"\n"
+ questionAndAnswers.join("\n");
/* ステップ4: 指定したSlackチャンネルに通知を送信する */
//Slackを送信する
sendSlack(url, body);
}
function sendSlack(url, body) {
let data = {
"text": body
}
let options = {
"method" : "post",
"contentType": "application/json",
"payload" : JSON.stringify(data)
};
UrlFetchApp.fetch(url, options);
}
3. 関数を実行させるタイミングをトリガーで設定
ついに大詰めです.
左のトリガータブから「+トリガーを作成」をクリック.
「イベントの種類を選択」だけ起動時→フォーム送信時に変更して以下のようになればOK.関数autoSlackをフォーム送信時に実行してくれます.
保存した後,Googleアカウントでの承認を求められるのですが,初回の承認の時だけエラーのような表示がされてしまいます.このとき,「安全なページに戻る」ではなく左下の「詳細」から進めてください.(画像なくてすみません)
無事追加できれば終了です!お疲れさまでした.
↓こんな感じで通知されます.
おまけ:スプレッドシートの並び替え
スプレッドシートも当然GASが使えるので,同様にコピペ コーディングしましょう!
function sortByHope() {
var sheet = SpreadsheetApp.getActiveSpreadsheet();
var activeSheet = sheet.getActiveSheet();
var lastRow = sheet.getLastRow();
var range = "A2" + ":J" + lastRow;
var range = activeSheet.getRange(range);
range.sort([{column: 4, ascending: true}]);
range.sort([{column: 3, ascending: true}]);
}
このコードではA2からJの範囲を4列目基準でソートした後に3列目でソートします.(確か)
追記:
後輩のS君がアップデートしてくれました!感激
参考にしたサイト