Binary Diary

誰かに会ったり 話しかけたり 街行く人に優しくね

GASを駆使して冷蔵庫の中身を可視化するぞ!!

どうもこたにんです。

買い物をしているときにふと思ったことはありませんか?
「あれ、たまご何個あったっけ。。。」
「あれ、玉ねぎあったっけ。。。」

そんなお悩みに、今日をもって別れを告げましょう。
冷蔵庫の中身を記憶しなくても済むように、ソリューションを作ったぞ!!

完成形はこんなかんじ!

今回は、Slackコマンドで冷蔵庫の中身を可視化しました!

f:id:Kotanin0:20190914140321p:plain
冷蔵庫くん、かわいいなあ!!

やりたいこと

  • 買い物中に冷蔵庫の中身を知りたい

ただひとつです。

買い物をしているときに冷蔵庫の中身を知りたい。
なぜならば、買い忘れ・買いすぎになってしまうと食費がもったいないから。

なので「冷蔵庫の中身が可視化できていること」がゴールになります。

どういう技術を使って実現しよう

可視化する上で、煩雑な手入力とかはしたくないですね。
余剰なオペレーションが増えてしまうと、結果的にコストが増えてしまいます。
大きくコストがかからないようにしたいですね。
これを実現するために、どの手法がいいか考えてみます。

f:id:Kotanin0:20190914142523p:plain

冷蔵庫の中身を知りたいとき

スマートフォンからSlackコマンドを叩いて、GAS経由でスプレッドシートの値を取得。
余計なUIを考えることなく、GAS1つ作るだけでいけそうです。

冷蔵庫の中身を増やしたい/減らしたいとき

Google Homeに声かけて、IFTTT経由でスプレッドシートに保存。
これでハンズフリーでさくっとデータ化することができそうです。

というわけで、作り方は思いついた!
ので作る!!

Google HomeからIFTTT経由でスプレッドシートに保存

IFTTTでレシピ作り

これはとても簡単です。
IFTTT でさっくりとレシピを作りましょう。

Google Assistant がトリガーね。

f:id:Kotanin0:20190914143524p:plain
検索窓にそれっぽいキーワード入れて探しましょう。

今回は、品物と数をデータにしたいので選ぶトリガーはこれ。
Say a phrase with both a number and a text ingredient

f:id:Kotanin0:20190914103717p:plain
トリガーのフレーズ+好きなフレーズ+数、が取れるトリガーです。

トリガーとなる言葉を並べます。

f:id:Kotanin0:20190914143721p:plain 

$ がテキストフレーズ、 # が数値になります。
「冷蔵庫にたまご2個」って言いたいので、このように入れておきます。

トリガーの発火先は、スプレッドシートです。

f:id:Kotanin0:20190914144030p:plain

sheet的な単語で探しましょう。

今回は行を追加していくスタイルを取りたいのでこれ。
Add row to spreadsheet

f:id:Kotanin0:20190914144121p:plain


好きなスプレッドシート名にしましょう、あらかじめ作ってても良いかもね。

f:id:Kotanin0:20190914144245p:plain

Formatted row がこのトリガーで挿入される行の値になります。
ここでは、日時|テキスト|数値|数値 としています。
(数値を2つとしているのは後で説明する)

これで、完成。
「ねえぐーぐる、冷蔵庫にたまご2個」でスプレッドシートにデータが入ります。

逆に「冷蔵庫からたまご3個」を取り出したくなるとき。
その場合、上記レシピのうち、以下の部分を変えた版を作りましょう。

トリガーとする言葉を「冷蔵庫から」にする。
f:id:Kotanin0:20190914144509p:plain

スプレッドシートに保存する値をこのようにする。

f:id:Kotanin0:20190914144717p:plain
日付|テキスト|数値|数値に-1をかけたもの、とします。
スプレッドシート内で使える関数をフォーマットに組み込むことができます。
これは、後でやるスプレッドシート内の計算のために負数にしておきます。

スプレッドシートでピボットテーブル作っておく

できあがったスプレッドシートを見てみましょう。
何度かGoogle Homeに話しかけてあげて、データが入っていることを確認します。
(1行目にヘッダ入れておきましょう、あとで楽ちんです)

f:id:Kotanin0:20190914145149p:plain

うん!いい感じだね!!
MULTIPLYで減った分も値として追加されているね!

ただこれだと、後で可視化する際にいちいち処理書くのがめんどうになりそう。
なので、シートを分けてピボットテーブル作っておきましょう。

別シートを用意して、データ→ピボットテーブル。

f:id:Kotanin0:20190914145325p:plain

すると、画面右部にピボットテーブルエディタが出てきます。

f:id:Kotanin0:20190914145520p:plain

データ元に、元のシートの範囲を指定しておきます。
たくさんデータ入れるつもりなので、B:Dと広く取っておきます。
行に「もの」、値に「ぞうげん」を選択します。

するとほら簡単に集計!ピボットテーブル素敵!

f:id:Kotanin0:20190914145635p:plain

ここまでが、冷蔵庫の中身を音声入力でデータにするところまででした。

テストプレイ!!

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発行します。

f:id:Kotanin0:20190914164156p:plain
ここ。

f:id:Kotanin0:20190914164214p:plain

これで、GASでSlackにPOSTするスクリプトの準備が整いました。
 

Slack Appを作っておく

Slack API: Applications | Slack 
ここにアクセスして、先程作ったGASのURLをSlack Appに登録します。

アプリ名任意、ワークスペースを指定したあと、アプリ設定です。
今回はSlackコマンドとしたいので、Basic Information から Slash Commands を選択。

f:id:Kotanin0:20190914164530p:plain

コマンドの設定画面になるので、トリガーにしたいコマンド名を入れます。
Request URL に、先のGAS上のURLを入れて登録します。

f:id:Kotanin0:20190914164429p:plain

これで完了!
Slackコマンドに登録されました。
(アイコンなどは後でも登録できます)

f:id:Kotanin0:20190914164750p:plain

実際にコマンドを叩いてみると、冒頭に書いたように返事がきます!

f:id:Kotanin0:20190914140321p:plain
冷蔵庫くん、かわいいなあ!!

できたぞ!!!

さっくりできた!
「冷蔵庫の中身が可視化できていること」というゴールは達成です!!
これで買い物していても困ることは、たぶんないぞ!!

このしくみ、改善の余地あるし拡張の展望もたくさんありそうだ。
ただ、今の時点ではこれで課題は解決できそうなので満足!

久々にGAS書いて楽しかった!!!