みなさん、こんにちは!
タカハシ(@ntakahashi0505)です。
引き続きGoogle Apps Scriptでチャットワークに自動でタスクを追加する仕組みを作っています。
以前の記事で毎日のタスクについて自動でチャットワークにタスク追加する方法をお伝えしました。
それで、毎日だけでなく毎月だったり毎週だったりのタスクも自動で追加していきたいので、その事前準備としてスプレッドシートに毎月のタスクについて、次のタスク期限を求めるように数式を仕込みました。
それがこちらの記事です。
これで準備が整いましたので、今回はGoogle Apps Scriptで毎月、毎週も含む定期のタスクを自動でチャットワークにタスク追加するプログラムを作っていきたいと思います。
では、いってみましょう!
定期タスクのリストをスプレッドシートに準備
まず定期で追加するタスクについてまとめたスプレッドシートがこちらです。
A列からタスク内容、ルームID、アカウントID、頻度、設定日、次のタスク期限という構成です。
次のタスク期限はE列が日数であれば今日以降の最初にくるその日数の日付、「末」であれば今日以降の最初にくる末尾の日付が出力されます。
ここについては前回記事をご参考下さい。
スクリプトの流れ
毎月のタスクについては、タスク期限当日のタスク追加だと、さすがにタスクの消化がしんどいので、期限の3日前に自動でタスクを追加するというルールににします。
スクリプトの流れとしては
- スプレッドシートとその最終行数、データの取得をする
- スプレッドシートの全ての行について繰り返し
- 頻度が「毎日」であれば
- 期限を本日としてチャットワークにタスクを追加
- 頻度が「毎月」であれば
- 今日の日付がタスク期限の3日前であれば
- チャットワークにタスクを追加
- 今日の日付がタスク期限の3日前であれば
- 頻度が「毎日」であれば
という流れで進めたいと思います。
チャットワークに定期タスクを追加するスクリプト
スクリプトはこちらです。
function addRegularTasks() { /* スプレッドシートとその最終行数、データを取得 */ var mySheet=SpreadsheetApp.getActiveSheet(); var maxRow=mySheet.getDataRange().getLastRow(); var myVars=mySheet.getDataRange().getValues(); var token = 'APIトークン'; //チャットワークAPIトークン for(var i=2;i<=maxRow;i++){ var date = new Date(); //今日の日付 var limit = "" var body = myVars[i-1][1-1]; //タスク内容 var room_id = myVars[i-1][2-1]; //ルームID var to_ids = myVars[i-1][3-1]; //アカウントID if(myVars[i-1][4-1] === "毎日"){ limit = changeUnixTime(date); addTask(token,room_id,body,limit,to_ids); } else if(myVars[i-1][4-1] === "毎月" || myVars[i-1][4-1] === "毎週"){ var date1 = new Date(myVars[i-1][6-1]); //タスク期限 var date2 = new Date(date.setDate(date.getDate()+3)); //期限日の3日前に通知 if(compareDate(date1,date2)){ limit = changeUnixTime(date1); addTask(token,room_id,body,limit,to_ids); } } } }
24行目からのif文にて、D列の頻度が「毎日」か「毎月」(または「毎週」)かで分岐をしています。
「毎日」であれば、本日を期限としてチャットワークにタスクを追加します。
日付を固定小数点表記のUNIX時間に変換する関数
changeUnixTimeは日付を固定小数点表記のUNIX時間に変換する関数です。
/* dateを受け取って固定小数点表記のUNIX時間に変換 */ function changeUnixTime(date){ var limit = date.getTime()/1000; return limit.toFixed(); }
なんてことはありませんね。この処理が「毎日」と「毎月」の二か所で必要になったので関数化をしました。
getDateとsetDateで3日後の日付を求める
大元の関数addRegularTasksですが、24行目以降が「毎月」(または「毎週」)だった場合の処理になります。
26行目のdate1には、スプレッドシートのF列「次のタスク期限」に算出されている日付、27行目のdate2には今日の3日後の日付を格納します。
date2ですが二つのメソッドの組み合わせをしています。
まずDateオブジェクトから日数を取り出すgetDateメソッドで日数を取り出し、setDateでDateオブジェクトの日数を設定するときにプラス3をすることで「3日後」の日付を求めています。
setDateは
とすることで、そのDateオブジェクトの日数を設定します。
同じようにget~とset~で何かを書き換えるみたいなことがGASでは結構ありますので、慣れておくと良いと思います。
後日追記:Moment.jsライブラリを使うと簡単に日時の計算ができる
Moment.jsライブラリのaddメソッドを使うと日時の加算が簡単にできるようになりますので、以下ページもご参考下さい。
二つの日付が等しいかを判定する関数
29行目のif文ですが、compareDateというのは二つの日付が等しいかどうかを判定する関数です。
/* 2つの日付が等しいかを比較する */ function compareDate(date1,date2){ if(date1.getFullYear() === date2.getFullYear() && date1.getMonth() === date2.getMonth() && date1.getDate() === date2.getDate()){ return true; }else{ return false; } }
if(date1 === date2)などという条件文でできそうですが、そうはいきません。
dateオブジェクトには年月日だけでなく、時分秒も含まれているので、1秒でもずれていれば等しいという判定になりません。
ということで、年月日だけを比較する関数を作りました(他にスマートな方法があれば教えて欲しい…)。
ちなみに、その際に使っているgetFullYear、getMonthなどのメソッドについては、以下の記事で詳しく説明しているので、ご参考ください。
後日追記:Moment.jsライブラリを使うと簡単に日時の比較ができる
Moment.jsライブラリのisSameメソッドを使うと日時の比較が簡単にできるようになりますので、以下ページもご参考下さい。
実行結果
では、このスクリプトを実行してみましょう。
このように、当日のタスクが二つ、毎月のタスクが一つ追加されました。
イベントトリガーで毎日に設定をしておけば、毎日のタスクも毎月のタスクもそれぞれがきちんと自動でタスク追加されるようになります。
毎週のタスクにも対応
実はこのスクリプトですが毎週のタスクもそのまま対応しています。
例えばスプレッドシートとして
このようにH列、I列に曜日と値の表を準備します。
F6セルには
=IF(VLOOKUP(E6,$H:$I,2,false)>WEEKDAY(TODAY()),TODAY()+(VLOOKUP(E6,$H:$I,2,false)-WEEKDAY(TODAY())),TODAY()+(VLOOKUP(E6,$H:$I,2,false)-WEEKDAY(TODAY())+7))
などとしています。
もう少しスッキリかけそうな気もしますが、各自研究してみてください。
まとめ
Google Apps Scriptで毎月、毎週、毎日の定期のタスクをチャットワークに自動でタスク追加するプログラムについてお伝えしました。
日付の扱い…スプレッドシートでもGoogle Apps Scriptでもなかなかやっかいかもですね。
ですが、スプレッドシート、Gmail、カレンダーなどといったGASの得意分野を扱う上では避けては通れないと思いますので、ぜひ慣れてしまってほしいと思います。
本連載はこれでひとまず終了となります。
また面白いアイデアを見つけたら紹介していきますので、どうぞお楽しみにしてくださいね。