GoogleAppsScriptで私用の予定を社用のカレンダーにマスクして同期した

# はじめに
## 概要
私がGoogleAppsScriptで作成したプログラムを使って、軽くGoogleAppsScript上でのCalendarの操作について説明できたらと思います。

## 状況
+ 社用は社用、私用は私用のアカウントで予定管理をしています。
+ 社用アカウントのデフォルトカレンダーは他社員に共有されている。
+ デフォルトカレンダーに「私用」って書くと残業絶対できない日として扱われます。

## 作ったもの
+ 私用カレンダーの予定を社用カレンダーにコピーする。
+ コピーするのは2週間後までの予定とする。
+ コピーした予定は名前「私用」以外の情報が記載されていない。
+ 毎日夜間に実行する。 


# プログラムと解説
ざっくりいうと、指定期間の私用をDelete＆Copyしているだけです。
##プログラム
```js

function uniteCal() {
  //統合先のカレンダーID(会社のデフォルトカレンダーのIDを指定)
  var mainCal = CalendarApp.getCalendarById('');
  var startTime = new Date();
  
  //何日後まで同期するか
  var dayCount = 14;
  var endTime = new Date()
  endTime.setTime(startTime.getTime() + dayCount * 24 * 60 * 60 * 1000);

  //予定のタイトル
  var title = '私用';

  //初期化：指定期間の間に私用があったら削除
  var mainCalEvents = mainCal.getEvents(startTime, endTime);
  for(var i = 0; i < mainCalEvents.length; i++){
    var event = mainCalEvents[i];
    if(event.getTitle() == title){
      event.deleteEvent();
    } 
  }

  //統合元のカレンダーIDをリスト形式で列挙
  var subCalIds = [''];

  //私用のカレンダーを取得して、同時刻に社用カレンダーに「私用」イベントを作成
  for(var i = 0; i < subCalIds.length; i++){
    var subCal = CalendarApp.getCalendarById(subCalIds[i]);
    var subCalEvents = subCal.getEvents(startTime, endTime);
    for(var j = 0; j < subCalEvents.length; j++){
      var subCalEvent = subCalEvents[j];

      // allDayEvent(終日イベント)とそれ以外で条件分岐。
      if(subCalEvent.isAllDayEvent()){
        mainCal.createAllDayEvent(title, subCalEvent.getAllDayStartDate(), subCalEvent.getAllDayEndDate());
      } else {
        mainCal.createEvent(title, subCalEvent.getStartTime(), subCalEvent.getEndTime());
      }
    }
  }
}
```

## GoogleAppsScript
GoogleAppsScriptはExcelのマクロのようなものを実現するためのものです。GoogleAppsScriptはJavaScriptでいうDOM操作の感覚で、GoogleApps内の様々なリソースを操作することができます。今回はGoogleCalendarを使いましたが、Gmailなどのアプリケーションを操作することも可能です。
詳しくは[公式ドキュメント](https://developers.google.com/apps-script/reference/calendar/)をご覧ください。


以下、今回操作したGoogleCalendarのオブジェクトとメソッドを紹介します。
### CalendarApp
後述するCalendarオブジェクトと同じような操作を行うことができます。CalendarAppのメソッドはデフォルトカレンダーを操作するためのメソッドなので、`getCalendarById(id)`メソッドや`getCalendarsByName(name)`メソッドを使って操作したいCalendarオブジェクトを選択する必要があります。

### Calendar
ブラウザ上だと左下に並んでいるCalendar一つ一つがCalendarオブジェクトです。
Calendarそのものの操作や後述するカレンダーの予定を作成したりすることができます。
どの予定を編集するかを指定するのもCalendarオブジェクトのメソッドを使用します。
IDだけではなく期間での絞り込みもできるので、[公式ドキュメント](https://developers.google.com/apps-script/reference/calendar/calendar)を確認してください。

### CalendarEvent/CalendarEventSeries
Calendarに登録されている予定の一つ一つがCalendarEvent/CalendarEventSeriesオブジェクトの要素です。
CalendarEvent/CalendarEventSeriesオブジェクトの要素では、さらに終日イベントか否かで属性やメソッドが分かれています。

|  | 終日 | それ以外 |
|:-:|:-:|:-:|
| **繰り返し** | AllDayEventSeries | EventsSeries |
| **それ以外** | AllDayEvent | Event |

それぞれプロパティや使えるメソッドが少しずつ違います。
例えば、CalendarEventには開始時刻と終了時刻を指定できますが、AllDayEventでは日付だけを指定できます。画面上のCalendarを操作するのと同じですね。

# 補足
## 社用アカウントで予定を作成しても大丈夫なんだけど
今回は私用のアカウントのカレンダーを社用のカレンダーに共有するというユースケースでしたが、社用のカレンダーに書き込んでも大丈夫という人はもっと楽な方法があるみたいです。
基本的な機能らしいですよ!みなさん!

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">再掲:これすると見えないよ <a href="https://t.co/l7nZpwFYYb">pic.twitter.com/l7nZpwFYYb</a></p>&mdash; 中村 優輝 (@yuki_027) <a href="https://twitter.com/yuki_027/status/1058365036966473729?ref_src=twsrc%5Etfw">2018年11月2日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">こんな感じだわ。 <a href="https://t.co/anxPnfn50D">pic.twitter.com/anxPnfn50D</a></p>&mdash; 中村 優輝 (@yuki_027) <a href="https://twitter.com/yuki_027/status/1058366091653566464?ref_src=twsrc%5Etfw">2018年11月2日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>


## プログラムを実行する準備
### カレンダーの共有
私用アカウントのカレンダーを社用アカウントに共有する必要があるかもしれません。私は共有しています。
[Google　Calendarヘルプ 他のユーザーとカレンダーを共有する](https://support.google.com/calendar/answer/37082?hl=ja)

### カレンダーID
私用のカレンダーID、社用のカレンダーIDがそれぞれ必要です。
[sukicomi Googleカレンダーで各カレンダーのカレンダーIDを知る方法](http://www.sukicomi.net/2018/07/google-calendarid.html)

# さいごに
GoogleAppsScriptはEditor上でデバッグをすることもできるので、とても便利でした。
ただ、普段使っているJetbrains製のエディタと比べると「うーん」なので、近々node.js×Serverless構成にリプレースしたいですね。

# 参考サイト
[公式ドキュメント](https://developers.google.com/apps-script/reference/calendar/)