どうもこたにんです。
買い物をしているときにふと思ったことはありませんか?
「あれ、たまご何個あったっけ。。。」
「あれ、玉ねぎあったっけ。。。」
そんなお悩みに、今日をもって別れを告げましょう。
冷蔵庫の中身を記憶しなくても済むように、ソリューションを作ったぞ!!
完成形はこんなかんじ!
今回は、Slackコマンドで冷蔵庫の中身を可視化しました!
冷蔵庫くん、かわいいなあ!!
やりたいこと
- 買い物中に冷蔵庫の中身を知りたい
ただひとつです。
買い物をしているときに冷蔵庫の中身を知りたい。
なぜならば、買い忘れ・買いすぎになってしまうと食費がもったいないから。
なので「冷蔵庫の中身が可視化できていること」がゴールになります。
どういう技術を使って実現しよう
可視化する上で、煩雑な手入力とかはしたくないですね。
余剰なオペレーションが増えてしまうと、結果的にコストが増えてしまいます。
大きくコストがかからないようにしたいですね。
これを実現するために、どの手法がいいか考えてみます。
冷蔵庫の中身を知りたいとき
スマートフォンからSlackコマンドを叩いて、GAS経由でスプレッドシートの値を取得。
余計なUIを考えることなく、GAS1つ作るだけでいけそうです。
冷蔵庫の中身を増やしたい/減らしたいとき
Google Homeに声かけて、IFTTT経由でスプレッドシートに保存。
これでハンズフリーでさくっとデータ化することができそうです。
というわけで、作り方は思いついた!
ので作る!!
Google HomeからIFTTT経由でスプレッドシートに保存
IFTTTでレシピ作り
これはとても簡単です。
IFTTT でさっくりとレシピを作りましょう。
Google Assistant がトリガーね。
検索窓にそれっぽいキーワード入れて探しましょう。
今回は、品物と数をデータにしたいので選ぶトリガーはこれ。
Say a phrase with both a number and a text ingredient
トリガーのフレーズ+好きなフレーズ+数、が取れるトリガーです。
トリガーとなる言葉を並べます。
$ がテキストフレーズ、 # が数値になります。
「冷蔵庫にたまご2個」って言いたいので、このように入れておきます。
トリガーの発火先は、スプレッドシートです。
sheet的な単語で探しましょう。
今回は行を追加していくスタイルを取りたいのでこれ。
Add row to spreadsheet
好きなスプレッドシート名にしましょう、あらかじめ作ってても良いかもね。
Formatted row がこのトリガーで挿入される行の値になります。
ここでは、日時|テキスト|数値|数値 としています。
(数値を2つとしているのは後で説明する)
これで、完成。
「ねえぐーぐる、冷蔵庫にたまご2個」でスプレッドシートにデータが入ります。
逆に「冷蔵庫からたまご3個」を取り出したくなるとき。
その場合、上記レシピのうち、以下の部分を変えた版を作りましょう。
トリガーとする言葉を「冷蔵庫から」にする。
スプレッドシートに保存する値をこのようにする。
日付|テキスト|数値|数値に-1をかけたもの、とします。
スプレッドシート内で使える関数をフォーマットに組み込むことができます。
これは、後でやるスプレッドシート内の計算のために負数にしておきます。
スプレッドシートでピボットテーブル作っておく
できあがったスプレッドシートを見てみましょう。
何度かGoogle Homeに話しかけてあげて、データが入っていることを確認します。
(1行目にヘッダ入れておきましょう、あとで楽ちんです)
うん!いい感じだね!!
MULTIPLYで減った分も値として追加されているね!
ただこれだと、後で可視化する際にいちいち処理書くのがめんどうになりそう。
なので、シートを分けてピボットテーブル作っておきましょう。
別シートを用意して、データ→ピボットテーブル。
すると、画面右部にピボットテーブルエディタが出てきます。
データ元に、元のシートの範囲を指定しておきます。
たくさんデータ入れるつもりなので、B:Dと広く取っておきます。
行に「もの」、値に「ぞうげん」を選択します。
するとほら簡単に集計!ピボットテーブル素敵!
ここまでが、冷蔵庫の中身を音声入力でデータにするところまででした。
テストプレイ!!
Google Homeがちゃんと言うこと聞いてくれた!!冷蔵庫可視化ひとまず完了かしら。一旦ここまでで記事書く〜 pic.twitter.com/gx7MXuMbUY
— こたにん@エンジニア採用など (@Kotanin0) September 14, 2019
Homeちゃん、かわいい。
「いれたよ!」「とりだしたよ!」って、かわいい。
SlackからGAS経由でスプレッドシートの値を取得
後半戦です。
いよいよ本丸、GASの出番です。
GASでSlackにメッセージをPOSTするスクリプトを書く
Apps Script – Google Apps Script
ここから、新規スクリプトを作りましょう。
まずはコードをベタ貼りします!
このGASのメイン関数をdoPostとしておきます。
function doPost(e) {
var message = getStock();
var response = {
text: message,
response_type: 'in_channel'
};
return ContentService.createTextOutput(JSON.stringify(response))
.setMimeType(ContentService.MimeType.JSON);
}
function getStock() {
var spreadsheet = SpreadsheetApp.openById('[スプレッドシートのID]');
var sheet = spreadsheet.getSheetByName('[ピボットテーブル作ったシート名]');
var range = sheet.getRange('A:B');
var values = range.getValues();
var length = values.length;
var message = "";
for (var i = 2; i < length; i++) {
if (!values[i][0]) {
continue;
}
message = message + values[i][0] + ":" + values[i][1] + "\n";
}
return message;
}
doPostの中の処理は、シンプルなので読んで理解してください。
レスポンスフィールドを作って、それをreturnしてるだけ。
スプレッドシートから値をとってくる処理がこちら。
あらかじめ変数に準備しておく必要があるものがいくつか。
var spreadsheet = SpreadsheetApp.openById('[スプレッドシートのID]');
var sheet = spreadsheet.getSheetByName('[ピボットテーブル作ったシート名]');
var range = sheet.getRange('A:B');
var values = range.getValues();
スプレッドシートのIDは、スプレッドシートのURLから参照できます。
https://docs.google.com/spreadsheets/d/[ここがID]/edit
ピボットテーブル作ったシート名は自分で入力。
またピボットテーブルの参照するセルの範囲を広く指定しておきます。
そんで、範囲から取得した値は多次元配列になるので、そこからメッセージ文字列を作る。
for (var i = 2; i < length; i++) {
if (!values[i][0]) {
continue;
}
message = message + values[i][0] + ":" + values[i][1] + "\n";
}
といった具合でスクリプトを書いちゃいます。
それを、ウェブアプリケーションとして導入、というメニューからURL発行します。
ここ。
これで、GASでSlackにPOSTするスクリプトの準備が整いました。
Slack Appを作っておく
Slack API: Applications | Slack
ここにアクセスして、先程作ったGASのURLをSlack Appに登録します。
アプリ名任意、ワークスペースを指定したあと、アプリ設定です。
今回はSlackコマンドとしたいので、Basic Information から Slash Commands を選択。
コマンドの設定画面になるので、トリガーにしたいコマンド名を入れます。
Request URL に、先のGAS上のURLを入れて登録します。
これで完了!
Slackコマンドに登録されました。
(アイコンなどは後でも登録できます)
実際にコマンドを叩いてみると、冒頭に書いたように返事がきます!
冷蔵庫くん、かわいいなあ!!
できたぞ!!!
さっくりできた!
「冷蔵庫の中身が可視化できていること」というゴールは達成です!!
これで買い物していても困ることは、たぶんないぞ!!
このしくみ、改善の余地あるし拡張の展望もたくさんありそうだ。
ただ、今の時点ではこれで課題は解決できそうなので満足!
久々にGAS書いて楽しかった!!!