【ずぼら向けIoT】調味料を開封してからの日数をLINE通知【IFTTT】

夫です。

調味料を開封日をGoogleスプレッドシートに記録し、開封してからの日数をLINE通知するようにしました。

f:id:daredemosmart:20180826115757p:plain

やろうと思った経緯

我が家では家事の分担上、基本的に私がキッチンを担当しているのですが、冷蔵庫の中身や調味料の使用状況が全く管理できておらず、調味料を余ってるのに買い足したり、いつ開けたかわからない食材が散乱している状況が多々あります。妻にも頻繁に注意されるので、これを解決する必要性が生じました。

ベタな方法だと、開封日を記載したシールを貼るなどが考えられますが、自分の性格上100%続かない自信があります。Google Homeを使えば、用具なしですぐに記録できると考えました。記録先は、買い物時など外出先ですぐにスマートフォンで確認できるよう、Googleスプレッドシートにします。さらに、開封日から長時間経過した調味料をLINE通知することで、放置してしまうことを避けます。

システム構成

本システムは、「調味料の開封日をスプレッドシートに記録するシステム」と「記録された開封日を毎日チェックし、LINE通知するシステム」に大別されます。

 

f:id:daredemosmart:20180917132356p:plain

調味料の開封日をスプレッドシートに記録するシステム

IFTTTで、Google Homeへの「OK Google開封〇〇」の命令をトリガーに設定し、それを受けてGoogle Apps Scriptにリクエストを送るWebhooksをトリガーに設定します。

Google Apps Scriptはリクエストを受けてGoogleスプレッドシートに調味料の開封日を書き込みます。

OK Google、使い切り〇〇」と命令した場合は、その調味料をスプレッドシートから削除します。

また、既に記録されている調味料を指定した場合は、「使い切ったので新品を開封した」とみなして開封日を更新するようにします。

記録された開封日を毎日チェックし、LINE通知するシステム

スプレッドシートに記録するGoogle Apps Script(GAS1)とは別に、記録された開封日を毎日チェックするGoogle Apps Script(GAS2)を実装します。チェックした結果、開封日から一定時間(デフォルト7日間)経過している調味料については、IFTTTでトリガーとして設定しているWebhooksのリクエスト用URLにリクエストを送信し、IFTTTのアクションでLINE通知するようにします。

システム構築手順

事前準備

Google Homeの初期セットアップを済ませておく必要があります。
 ※Google Homeの初期セットアップ手順については別途記事作成予定

・IFTTTのアカウント登録も事前に済ませておく必要があります。
 未登録の方は以下記事を参考に登録しておいて下さい。

【ずぼら向けIoT】Google HomeからメモをLine通知【IFTTT】 - 誰でもスマートホーム ~ずぼら夫婦の賃貸暮らし~

Googleスプレッドシート作成・共有

 以下記事の4-1.と同じ手順で、空のGoogleスプレッドシートを作成し、共有します。

【ずぼら向けIoT】ゴミ出し曜日の朝にGoogle Homeが音声通知 - 誰でもスマートホーム ~ずぼら夫婦の賃貸暮らし~

Googleスプレッドシートに調味料開封日を書き込むGASを実装・公開

上の記事の4-2.と同じ手順で、新規GASを作成して実装します。以下、実装例です。

// ポスト時に呼び出される関数
function doPost(e) {
  var jsonString = e.postData.getDataAsString();
  var data = JSON.parse(jsonString);
  
  var openSeasoning = data["open"];
  if(openSeasoning != null){
    WriteOpeningDay(openSeasoning);
  }
  
  var deleteSeasoning = data["delete"];
  if(deleteSeasoning != null){
    DeleteOpeningDay(deleteSeasoning);
  }
}

