明日のGoogleカレンダーの予定をLINE Notifyで自動通知

# 諸注意

2025年3月31日にLine Notify はサービスを終了します。

https://notify-bot.line.me/closing-announce

# 下準備（LINE Notifyのトークンを取得）

LINE側の設定をまずはしていく必要があります。

## 下準備①
自分のLINEを開いて、メールアドレスとパスワードを設定しておいてください。
※設定済みの方は手続き不要です

#### iPhoneの場合
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216701/d03ed72a-b623-4654-d903-eb17760d0079.png)

#### Androidの場合
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216701/947f3618-640b-d301-58bb-f95863b3c612.png)

## 下準備②

[LINE Notify](https://notify-bot.line.me/ja/)にアクセスして、ログインできるかチェック。
<img width="1280" alt="スクリーンショット 2019-04-12 15.37.58.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216701/00789fda-659a-f58e-aec4-ee806f42f7d6.png">

# Googleスプレッドシートを開いて、スクリプトシートを開く(コンテナバインドスクリプト)

新しく[スプレッドシート](https://spreadsheet.new)を開く。
<img width="721" alt="スクリーンショット 2019-01-23 13.15.50.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216701/28216bb9-153a-6325-57d4-40538687be79.png">
ツールのスクリプトエディタを選択すると、下記の画面になる。
<img width="656" alt="スクリーンショット 2019-01-23 13.16.08.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216701/fbaf1138-3041-0198-2140-1a72c6a432e2.png">
ここにコードを書いていきます。

## ソースコード

```code.js

// ここに発行したアクセストークンを書く
const token = "*********";

// ここにカレンダーIDとカレンダー名を書く。ここに書いたカレンダーのみリマインド対象になる
const calendarTitleMap = {
  "********@gmail.com" : "****のカレンダー",
  "********@group.v.calendar.google.com" : "****のカレンダー" // 例： "ja.japanese#holiday@group.v.calendar.google.com" : "日本の祝日"
};

const weekday = ["日", "月", "火", "水", "木", "金", "土"];

function notifyEvent() {
  const calendars = CalendarApp.getAllCalendars();
  const dt = new Date();// dateオブジェクトの生成
  dt.setDate(dt.getDate() + 1); //明日をdtにセット
  const tomorrow = Utilities.formatDate(dt, `JST`, `M/d (${weekday[dt.getDay()]})`);

  let message = ` ${tomorrow}\n\n`;
  let dayText = "";

  // 取得した予定の数だけfor文でまわす
  for(i in calendars) {

    const calendar = calendars[i];
    const calendarName = calendarTitleMap[calendar.getId()]
    if ( calendarName == undefined ) {
      continue; // カレンダー名が設定されてなければパス
    }

    let events = calendar.getEventsForDay(dt);
    if( events.length == 0 ) {
      continue;
    }

    // カレンダー名を添えたい場合
    dayText += `< ${calendarName} >\n`;

    // イベントの数だけfor文でまわす
    for(e in events) {
      dayText += toDayText(events[e]);
    }
    dayText += "\n"
  }

  if ( dayText == "") {
      dayText += "予定はありません\n\n";
  }
  message += dayText;

  console.log(message);

  // LINE送信
  sendToLine(message);
}

function sendToLine(message){
  const options = {
    "method"  : "post",
    "headers" : {"Authorization" : "Bearer "+ token},
    "payload" : "message=" + message
  };

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

function toDayText(event) {
  return toTimeText(event.getStartTime()) + ' - ' + toTimeText(event.getEndTime()) + " " + event.getTitle() + '\n';
}

function toTimeText(str){
  return Utilities.formatDate(str, 'Asia/Tokyo', 'HH:mm');
}

```

発行したトークンと、適切なメールアドレスを入力してあげて実行を押すと、通知が行きます。

![スクリーンショット 2021-03-12 0.18.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216701/9b646b3f-6759-31bc-9e36-b22bba28e886.png)

## 日付がおかしい場合

下記の設定を変更すればOK
（デフォルトのタイムゾーンが「GMT-05:00」で設定されているので、日本標準時である「GMT+09:00」に設定する必要あり）

![スクリーンショット 2021-03-12 0.54.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216701/8b0a1d90-de3f-d458-ddf6-170c6c12ccf7.png)

ファイルに新しく ```appsscript.json```が新しく表示されてるので、下記のコードに変更

```appsscript.json
{
  "timeZone": "Asia/Tokyo",
  "dependencies": {
  },
  "exceptionLogging": "STACKDRIVER",
  "runtimeVersion": "V8"
}
```

![スクリーンショット 2021-03-12 0.54.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216701/6dda53a2-1691-759d-c48f-b215f29d820d.png)

# トリガー設定の例

毎日LINEに通知するために、トリガー設定をGoogle側で設定することができます。
例えば、毎晩午後8時〜9時に明日の通知を送る設定にする場合、下記の設定でトリガーを追加することができます。

実行する関数：notifyEvent
デプロイ時に実行：Head
イベントのソース：時間手動型
時間ベースのトリガーのタイプ：日付ベースのタイマー
時間：午後8時〜9時

![スクリーンショット 2021-03-12 11.56.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216701/4e3bfbf9-234e-f71a-cc18-17563da186cd.png)

# 解説

### 用語解説

- 関数
    - ソースコードの内容が書かれた箱のようなもの
- 引数
    - 関数に与えるパラメータのこと

## 使ってる関数の説明

- CalendarApp.getAllCalendars()
    - 自分のGoogleカレンダーに共有されている全カレンダーのリストを取得

- new Date()
    - 日付を扱うためのオブジェクトを作成

- .setDate()
    - 指定された日付のローカルタイムに沿って、その月の日を設定します。

- .getDate()
    - 指定された日付のローカルタイムに沿って、その月の日を返します。

- Utilities.formatDate(引数1, 引数2, 引数3)
    - 指定した書式で日時を取得。引数は、オブジェクト名、タイムゾーン（JST等）、書式、の順で。
    - “JST”とは、Japan Standard Time の頭文字を取った略語で、日本標準時のこと。

- getEventsForDay(日付オブジェクト)
    - 指定した日付に登録されている予定イベントをすべて取得


## 作成している関数の概要説明

- sendToLine()
    - LINE送る。引数にメッセージ

- toDayText()
    - 予定を指定の書式に変換する

- toTimeText()
    - 日時を指定の書式に変換する

YouTube: https://youtu.be/umIsXEkiDpQ