LINE NotifyとGasを使って 〜Googleカレンダー予定通知編〜

先日歯医者の予定をすっ飛ばしてしまったので、GASを使いLINEに予定を通知する機能を作りました。
（別の記事で<a href="https://qiita.com/iiizoo/items/cf3e5b8dd4f2c09887b9">LINEから予定の登録、変更、キャンセル</a>する機能についても書いています。）

※ GASの使い方、LINE Notifyについてなどは他にたくさん記事が出ているので割愛しています。

# LINEへ予定を通知
毎週日曜夜に1週間分の予定を、前日夜に次の日の予定を送るようにします。

### 作るもの
![スクリーンショット 2021-06-28 18.19.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/578913/8b32d2a3-36c2-1fa8-d94b-d829aca30c63.png)

![スクリーンショット 2021-06-28 18.21.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/578913/31c6cc9d-b762-91ef-a0db-1e4662bb40c5.png)


### 事前準備
１）GAS(Google Apps Script)の環境
２）LINE Notifyのアクセストークン

### 実装
１）Googleカレンダーから予定を取得

```.js
//1週間分
function getScheduleForWeek() {
  let tomorrow = new Date();
  tomorrow.setDate(tomorrow.getDate() + 1);

  let oneWeekLater = new Date();
  oneWeekLater.setDate(oneWeekLater.getDate() + 8);
  
  let events = CalendarApp.getDefaultCalendar().getEvents(tomorrow, oneWeekLater);
  if(events.length === 0) {
    sendTolLine("\n来週の予定はありません。");
  }
  let event = setWeekEventsForDisplay(events);
  sendTolLine('\n↓来週の予定です。\n\n' + event);
}

//1日分
function getScheduleForDay() {
  let tomorrow = new Date();
  tomorrow.setDate(tomorrow.getDate() + 1);
  let events = CalendarApp.getDefaultCalendar().getEventsForDay(tomorrow);
  if(events.length === 0 || events === undefined) {
    sendTolLine("\n明日の予定はありません。");
  }
  let event = setDayEventsForDisplay(events);
  sendTolLine('\n↓明日の予定です。\n\n' + event);
}
```


２）　取得した予定を成形（ここは好みの問題）

```.js
const arrayDay = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']

//1週間分の予定を表示用にセット
function setWeekEventsForDisplay(events)
{
  let beforeDayOfTheWeek = '';
  let count = 1;
  let event = ""; 
  
  for (let i in events) {
    let title = events[i].getTitle(); //タイトル
    let startDay = new Date(events[i].getStartTime());
    let startTime = Utilities.formatDate(startDay, "JST", "HH:mm"); //開始時間
    let endTime = Utilities.formatDate(events[i].getEndTime(), "JST", "HH:mm"); //終了時間
    
    let numberOfDay = startDay.getDay(); //曜日番号を取得
    let newdayOfTheWeek = arrayDay[numberOfDay];

    if(beforeDayOfTheWeek !== newdayOfTheWeek) {
      beforeDayOfTheWeek = newdayOfTheWeek;
      count = 1;
      event += "-------------\n" + beforeDayOfTheWeek + "\n-------------\n";
    }
    event += count + "件目\n予定：" + title + "\n開始時間：" + startTime + "\n終了時間：" + endTime + "\n\n";
    count = Number(count) + 1;
  }
  return event;
}

//1日分の予定を表示用にセット
function setDayEventsForDisplay(events)
{
  let event = ""; 
  for (let i in events) {
    let count = Number(i) + 1;
    let title = events[i].getTitle();
    let startTime = Utilities.formatDate(events[i].getStartTime(), "JST", "HH:mm");
    let endTime = Utilities.formatDate(events[i].getEndTime(), "JST", "HH:mm");
    event += count + "件目\n予定：" + title + "\n開始時間：" + startTime + "\n終了時間：" + endTime;
    event += (count !== events.length)?  "\n\n" : "";
  }
  return event;
}
```


３）LINEに予定を送信

```.js
function sendTolLine(message)
{
  let token = "{LINE Notifyのアクセストークン}";
  let options = {
    "method": "post",
    "payload": `message=${message}`,
    "headers": {
      "Authorization": `Bearer ${token}`
    }
  };
  UrlFetchApp.fetch("https://notify-api.line.me/api/notify", options);
}
```

### 通知トリガー
GASのトリガー機能を使い、決まったタイミングで予定を通知するようにします。（すごく便利！！）
細かい設定方法は調べるとたくさん出てきますが、こんな感じで周期（日毎、月毎など）、時間を選択できます。

![スクリーンショット 2021-06-28 18.15.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/578913/4eac3bdc-a08b-bb31-6bcd-3faef1b63bd7.png)

### 最後に
自分用に適当に作ったので、全然リファクタリングできていません。
そして、予定通知もLINE Botを使いたかったのですがLINE Notifyを使う方法しか分からず。
全部1つのチャンネルで完結させたい。。。良い方法ご存知の方いましたらぜひ教えてください。