// スプレッドシートに開封日を書き込む関数
function WriteOpeningDay(inSeasoningName) {
  
  // スプレッドシートを開く
  var spreadsheet = SpreadsheetApp.openById("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
  var sheet = spreadsheet.getSheetByName('シート1');
  
  // 最終行取得
  var lastRow = sheet.getLastRow();

  // 最終行が「1」の場合、1行目にデータが存在するか確認(存在しない場合でも、最終行は0ではなく1になるため)
  if(lastRow == 1) {
    if(sheet.getRange("A1").isBlank()){
      var today = new Date();
      sheet.getRange(1, 1).setValue(inSeasoningName);
      sheet.getRange(1, 2).setValue(today);
      sheet.getRange(1, 3).setValue(7);
      return;
    }
  }
  
  // 登録済みの調味料か確認 
  var isRegistered = 0;
  for(var i=1; i <= lastRow; i++){
    var seasoningName = sheet.getRange(i, 1).getValue();
    if(inSeasoningName == seasoningName) {
      // ヒットした場合、調味料開封日更新
      var today = new Date();
      sheet.getRange(i, 2).setValue(today);
      isRegistered = 1;
      break;
    }
  }
  
  // 未登録の場合は、新規追加
  if(isRegistered == 0){
      var today = new Date();
      sheet.getRange(lastRow+1, 1).setValue(inSeasoningName);
      sheet.getRange(lastRow+1, 2).setValue(today);
      sheet.getRange(lastRow+1, 3).setValue(7);
  }
}

// 調味料を削除する関数
function DeleteOpeningDay(inSeasoningName) {
  
  // スプレッドシートを開く
  var spreadsheet = SpreadsheetApp.openById("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
  var sheet = spreadsheet.getSheetByName('シート1');
  
  // 最終行取得
  var lastRow = sheet.getLastRow();
  
  // 登録済みの調味料か確認 
  var isRegistered = 0;
  for(var i=1; i <= lastRow; i++){
    var seasoningName = sheet.getRange(i, 1).getValue();
    if(inSeasoningName == seasoningName) {
      // ヒットした場合、調味料削除
      sheet.deleteRow(i);
    }
  }
  
  // 未登録の場合は、何もしない
}

「xxx・・・」の部分は、スプレッドシートのIDを記載して下さい。

 

doPost関数は、GASの公開URLにPOSTリクエストがあった場合に呼び出される関数です。データ部にjson形式「{"add":"(調味料名)"}」で調味料名を指定すればWriteOpeningDay関数が実行され、Googleスプレッドシートにおいて指定した調味料名が追加されます。

これだけだと、使い切った調味料の削除ができないので、削除用にDeleteOpeningDay関数も設けます。データ部にjson形式「{"delete":"(調味料名)"}」で指定すればこちらの関数が呼び出されるようにしています。

実装したGASを公開し、URLをメモしておいて下さい(公開方法についても上記記事4-2.で記載しています)。

動作確認として、公開したGASにPOSTリクエストを送信し、正常にスプレッドシードに記録されるか確認してみましょう。HTTPリクエストの動作確認には、Google拡張昨日である「Advanced REST client」がおすすめです。

【備忘録】Chrome拡張機能「Advanced REST client」を使ってHTTPリクエストの動作確認をする - 誰でもスマートホーム ~ずぼら夫婦の賃貸暮らし~

データ部に{"open","(調味料名)"}などを格納してPOSTリクエストを送信すると、スプレッドシートに追加され、{"delete","(調味料名)"}で送るとスプレッドシートから削除されることを確認して下さい。

f:id:daredemosmart:20180917155928p:plain

3列目の数字は開封日をLINE通知する周期でデフォルト7日に設定しています。調味料によって変更したい場合は、スプレッドシートを直接編集して下さい。

GASにPOSTリクエストを送信するIFTTTアプレット作成

Google Homeへの命令をトリガーに、実装したGASへPOSTリクエストを送信するIFTTTアプレットを作成します。

トリガーはGoogle Assistantで「Say a phrase with a text ingredient」を選択して下さい。「OK Google開封 〇〇」がトリガーになるよう以下のように設定し、「Create Trigger」をクリックして下さい。

f:id:daredemosmart:20180904223439p:plain

 アクションは、Webhooksを選択します。「URL」はGASの公開URL、「Method」は「POST」、「Content Type」は「application/json」、「Body」は「{"open":"{{TextField}}"}」を設定し、「Create Action」をクリックて下さい。

f:id:daredemosmart:20180909151720p:plain

同様の手順で、「OK Google、使い切り 〇〇」をトリガーに、リストから調味料を削除するアクションを設定したアプレットを別途作成します。

f:id:daredemosmart:20180911231804p:plain

f:id:daredemosmart:20180911231953p:plain

POSTリクエストを受けてLINE通知を行うIFTTTアプレット作成

GASからのPOSTリクエストをうけて、開封日から一定期間が経った調味料をLINE通知するIFTTTアプレットを作成します。まず、トリガーにWebhooksを設定し、任意の「Event Name」を設定して下さい。

f:id:daredemosmart:20180904235059p:plain

アクションは、LINE通知を設定します。Value1とValue2は、POSTリクエストのデータ部で格納されたものです。後の手順で実装するGSSにおいて、POST1に調味料名、POST2に経過日数を格納してPOSTリクエストを送信します。

f:id:daredemosmart:20180904235605p:plain

アプレット一覧から作成したアプレットを選択し、Webhooksのアイコンをクリックして下さい。

f:id:daredemosmart:20180916073450p:plain

 以下の画面が表示されるので、Documentationをクリックして下さい。

f:id:daredemosmart:20180904235852p:plain

以下の画面が表示されます。「Make a POST or GET web request to:」が、POSTリクエスト時に送信するURLで、{event}はトリガーで設定した「Event Name」を設定します。「With an optional JSON body of:」は、リクエスト時のデータ部の指定方法です。JSON形式で、3つまでのデータを渡せます。

f:id:daredemosmart:20180911234053p:plain

これらの情報は、以降の手順でPOSTリクエストを送信するGASを実装する際に使用します。

開封日からの経過日数を確認するGASを実装

スプレッドシート開封日を確認し、一定期間(デフォルト7日)経過した調味料があれば、IFTTTでトリガーに設定したWebhooksのURLにリクエストを送信する」GASを実装します。以下の通り実装しました。

// 開封日をチェックして、WebhooksにPOST(毎朝実行される関数)
function CheckOpeningDay() {
  
  var spreadsheet = SpreadsheetApp.openById("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
  var sheet = spreadsheet.getSheetByName('シート1');
  
  // 最終行取得
  var lastRow = sheet.getLastRow();

  // 調味料開封日から経過した調味料があれば、WebhooksにPOST 
  var isRegistered = 0;
  for(var i=1; i <= lastRow; i++){
    var seasoningName = sheet.getRange(i, 1).getValue();
    
    // 差日を求める(86,400,000ミリ秒=1日)
    var openingDay = sheet.getRange(i, 2).getValue();
    var today = new Date();
    var termDay = Math.ceil((today - openingDay) / 86400000);
    
    // 通知周期の場合は、POST
    var notificationPeriod = sheet.getRange(i, 3).getValue();
    if(termDay % notificationPeriod == 0) {
      
      // POSTデータ
      var payload = {
        "value1" : seasoningName,
        "value2" : termDay,
        "value3" : ""
      }
      // POSTオプション
      var options = {
        "method" : "POST",
        "payload" : payload
      }

      // アクセス先
      var url = "https://maker.ifttt.com/trigger/Seasoning/with/key/xxxxxxxxxxxxxxxxxxxx"
      
      // POSTリクエスト
      var response = UrlFetchApp.fetch(url, options);
    }
  }
}

実装したGASの関数が毎日実行されるよう、スケジュール設定を行います。以下赤枠の時計ボタンを謳歌すれば、関数の実行スケジュールを指定できます。以下、毎日7時~8時に実行されるよう設定す場合の例です。

f:id:daredemosmart:20180914005449p:plain

まとめ

スプレッドシート、GAS、IFTTTを連携させることで、調味料の開封日を管理するシステムを作ることができました。