Gmailに受信したFEELCYCLE予約完了メールからGoogleカレンダーにイベント追加するGASスクリプト

# 参考にした記事
[Gmailに受信した予約完了メールからGoogle Calendarにイベント追加するGASスクリプト](https://qiita.com/chkk525@github/items/d7e739361fd7f78cb7cf)

上記をfeelcycle専用に書き換えました。
- 執筆時点(2018/06)のGmail仕様に合わせました。
- イベント名に、レッスン名、インストラクター名、バイクNo.を表示するようにしました。
- キャンセルに対応しました。

[regular expressions 101](https://regex101.com/)
正規表現のテストに役立った。

# 注意事項
- メールの受信順序によって、登録削除に失敗することがあります。
- 登録削除に使用したメールはゴミ箱に移動し、放っておくと消えますので注意。

# コード
```AddFCEvent.gs
/*
 * Gmailに受信したFeelCycle予約完了メールから自動的にGoogle Calendarにイベント登録する
*/

// 日時の正規表現パターン
var RegExpPattern = {
  regExp_date: /(\d{4}年\d{1,2}月\d{1,2}日)/gm,// 日時形式(ex: 2016年6月25日)
  regExp_time: /(\d{2}:\d{2})/gm,// 時刻書式(ex: 20:15)
  regExp_replace: /[年月日]/gm, // 日時に含まれる、「年,月,日」を「/」に置換する
  regExp_LessonName: /B\w{2,3}\s*\w{2,4}\s*\d{1,2}/,
  regExp_InstructorName : /インストラクター：\s*(.+)/,
  regExp_BikeNo : /バイクナンバー：\s*(\w+)/,
  regExp_StudioName : /店舗\s*：\s*((.*)（(\w*)）)[\s|　]/
}

var CalendarName = "feelcycle"; // 登録するGoogleカレンダーの名称
var GmailLabelName = "feelcycle"; // feelcycleのメールを仕分けたラベル名
var PopupReminderBeforeMinutes = 60; // リマインダーの分設定

function main(){
  createEventFromGmail()
}

function createEventFromGmail() {

  // feelcycleのラベルが付いたメールスレッドを取得
  var threads = GmailApp.getUserLabelByName(GmailLabelName).getThreads();

  // それぞれのスレッドに関して
  Logger.log("threads.length : " + threads.length);
  for (var i = 0,thread; i<threads.length; i++) { 
    thread = threads[i];

    // 含まれるメッセージを取り出し、
    var messages = thread.getMessages();
    Logger.log("messages.length : " + messages.length);
        
    for(var j = 0,message; j<messages.length; j++){
      var message = messages[j]
      
      if(message.isInTrash()){
        continue;
      }
      
      // メッセージのタイトルにKeywordが含まれていた場合は
      if(message.getSubject().indexOf("ご予約")>0){
      
        // 本文を取り出して、
        var body = message.getBody();

        // 設定したパターンにマッチする日時を探して、
        var regExp_date = RegExpPattern.regExp_date;
        var regExp_time = RegExpPattern.regExp_time;
        var regExp_replace = RegExpPattern.regExp_replace;
        var regExp_LessonName = RegExpPattern.regExp_LessonName;
        var regExp_InstructorName = RegExpPattern.regExp_InstructorName;
        var regExp_BikeNo = RegExpPattern.regExp_BikeNo;
        var regExp_StudioName = RegExpPattern.regExp_StudioName;
        
        var date = body.match(regExp_date);
        var time = body.match(regExp_time); 
        var LessonName = body.match(regExp_LessonName)[0];
        var InstructorName = body.match(regExp_InstructorName)[1]
        var BikeNo = body.match(regExp_BikeNo)[1]
        var StudioNameJE = body.match(regExp_StudioName)[1];
        var StudioNameJ = body.match(regExp_StudioName)[2];
        var StudioNameE = body.match(regExp_StudioName)[3];


        // イベント開始時刻
        var from = new Date(date[0].replace(regExp_replace,'/')+" "+time[0])        
        // イベント終了時刻 = 開始時刻 + レッスン時間
        var to = new Date(+from + 45*60*1000);
        
        // 追加したいCalendarNameという名前のカレンダーを取得し、
        var myCalendar = CalendarApp.getCalendarsByName(CalendarName)[0];

        // ちゃんと存在したら
        if(myCalendar){
          var EventName = LessonName + "@" + InstructorName + "(" + BikeNo + ")";
//          var EventName = LessonName + "@" + StudioNameE + "-" + InstructorName + "(" + BikeNo + ")";
          // 同じ時刻に、同じイベント名で登録されているイベントを探してみて、
          var existingEvents = myCalendar.getEvents(from, to, {search: EventName})

          // 登録確認メールの場合
          if(message.getSubject().indexOf("登録")>0){
            // なかったらイベントを作成する
            if(existingEvents.length == 0){            
              event = myCalendar.createEvent(EventName, from,to, {description: body});
              event.addPopupReminder(PopupReminderBeforeMinutes);
              Logger.log(EventName + ": 登録しました");              
            } else {
              Logger.log(EventName + ": イベント登録済みです");
            }          
          // キャンセル確認メールの場合で
          }else if(message.getSubject().indexOf("キャンセル")>0){
            // イベント登録済みなら削除する
            if(existingEvents.length == 1){            
              existingEvents[0].deleteEvent();
              Logger.log(EventName + ": 削除しました");              
            } else {
              Logger.log(EventName + ": イベント削除済みです");
            }          
          }

        }else{       
          Logger.log("カレンダーが見つかりませんでした: " + CalendarName);
        }
      }
      message.moveToTrash();
    }
  }
}
```