[GAS]Googleカレンダーの予定+定期的なリマインドを毎朝LINE Notifyで通知

GAS

Google Apps Scriptで、Googleカレンダーに登録されている予定と、毎週や隔週、第何曜日などの定期的な予定を毎朝LINE NotifyでLINEに通知する方法です。スクリプトが分からない初心者でも簡単にできるよう丁寧に解説していきます。

予定を忘れがちな人<br>
予定を忘れがちな人

第2、第4月曜日のミーティングの前々日に、メール送信しないといけないのですが、毎回リマインダーセットするのも面倒なので、何かいい方法ありませんか?

シップ
シップ

GASを使えば第何番目の特定曜日だけでなく、その何日前かも指定してリマインドできますよ。

概要

iOSのリマインダーでも繰り返しで「第1月曜日」のように第何何曜日という風にリマインドできますが、その何日前に通知させることはできません。

例えば、第一月曜日の前々日にリマインドさせたい場合など、第1土曜日にリマインド設定しても、日曜日や月曜日から月が始まる場合、第1土曜日ではすでに第1月曜は過ぎているわけです。

それで、第何曜日の何日前にLINEで通知できるスクリプトをGASで作成しました。ついでにGoogleカレンダーに登録されている当日の予定も一緒に通知できるようにして毎朝LINE Notifyを見るだけで今日やるべき予定を確認できるようにしました。

使用例

こんなときに
  • 第1水曜日が粗大ゴミの日、その前日にリマインドが欲しい。
    (たいていのリマインダーでも第何曜日でのリマインドはできますが、その当日しかできません。このスクリプトでは第何曜日の何日前に通知するかを指定できます。)

Google Apps Scriptを利用するため、すべて無料で実現できます。

必要なもの
  • Googleカレンダー(カレンダーの予定も通知する場合)
  • LINE Notifyのアクセストークン(無料で取得できます)

使用方法

Googleドライブから新規Google Apps Scriptを追加

  1. GoogleドライブをPCで開き、「+新規」ボタンをクリックし、メニューから「その他」→「Google Apps Script」を選択します。すると新しいタブで「無題のプロジェクト」という名前で新しいプロジェクトが作成されます。
  2. コード.gsを選択し(最初から選択されています)最初から入力されているコードは消して、次のコードをコピペします。
