肩の力を抜いて

肩の力を抜いて

プログラミングのネタが中心。ラクして成果を上げる仕組みを考える。

三日坊主を防ぐ仕組みをGoogle Apps Scriptで作る

f:id:tadaken3:20170922204913p:plain こんにちは!
タダケン(@tadaken3)です。

新しいことを始めようと意気込んでみても三日坊主になってしまったことはありませんか。

例えば、ジム通い。

通い始めた直後はモチベーションも高く意気揚々と筋トレに勤しんでいくのですが、ときには天気が悪いことを理由に、ときには仕事が忙しいことを理由に、だんだんジムに行かなくなってしまいます。

そんなことではいけない!これではムキムキマッチョになれない!

意志の力に頼らずジムに通えるようにしようと考え、三日坊主を検知したらGoogle Apps Scriptで通知する仕組みを作ってみたところ、これが自分の三日坊主を防ぐのに大いに役立ちました。

今回は三日坊主を克服するための仕組みをGoogle Apps Scriptで作る方法をご紹介します。 ジム通い以外にも、習慣化したいものに応用できるはずです。

三日坊主克服システムの概要

三日坊主克服システムの仕組みを簡単にご説明すると

  • ジムに行った履歴を残して管理する
  • 最後にジムに通った日から3日経過すると通知が送られる
  • ジムに行った記録はボタン一つで簡単に残せるようにする

です。

三日坊主が検知されるとこのように通知が送られます。

f:id:tadaken3:20170921235328j:plain

三日坊主克服システムはWEBサービスを組み合わせて構築しました。 もちろん無料でできます。

利用したサービス・役割は以下の通りです。

図にするとこんな感じです。

f:id:tadaken3:20170922114518p:plain

スマートフォンスプレッドシートの連携をIFTTT、それ以外の部分をGoogle Apps Scriptが担っています。

では、さっそく作成方法をご説明します。

IFTTTとGoogleスプレッドシートを連携してジムに行ったことを簡単に記録できるようにする

IFTTTとは

まず、IFTTTとGoogleスプレッドシートを連携させてスマホで簡単に押せる「ジムに行った」ボタンを作ります。

IFTTTを簡単に説明すると「あるWebサービスとあるWebサービス間を自動的に連携する」WEBサービスです。

ifttt.com

例えば、「もしTwitterに投稿したら、Facebookにも同じ投稿をする」といった「Applets」を簡単に作れます。詳しいことは省略しますが、IFTTTを使うとさまざまなWEBサービスを簡単に連携できるようになり、大変捗ります。

「もしスマートフォンウィジェットにあるボタンを押したら、○○をする」というAppletsも作ることができます。

こちらを使って「もしスマートフォンウィジェットにあるボタンを押したら、スプレッドシートに日時を記録する」というAppletsを作成します。

IFTTTをダウンロードする

まずはIFTTTのアプリが必要になりますので、アプリストアで「IFTTT」と検索するか、こちらからダウンロードしてください。1

IFTTT on the App Store

IFTTT - Google Play の Android アプリ

アプリを起動したらアカウント作成画面が出てくると思いますので、「Googleアカウント」「Facebook」アカウントでログインするか、新たにアカウントを作成してください。

新しいアプレットを作る

アカウントの作成ができたら、トップの右下にある「My Applets」をタップします。ここに作ったAppletsが保存されます。

では、早速、新しいAppletを作成ましょう。Applet作成するには、右上の「+」をタップします。

f:id:tadaken3:20170922000025j:plain


するとこのような画面がでてきます。

f:id:tadaken3:20170922000145p:plain

IFTTTは「if this then that」の略でthisの部分に「きっかけ」(トリガー)、thatの部分に「行動」を指定することでAppletが作られます。

「this」の部分をタップして、トリガー部分を設定します。「button widget」を検索して選択します。

f:id:tadaken3:20170922000206j:plain

