Googleカレンダーの1週間分の予定をGASを使いLINE通知

　Googleカレンダーの予定をGAS(Google Apps Script)を使ってLINEに通知します。
1日分ではなく1週間分の予定を通知しています。そのほうが先のことも思い出せるので…。
普段から予定に場所とか説明を細かく記載しないため、時間とタイトルだけシンプルに表示させます。

流れとしては大きく３つです。
１、LINE Notifyでアクセストークンの発行
２、GoogleカレンダーIDの確認
３、Google Apps Scriptの用意
スクリプトの実行は"毎日〇〇時に実行"というように、時間をトリガーにします。

## LINE Notifyでアクセストークンの発行
以下にLINE IDでログインします。
https://notify-bot.line.me

その後画面右上のマイページをクリック
![Inkedキャプチャ_LI.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131627/1a4ec759-6051-4986-964e-1eec56edb120.jpeg)

下のほう、「トークンを発行する」をクリック
<img width="511" alt="キャプチャ2.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131627/6361dad2-30e5-b193-732b-30d0402f8afe.png">

トークン名(LINE通知の時のメッセージタイトル)を入力し、通知を送信するトークルームを選択します。
自分のみに通知する場合、「1:1でLINE Notifyから通知を受け取る」でOKです。

発行するとトークンが表示されるので、必ず控えておきます。
![Inkedキャプチャ4_LI.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131627/cb5c53ff-1ded-a58d-f9cb-89c2e976284d.jpeg)

## GoogleカレンダーIDの確認
Googleカレンダー右上の歯車マークより「設定」を選択します。
<img width="219" alt="キャプチャ6.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131627/c8a224bc-2a69-d39e-ab30-f74c7d92dba2.png">

左側の「マイカレンダーの設定」にて自分のアカウントをクリックします。
そして下にスクロールすると「カレンダーの統合」が表示され、そこにアカウントIDが表示されます。
![Inkedキャプチャ8_LI.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131627/711c44a8-578e-be35-1aee-b013029f7ffd.jpeg)



## Google Apps Scriptの用意
Googleドライブ、左上の「＋新規」より、その他 > Google Apps Scriptを選択します。
※Google Apps Scriptが表示されない場合、「＋アプリを追加」より追加できます。
<img width="345" alt="キャプチャ5.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131627/53714137-a4f1-7d3b-db7b-028db835cb67.png">

コード編集画面に遷移します。
<img width="624" alt="キャプチャ10.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131627/f5aa07e5-c556-6ba0-5d93-abcb6ab1b255.png">

コード.gsの編集画面に以下のコードを貼り付けます。
LINE Notifyのトークン、GoogleアカウントのIDを記載する箇所があるので、
自分の環境に合わせて修正してください。

```js
function myFunction(){
  
  var startDate = new Date();
  var period = 7; // 予定を表示したい日数

  startDate.setDate(startDate.getDate() + 1);
  var schedule = getSchedule(startDate, period);
  var message = scheduleToMessage(schedule, startDate, period);

  sendToLINE(message);  
}

// Googleカレンダーから予定取得
function getSchedule(startDate, period){
  var calendarIDs = ['GoogleアカウントのIDを記載']; //カレンダーIDの配列。カレンダーを共有している場合、複数指定可。
  
  var schedule = new Array(calendarIDs.length);
  for(var i=0; i<schedule.length; i++){schedule[i] = new Array(period);}
  
  for(var iCalendar=0; iCalendar < calendarIDs.length; iCalendar++){
    var calendar = CalendarApp.getCalendarById(calendarIDs[iCalendar]);
    
    var date = new Date(startDate);
    for(var iDate=0; iDate < period; iDate++){
      schedule[iCalendar][iDate] = getDayEvents(calendar, date);
      date.setDate(date.getDate() + 1);
    }
  }
  
  return schedule;
}  

function getDayEvents(calendar, date){
  var dayEvents = "";
  var events = calendar.getEventsForDay(date);
  
  for(var iEvent = 0; iEvent < events.length; iEvent++){
    var event = events[iEvent];
    var title = event.getTitle();
    var startTime = _HHmm(event.getStartTime());
    var endTime = _HHmm(event.getEndTime());
    
    dayEvents = dayEvents + '・' + startTime + '-' + endTime + ' ' + title + '\n';
  }

  return dayEvents;
}

function scheduleToMessage(schedule, startDate, period){
  var now = new Date();
  var body = '\n1週間の予定\n' 
    + '(' +_Md(now) + ' ' +_HHmm(now) + '時点)\n'
    + '--------------------\n';
  
  var date = new Date(startDate);
  for(var iDay=0; iDay < period; iDay++){
    body = body + _Md(date) + '(' + _JPdayOfWeek(date) + ')\n';
    
    for(var iCalendar=0; iCalendar < schedule.length; iCalendar++){
      body = body + schedule[iCalendar][iDay];
    }   
    
    date.setDate(date.getDate() + 1);
    body = body + '\n';
  }

  return body;
}

// LINE通知
function sendToLINE(message){
  var token = 'LINE Notifyのトークンを記載'; //LINE Notifyのトークン
  var options =
      {
        "method": "post",
        "payload": "message=" + message,
        "headers": {"Authorization" : "Bearer "+ token}
      };

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

// 日付指定の関数
function _HHmm(date){
  return Utilities.formatDate(date, 'JST', 'HH:mm');
}

function _Md(date){
  return Utilities.formatDate(date, 'JST', 'M/d');
}

function _JPdayOfWeek(date){
  // date = new Date()
  var dayStr = ['日', '月', '火', '水', '木', '金', '土'];
  var dayOfWeek = date.getDay();
  
  return dayStr[dayOfWeek];
}
```
そしてメニューバーの「実行」 > 関数を実行 > myFunction をクリックして実行します。
※スクリプトの保存を促されるので、スクリプト名を適当に入力して保存してください。

するとこのような画面が表示されます。
<img width="311" alt="キャプチャ11.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131627/0250f697-a283-4049-5af5-e79b01c8d3eb.png">

初回実行のみ認証が必要になります。自身のGoogleアカウントで認証します。

成功すると以下のようにLINEに通知がきます。
<img width="200" alt="キャプチャ9.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131627/fbca179f-6b5e-40ea-8067-7c1606f2a51e.png">

### トリガーの設定
定期実行させたいのでトリガーを設定します。
メニューバー「編集」 > 現在のプロジェクトのトリガー を選択します。
<img width="251" alt="キャプチャ13.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131627/6ddf5513-2353-5faa-ca50-8709b135ffdc.png">

右下の「トリガーを追加」をクリックします。
<img width="726" alt="キャプチャ14.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131627/45321b21-403f-b6e1-c421-4eee4e19c73b.png">

「時間ベースのトリガーのタイプを選択」を 日付ベースのタイマー に変更し、
通知させたい時刻を選択、保存します。
<img width="533" alt="キャプチャ15.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131627/00c58dcb-9743-e95b-1f40-ccaa1e568a05.png">

これで指定した時刻に通知が来るようになります。

## 参考
https://note.mu/makotou/n/ne2819aa536bb