function myFunction() {
  // 初期設定項目--------------
  
  // カレンダーID
  const calId = "ここにカレンダーIDを入力";
  
  // LINE Notifyのアクセストークン
  const key = "ここにLINE Notifyのアクセストークンを入力";

  //定期的な予定
  const regularlyEvents = [
    [[1, 3],['水'],-1,"明日は第1、第3水曜日です。"],
    [[3],['火'],0,"今日は第3火曜日です。"],
    [[2,4],['月','木'],0,"第2、第4の月木です。"],
    [[4],['金'],-7,"第4金曜の一週間前です。"],
  ];

  // 初期設定項目ここまで-------

  const url = "https://notify-api.line.me/api/notify";
  const WEEKDAYS = ['日', '月', '火', '水', '木', '金', '土'];

  // LINE Notifyに送るメッセージ
  let msg = new Array();
  
  const now = new Date(); //現在の日時
  const today = new Date(now.getFullYear(), now.getMonth(), now.getDate());

  const cal = CalendarApp.getCalendarById(calId); //カレンダーIDからGoogleカレンダーを取得
  const todayEvent = cal ? cal.getEventsForDay(today) : []; // googleカレンダーより今日の予定を配列で取得。

  // 予定ありなら
  if(todayEvent.length !== 0){
      msg = msg.concat(allPlanToMsg(todayEvent));
  }

  regularlyEvents.forEach( function(event, index){
    const numberOfdays = event[0];  //対象が第何曜日かの配列
    const daysString = event[1];  //対象曜日の配列
    const dayOffset = event[2];  //対象曜日の何日前に送信するか(-2なら2日前に送信)
    const eventName = event[3];  //予定名称

    const daysNumber = daysString.map(days => WEEKDAYS.indexOf(days));//曜日を文字から曜日番号へ変換
    const targetDay = new Date(now.getFullYear(), now.getMonth(), now.getDate() - dayOffset); //対象の日を算出
    const targetDays = getDays(targetDay, daysNumber, numberOfdays);  //第何の各曜日から該当する日付の配列を取得

    if(isToday(targetDay, targetDays)){ //対象の日が、該当する日付にあるなら通知メッセージへ追加
      msg.push(eventName);      
    }
    
    /*
    *その年月のd曜日を取得する関数
    * 
    * @param {Date} date - 調べたい年月の日付(Date型)
    * @param {Array: number} day - 取得したい曜日を表す数値の配列(0:日曜日〜6:土曜日)
    * @param {Array: number} nthday - 対象の第何曜日かを表す数値配列
    * @return {days} ある年月のday曜日の日付の入った配列
    */
    function getDays(date, daysNumber, nthday) {
      const allTarget = daysNumber.map(function(day){

        const year = date.getFullYear();
        const month = date.getMonth();

        const days = [];

        for (let i = 1; i <= 31; i++){
          const tmpDate = new Date(year, month, i);

          if (month !== tmpDate.getMonth()) break; //月代わりで処理終了
          if (tmpDate.getDay() !== day) continue; //引数に指定した曜日以外の時は何もしない
          days.push(tmpDate);
        }

        return days.filter((v, i) => nthday.includes(i+1));
      });
      return allTarget.flat();
    }

    // 対象日かどうかチェックする
    function isToday(target, days){
      const isTodayDate = days.find(day => day.getFullYear() == target.getFullYear() && day.getMonth() == target.getMonth() && day.getDate() == target.getDate());
      return isTodayDate !== undefined 
    }

  });

  if(msg.length > 0){
    const messageText = msg.join("\n");
    const jsonData = {
      message: messageText
    }

    const options =
    {
      "method" : "post",
      "contentType" : "application/x-www-form-urlencoded",
      "payload" : jsonData,
      "headers": {"Authorization": "Bearer " + key}
    };
    //LINE Notifyに送信
    const res = UrlFetchApp.fetch(url, options);
  }
}

// イベントの配列をテキストにして返す
function allPlanToMsg(events/* array */){
  const msg = new Array;
  events.forEach( function(event, index){
    const title = event.getTitle();
    const start = event.getStartTime().getHours() + ":" + ("0" + event.getStartTime().getMinutes()).slice(-2);
    const end = event.getEndTime().getHours() + ":" + ("0" + event.getEndTime().getMinutes()).slice(-2);
    // 予定が終日の時
    if( event.isAllDayEvent() ){
      msg.push(title);
      return;
    }
    msg.push(title + " " + start + "~" + end + "");
  });
  return msg;
}
  1. 5行目に、GoogleカレンダーIDを記入します。

カレンダーIDの取得

Googleカレンダーを開き、「マイカレンダー」の「…」→「設定と共有」から設定画面を開きます。「カレンダーの統合」見出しの下に「カレンダーID」があるのでそれを確認します。

たいていはGoogleアカウントのメールアドレスです。

//「ここにカレンダーIDを入力」の部分を消して、IDに置き換えます。ダブルコーテーションは消さないように注意してください。
// カレンダーID
const calId = "ここにカレンダーIDを入力";

//例えばカレンダーIDが「xxx@example.com」の場合、次のようになります。
const calId = "xxx@example.com";

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

LINE Notifyを開き、LINEアカウントでログインします。メニューよりマイページへ進みます。

アクセストークンの発行(開発者向け)の見出しの下にある「トークンを発行する」ボタンをクリックします。

トークン名を記入します。「今日の予定」などお好きな名前で構いません。

「通知を送信するトークルームを選択してください」の部分では、通知を自分だけに送信する場合は「1:1でLINE Notifyから通知を受け取る」を選択してください。グループを選択することで特定のグループに送信することもできます。

トークンを発行するボタンをクリックします。

発行されたトークンをコピーして、8行目の「ここにLINE Notifyのアクセストークンを入力」を消してその部分にペーストします。

  // LINE Notifyのアクセストークン
  const key = "ここにLINE Notifyのアクセストークンを入力";

