LoginSignup
6
6

More than 3 years have passed since last update.

【GAS】スポーツジムに行くようにLINEにせっついてもらう

Last updated at Posted at 2019-04-16

はじめに

ジムに一定の期間行っていなかったら自動で、「行かないんですか?」とLINEで受け取るというものをつくります。
今回はIFTTTと連携します。

なおLINE連携の設定に関しては割愛します。必要に応じてこちらを参照していただければ。

完成イメージ

①ジムのWi-Fiにつながったら、来たということと現在日時をスプレッドシートに入力する。
②ジムのWi-Fiが外れたら、帰ったということと現在日時をスプレッドシートに入力する。
③指定の時刻になったらスプレッドシートを読みに行き、記録された最終日時が一定期間以上前だったらLINEでメッセージを受け取る。

準備

IFTTTの設定

IFTTTにアクセスし、ログインを(まだの場合は会員登録も)します。

できたら、まずは
『もしスポーツジムのWi-FiにAndroid端末が接続したら、ConnectLogスプレッドシートにEnterと入力する』
というアプレットを作成していきましょう。

①New Applet

q_1.png

②this

q_2.png

③Android Device

q_3.png

④Connects to a specific WiFi network

q_4.png

⑤スポーツジムのWiFiネットワーク名を設定 > ⑥Create trigger

q_5.png

⑦that

q_6.png

⑧Google Sheets

q_7.png

⑨Add row to spreadsheet

q_8.png

⑩Spreadsheet name:ConnectLog
⑪Formatted row:Enter
設定が完了したら > ⑫Create action

q_9.png

⑬分かりやすいアプレット名に変更 > ⑭Finish

q_10.png

▼▼▼

q_11.png

次に
『もしスポーツジムのWi-FiがAndroid端末から外れたら、ConnectLogスプレッドシートにExitと入力する』
というアプレットを作成していきます。

①New Applet

q_12.png

②this

q_13.png

③Android Device

q_14.png

Disconnects from a specific WiFi network

q_15.png

⑤スポーツジムのWiFiネットワーク名を設定 > ⑥Create trigger

q_16.png

⑦that

q_17.png

⑧Google Sheets

q_18.png

⑨Add row to spreadsheet

q_19.png

⑩Spreadsheet name:ConnectLog
⑪Formatted row:Exit
設定が完了したら > ⑫Create action

q_20.png

⑬分かりやすいアプレット名に変更 > ⑭Finish

q_21.png

▼▼▼

q_22.png

Googleドライブのディレクトリ作成

当たり前のことなのですが、先ほどIFTTTで指定したディレクトリ(『Drive folder path』)がないとそもそもシートが作れません。
私が少し突っかかったので念のため書いておきます。

ということで、Googleドライブに IFTTT > Android Device ディレクトリを作っておきましょう。
もちろんIFTTT側の設定を変えても大丈夫です。

q_23.png

確認

設定ができたので動きを確認してみましょう。

設定したWifiにつなげてみて『ConnectLog』スプレッドシートにEnter、はずしてみてExitと入力されればOKです。

q_25.png

以上で準備が完了です。

記録用スプレッドシートの設定

今回はシート側もごにょごにょします。

コード

IFTTTでは現在日時の入力はできないので、スプレッドシートに組み込みます。

コード.gs
function setDate() {
  const sheet = SpreadsheetApp.getActiveSheet();
  var lastRow = sheet.getLastRow();
  // 最終行の2列目に現在日付を設定します。
  sheet.getRange(lastRow, 2).setValue(new Date());
}

以上でコーディングが完了です。

トリガーの設定

先ほどのsetDate()をシート変更時に自動で実行するように設定します。

このまま設定を進めていきましょう。
編集 > 現在のプロジェクトのトリガー > トリガーを追加
①実行する関数:setDate
②イベントのソース:スプレッドシートから
③イベントの種類:変更時
と設定 > ④保存
q_24.png

以上でトリガーの設定が完了です。

Standalone Scriptの設定

Standalone Script(以降、スタンドアロン)とは、Googleドライブ上に作る独立したGASプロジェクトを指します。

コード

main.gs
var week = 2;

function sendMessage() {
  if ( checkLog===true ) {
    var accessToken = PropertiesService.getScriptProperties().getProperty('LINE_TOKEN');
    var message = '最後にジムに行ってから' + week + '週間が経っています。そろそろ行きましょう!(最終日:';
    message += _formatDate(new Date(getLastDate())) + '';
    var options =
     {
       'method'  : 'post'
      ,'payload' : 'message=' + message
      ,'headers' : {'Authorization' : 'Bearer '+ accessToken}
      ,muteHttpExceptions:true
     };
    UrlFetchApp.fetch('https://notify-api.line.me/api/notify',options);
  }
}