「Chose trigger」とトリガーを選ぶよう指示が出ますので、そのまま「Button press」を選びます。

f:id:tadaken3:20170922000223j:plain

次に「行動」部分の「that」を設定します。今度は「Goole Drive」を検索してタップしてください。

f:id:tadaken3:20170922082614j:plain

「Choose action」と促されますので「Add row to spreadsheet」(スプレッドシートに行を追加)を選択します。 f:id:tadaken3:20170922000349j:plain

続いて、スプレッドシートの設定になります。

「Spreadsheet name」の部分はお好きなスプレッドシート名を入力ください。該当するスプレッドシートがない場合は、自動で作成されるのでご安心ください。

「Formatted row」の部分は記録される行の内容になります。今回は時間だけがわかればいいのでOccurredAtだけ残してあとは削除してしまいましょう。

「Drive folder path」の部分はスプレッドシートの保存場所になりますので、こちらもお好きなところに変更してください。

f:id:tadaken3:20170922000622j:plain

完了したら「next」をタップします。

Appletが作られます。最後に「Edit title」でわかりやすい名前を設定しておきましょう。

これでボタンが作成されました。スマートフォンの設定でウィジェットにIFTTTアプリを追加すると、先ほど作成されたボタンが表示されるかと思います。

f:id:tadaken3:20170922000806j:plain

早速ボタンを押してテストしてみましょう。

このようにスプレッドシートにボタンを押した時間が記録されます。

f:id:tadaken3:20170921233435p:plain

Point IFTTTとGoogleスプレッドシートを連携させる

Google Apps Scriptで最後にジムに行った日から何日経過したか計算する

IFTTTのタイムスタンプを日付に変換する

ここからはGoogle Apps Scriptを使って経過日数を計算していきます。2 まずIFTTTで記録したタイムスタンプそのままだと、日付の計算ができないので日付型に変換する関数を作ります。

//IFTTTの日付形式から通常の日付に変換
function toDateFromIFTTT(str){
  str =  String(str);
  str = str.replace(/at.*/,"")//正規表現でatより後ろの部分を削除
  d = new Date(str);
  return d;
}

日付から経過日数を計算する

IFTTTでは、ボタンを押すたびに最終行に行が追加される仕様になっています。

そこで、最終行にセットされた日付から経過日数を算出します。 経過日数を算出するために、スプレッドシートの計算式を使っています。計算式をスクリプトで埋め込む方式だとスプレッドシートを確認した際も自動で計算されるからです。

計算式をセットするスクリプトをこのように追加します。

var ss = SpreadsheetApp.getActiveSpreadsheet(); //スプレッドシートを取得
var sheet = ss.getSheetByName("log"); //シートを取得

//シートの最終行に経過日を計算する式をセットする
function setFormuraLastRow(){
  //シートの使用範囲のうち最終行を取得
  var maxRow = sheet.getDataRange().getLastRow(); 
  //A列の最終行の値を取得
  var str  = sheet.getRange(maxRow,1).getValue();
  //スプレッドシート用の式
  var code = '=TODAY() - TO_DATE(B'+ maxRow+')';
  //フォーマットした日付をセット
  sheet.getRange(maxRow,2).setValue(toDateFromIFTTT(str));
  //式をセットする
  sheet.getRange(maxRow,3).setFormula(code);
}

試しにsetFormuraLastRow関数を実行すると、B列に日付のデータ、C列に経過日数が表示されているかと思います。

f:id:tadaken3:20170921233732j:plain

C列では「=TODAY - TO_DATE(B1)」という式をセットして、経過日を計算しています。

Point Google Apps Scriptで最後に行動した日からの経過日数を計算する

Google Apps ScriptでLINEに通知を送る

LINE Notifyのアクセストークンを取得する

LINEに通知を送るには、「LINE Notify」という仕組みを使います。

まず、LINEアプリからLINE Notifyのアカウントを友達として追加します。