定期的な予定を記入

この部分を変更して定期的な予定を記入します。既に入力してあるサンプルを参考にしてください。

予定のフォーマット

1行につき1つの定期的な予定です。

//各予定の形式
    [[第何曜日か],['対象曜日'],何日前か,"予定の名称"],
//
第何曜日か

第1曜日を対象にしたい場合「1」を半角で指定します。複数の場合は「,」(半角コンマ)で区切ります。

例えば、第一水曜日と第三水曜日を指定したい場合、[1,3]となります。もし毎週の場合は[1,2,3,4,5]とすべて指定してください。

対象曜日

対象の曜日です。前項の第何曜日かと組み合わせて使用します。’ ‘(シングルコーテーション)でひとつづつ囲ってください。

例えば、水曜日の場合は [‘水’] となります。月曜日と木曜日を指定したい場合は [‘月’,’木’] となります。([‘月,木’]ではないことに注意してください。)

何日前か

対象の何日前に通知を行うかを指定します。前日なら「-1」、前々日なら「-2」といった具合です。当日に通知する場合は「0」を指定してください。

予定の名称

LINE上で通知するときに表示される予定名です。

//定期的な予定 (例)
  const regularlyEvents = [
    [[1, 3],['水'],-1,"明日はごみの日"],// 第1、第3水曜日の前日にゴミ出しを通知
    [[3],['火'],0,"今日は第3火曜日です。"],
    [[2,4],['月','木'],0,"第2、第4の月と木です。"],
    [[4],['金'],-7,"第4金曜の一週間前です。"],
  ];

4. 「無題のプロジェクト」という名前をわかりやすい名前に変更し、「プロジェクトを保存」ボタンをクリックしてスクリプトを保存します。

スクリプトのタイムゾーンを変更する

このままだとGASのタイムゾーンがアメリカ東部時間のままのため、日本時間へ変更します。

  1. 「プロジェクトの設定」で「「appsscript.json」マニフェスト ファイルをエディタで表示する」にチェックを入れる。
  2. エディタで「appsscript.json」を開き「timeZone」の “America/New_York” を “Asia/Tokyo” に変更する。
「appsscript.json」マニフェスト ファイルをエディタで表示する にチェック
//この部分を
"timeZone": "America/New_York",

//このように書き換え
"timeZone": "Asia/Tokyo",
  1. プロジェクトを保存する

実行する

実行ボタンをクリックすると、「承認が必要です」というダイアログが出るので、「権限を確認」をクリックして、Googleアカウントでログインします。

「このアプリはGoogleで確認されていません」と出ますが、スクリプトは安全なので「詳細」をクリックしてから「今日の予定(安全ではないページ)に移動」をクリックします。(今日の予定は自分がつけた名前に変わります)

「詳細」をクリック
「今日の予定(安全ではないページ)に移動」をクリック
「許可」をクリック

もう一度「実行」ボタンをクリックします。

実行した日に該当する予定があればLINE Notifyに通知が届くはずです。

GASを毎朝実行するためのトリガー設定

このスクリプトを毎朝定期的に実行することで、毎朝LINEに通知が届くようになります。

  1. Google Apps Scriptのメニューから「⏰トリガー」をクリックします。
  2. 右下の「トリガーを追加」をクリックします。
  3. 「時間ベースのトリガーのタイプを選択」で、「日付ベースのタイマー」を選択します。
  4. 「時刻を選択」でお好きな時間帯を選択します。
  5. 「保存」をクリックします。

その時刻になったら通知が来ますので設定はこれで完了です。

その他

使い方や設定方法が分からない場合などはお問い合わせください。カスタマイズが必要な場合もお問い合わせください。お見積りさせていただきます。

この記事を書いた人

PHPが好物な個人開発プログラマ。フリーランスエンジニアとしてWebサービス作ったりしてます。15年の経験を生かしてMENTAでメンターもやってます。WordPressやPHPでお困りのことがあればご相談に乗りますのでDMください。

Follow on SNS
GAS
SOHO MIND

Comments

タイトルとURLをコピーしました