function checkLog() {
  var ret = false;
  var checkDate = new Date()
  checkDate = new Date(checkDate.getYear(),checkDate.getMonth(),checkDate.getDate() - week*7);
  checkDate = new Date(Utilities.formatDate(checkDate,'JST','yyyy/M/d') + ' 00:00:00'); // 一応時刻を揃えます
  var lastDate = new Date(getLastDate());
  lastDate = new Date(Utilities.formatDate(lastDate,'JST','yyyy/M/d') + ' 00:00:00');
  // 日付比較
  var dt = checkDate.getTime() - lastDate.getTime();
  var d = dt / (1000 * 60 * 60 * 24);
  // n週間前の日付が最終記録日時よりも大きい(新しい)場合、真とする
  if ( d > 0 ) ret = true;
  return ret;
}

function getLastDate() {
  var ssId = '********************************';
  var ss = SpreadsheetApp.openById(ssId);
  var sheet = ss.getSheetByName('シート1');
  // 打刻がうまくいっていなかったときのために
  // 念ため空を除きます
  var val = sheet.getRange('B:B').getValues().filter(String);
  return val[0,val.length-1];  // 最終行の値を返します
}

function _formatDate(dt) {
  const dow = ['','','','','','',''];
  return Utilities.formatDate(dt,'JST','yyyy/M/d') + '(' + dow[dt.getDay()] + ')';
}

コードはいたって単純です。先ほどの記録用スプレッドシートを読みに行き、日付比較してLINEにメッセージを送ります。
var week = 2; を変えれば3週間でも10週間でもそのまま使えます。
もっとストイックに6日以内にしたい場合もweekを使っているところを変えていきましょう。

さてsendMessage()を実行してみます。

line.jpg

来ましたね!胃が痛い

以上でコーディングが完了です。

トリガーの設定

こちらは時間でトリガーを引きます。

編集 > 現在のプロジェクトのトリガー > トリガーを追加
①実行する関数:sendMessage
②イベントのソース:時間主導型
③イベントの種類:日付ベースのタイマー
④時刻:午後12時~1時
と設定 > ⑤保存

q_26.png

以上でトリガーの設定が完了です。

まとめ

記録用スプレッドシートのコード
コード.gs
function setDate() {
  const sheet = SpreadsheetApp.getActiveSheet();
  var lastRow = sheet.getLastRow();
  sheet.getRange(lastRow, 2).setValue(new Date());
}


スタンドアロンのコード
main.gs
var week = 2;
/**
* メッセージ送信メイン処理
* @param none
* @return none
*/
function sendMessage() {
  if ( checkLog===true ) {
    var accessToken = PropertiesService.getScriptProperties().getProperty('LINE_TOKEN');
    var message = '最後にジムに行ってから' + week + '週間が経っています。そろそろ行きましょう!(最終日:';
    message += _formatDate(new Date(getLastDate())) + '';
    var options =
     {
       'method'  : 'post'
      ,'payload' : 'message=' + message
      ,'headers' : {'Authorization' : 'Bearer '+ accessToken}
      ,muteHttpExceptions:true
     };
    UrlFetchApp.fetch('https://notify-api.line.me/api/notify',options);
  }
}
/**
* 設定日以降のログデータ有無を確認する。
* @param none
* @return {bool} 最終記録日時よりも新しい場合TRUE
*/
function checkLog() {
  var ret = false;
  var checkDate = new Date()
  checkDate = new Date(checkDate.getYear(),checkDate.getMonth(),checkDate.getDate() - week*7);
  checkDate = new Date(Utilities.formatDate(checkDate,'JST','yyyy/M/d') + ' 00:00:00');
  var lastDate = new Date(getLastDate());
  lastDate = new Date(Utilities.formatDate(lastDate,'JST','yyyy/M/d') + ' 00:00:00');
  // 日付比較
  var dt = checkDate.getTime() - lastDate.getTime();
  var d = dt / (1000 * 60 * 60 * 24);
  if ( d > 0 ) ret = true;
  return ret;
}
/**
* 最新記録日時を取得する。
* @param none
* @return {object} 最新記録日時
*/
function getLastDate() {
  var ssId = '***************************************';
  var ss = SpreadsheetApp.openById(ssId);
  var sheet = ss.getSheetByName('シート1');
  var val = sheet.getRange('B:B').getValues().filter(String);
  return val[0,val.length-1];
}
/**
* 日付整形
* @param {date} 日付
* @param {date} 整形後日付
*/
function _formatDate(dt) {
  const dow = ['','','','','','',''];
  return Utilities.formatDate(dt,'JST','yyyy/M/d') + '(' + dow[dt.getDay()] + ')';
}

あくまでも行くも行かないも自由なイベントが対象となるのであまり使う機会はなさそうですが、IFTTTとの連携をしてみたくてつくりました。便利というか、キケンな使い方が出来そうですね。

今回は行ったかどうかを判定するだけなので最後にいた日付だけあれば十分ですし、最大行数も気にしなくていいので上書きでいい気もしますが、どれくらいいたか記録したいような場合はこのままEnterとExitの時間を計算すればできますね。

また、GASをスタンドアロンと記録用スプレッドシートに分けましたが、記録用スプレッドシートにコードを全てまとめてしまっても大丈夫です。

参考サイト

お母さんは心配症 ? GASとIFTTTで出社と退社の状況をLINEに通知する ? - Qiita とても参考になりました:bow:
GoogleHome + IFTTTで睡眠時間を管理してみる - Qiita

ありがとうございました。

6
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
6