次にLINE NotifyのページにLINEアカウントでログインしてアクセストークンを発行します。

アクセストークンはGoogle Apps ScriptからLINEに通知するために必要になりますので、メモしておきましょう。

わからない場合はこちらの解説記事も参考にしてみてください。

qiita.com

Google Apps ScriptでLINE通知を実装する

では、スプレッドシートに戻って、Google Apps Scriptで通知部分を実装してきましょう。

//LINEに通知を送る関数
function sentToLine(message){
  var token = "先程取得したアクセストークン";
  var options =
   {
     "method"  : "post",
     "payload" : "message=" + message,
     "headers" : {"Authorization" : "Bearer "+ token}     
   };

   UrlFetchApp.fetch("https://notify-api.line.me/api/notify",options);
}

これですべての部品が整いました。

Point LINE NotifyでGoogle Apps Scriptから通知を送る

三日坊主克服システムの完成!

では、三日坊主克服システムを完成させましょう。main関数を作って、メインルーチンを実装します。スプレッドシートの値を取得して、経過日が3日もしくは7日以上であれば、LINEに通知をするようにします。

完成形のプログラムはこのようになります。

var ss = SpreadsheetApp.getActiveSpreadsheet(); //スプレッドシートを取得
var sheet = ss.getSheetByName("log"); //シートを取得

function main(){
  setFormuraLastRow()
  var maxRow   = sheet.getDataRange().getLastRow();
  var passDate = sheet.getRange(maxRow,3).getValue();
  var message  ="";
  //経過日が3日もしくは7日以上だったらLINEに通知を送る
  if (passDate==3 || passDate>=7){
      message = "最終トレーニングから"+ passDate + "日経過しました";
      sentToLine(message);
  }
}

//IFTTTの日付形式から通常の日付に変換
function toDateFromIFTTT(str){
  str =  String(str);
  str = str.replace(/at.*/,"")
  d = new Date(str);
  return d;
}

//シートの最終行に経過日を計算する式をセットする
function setFormuraLastRow(){
  var maxRow = sheet.getDataRange().getLastRow(); 
  var str  = sheet.getRange(maxRow,1).getValue();
  var code = '=TODAY() - TO_DATE(B'+ maxRow+')';
  sheet.getRange(maxRow,2).setValue(toDateFromIFTTT(str));
  sheet.getRange(maxRow,3).setFormula(code);
}

//LINEに通知を送る関数
function sentToLine(message){
  var token = "先程取得したアクセストークン";
  var options =
   {
     "method"  : "post",
     "payload" : "message=" + message,
     "headers" : {"Authorization" : "Bearer "+ token}     
   };

   UrlFetchApp.fetch("https://notify-api.line.me/api/notify",options);
}



最後にスクリプトのトリガーを設定します。main関数を通知を送りたい時間帯を選んで日タイマーでセットします。

f:id:tadaken3:20170921234555j:plain

Point トリガーを設定してスケジュールでスクリプトを実行する

まとめ

今回は、Google Apps Scriptで三日坊主克服システムの作り方を解説しました。

を組み合わせて仕組み化しました。

仕組み化することで意識せずに三日坊主を検知できるので、今までよりは三日坊主を克服しやすくなったと思います。

あなたが、三日坊主を克服して新しい習慣を身につけられることを祈っています。

最後に尊敬するTestosterone先輩の名言を掲載します。

読者、フォロワーになってください

本ブログではPythonGoogle Apps Scriptの役立つテクニックを公開しています。よろしければ、本ブログの読者もしくはTwitterアカウントのフォロワーになっていただけると更新の励みになります。ぜひ一緒にプログラミングを学びましょう。


  1. 本記事ではアプリの画面で説明していますが、PCからブラウザ経由でもアプレットの作成ができます。

  2. スプレッドシートのシート名はlogに変更していますので、ご注意ください。