GASでGoogleカレンダーに自動予約する

## はじめに

社用車の利用時にGoogleカレンダーで予約して、手書で台帳に記入していたため、手間と管理に苦労していました。
GASを使用して、スプレッドシートに必要事項を入力すると自動でカレンダーに予約されるようにしてみました。

## 手順

1.スプレッドシートに社用車予約シートと管理台帳を作成します。
![image (20).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1242838/4aa1c0e2-6bfd-fd0d-e17d-efe0a1ddebe0.png)
![image (19).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1242838/289776c8-a38f-9447-91b0-e6f5e35f6915.png)

2.拡張機能からApps Scriptを開いてコードを入力します。

▼社用車のカレンダーID、通知先、予約シートの定義
```JavaScript
// 社用車のカレンダーID
const car_id = '■■■■ @resource.calendar.google.com';

// 社用車予約シート取得
const sheet = SpreadsheetApp.getActiveSheet();
const allSheet = SpreadsheetApp.getActiveSpreadsheet();

// 通知したい人
const noticeTarget = ["user1@example.com, user2@example.com"];
```

▼メニューに実行ボタンの追加
```JavaScript
function onOpen()
{
  let ui = SpreadsheetApp.getUi()
  // メニュー名を決定
  let menu = ui.createMenu('GAS');
  // メニューに実行ボタン名と関数を割り当て
  menu.addItem('予約','main');
  // スプレッドシートに反映
  menu.addToUi();
}
```

▼メインメソッド
```JavaScript
function main()
{
  // 入力値を取得
  let valueList = getInput(sheet);
  if(!valueList){return}

  // 空き状況を確認
  if(!checkReserveCar(valueList)){return}
  // カレンダー予約
  entryCalendar(valueList);
  // 管理台帳更新
  insertList(valueList);
  // 入力シートリフレッシュ
  refreshInput();

  Browser.msgBox("予約が完了しました。");
}
```

▼入力情報の取得
```JavaScript
function getInput()
{
  let valueList = Array();

  // 利用者名取得
  let userAddress = sheet.getRange("B3").getValue();

  // 所属部署
  let userDepatment = sheet.getRange("B4").getValue();

  // 行先
  let goTo = sheet.getRange("B5").getValue();

  // 目的
  let detail = sheet.getRange("B6").getValue();

  // ETC
  let useETC = sheet.getRange("B7").getValue();

  // 使用開始日時
  let startDateTime = sheet.getRange("B8").getValue();

  // 使用終了日時
  let endDateTime = sheet.getRange("B9").getValue();

  // 入力チェック
  if(userAddress === "" || goTo === "" || detail === "" || useETC === "" || startDateTime === "" || endDateTime === "")
  {
    Browser.msgBox("必須項目が入力されていません");
    return false;
  }

  // 選択チェック
  if(useETC != "要" && useETC != "不要")
  {
    Browser.msgBox("ETC利用の選択が正しくありません。");
    return false;
  }

  // 同乗者
  let riding = Array();
  let ride1 = sheet.getRange("B10").getValue();
  riding.push(ride1);
  let ride2 = sheet.getRange("B11").getValue();
  riding.push(ride2);
  let ride3 = sheet.getRange("B12").getValue();
  riding.push(ride3);
  let ride4 = sheet.getRange("B13").getValue();
  riding.push(ride4);
  riding = riding.filter(Boolean);

  valueList.push(userAddress);   //0
  valueList.push(userDepatment); //1
  valueList.push(goTo);          //2
  valueList.push(detail);        //3
  valueList.push(useETC);        //4
  valueList.push(startDateTime); //5
  valueList.push(endDateTime);   //6
  valueList.push(riding);        //7

  return valueList;
}
```

▼社用車の空き状況の確認
```JavaScript
function checkReserveCar(valueList) {
  // カレンダー取得
  var roomCalender = CalendarApp.getCalendarById(car_id);
  let start = new Date(valueList[5]);
  let end = new Date(valueList[6]);

  // 日時を指定してイベント数を取得
  var events = roomCalender.getEvents(start, end);

  if(events.length != 0)
  {
    Browser.msgBox("既に予約が埋まっています。");
    return false;
  }

  return true;
}
```
▼カレンダーの予約
```JavaScript
function entryCalendar(valueList)
{
  // カレンダー取得
  const calendar = CalendarApp.getDefaultCalendar();
  const title = '社用車使用予定'
  const option = {
    description: 
      '行先：'+ valueList[2] +"\n"+
      '目的：'+ valueList[3] +"\n"+
      'ETC：'+ valueList[4] +"\n\n"+
      '使用後は以下のシートを入力してください。'+"\n"+
      '（管理台帳シートのURL）',
    guests: noticeTarget + "," + car_id+","+ valueList[7]
  }

  let start = new Date(valueList[5]);
  let end = new Date(valueList[6]);

  calendar.createEvent(title,start,end,option);
}
```
▼入力した内容を社用車管理台帳シートに反映
```JavaScript
function insertList(valueList)
{
  let inputSheet = allSheet.getSheetByName("社用車管理台帳");
  let inputLow = inputSheet.getLastRow() + 1;

  inputSheet.getRange("A" + inputLow).setValue(inputLow - 4);
  inputSheet.getRange("E" + inputLow).setValue(valueList[0]);
  inputSheet.getRange("F" + inputLow).setValue(valueList[1]);
  inputSheet.getRange("G" + inputLow).setValue(valueList[2]);
  inputSheet.getRange("H" + inputLow).setValue(valueList[3]);
  inputSheet.getRange("I" + inputLow).setValue(valueList[4]);
  inputSheet.getRange("J" + inputLow).setValue(valueList[5]);
  inputSheet.getRange("K" + inputLow).setValue(valueList[6]);
  inputSheet.getRange("L" + inputLow).setValue(valueList[7][0]);
  inputSheet.getRange("M" + inputLow).setValue(valueList[7][1]);
  inputSheet.getRange("N" + inputLow).setValue(valueList[7][2]);
  inputSheet.getRange("O" + inputLow).setValue(valueList[7][3]);
}
```

▼入力台帳をリフレッシュする
```JavaScript
function refreshInput()
{
  sheet.getRange("B3").clearContent();
  sheet.getRange("B4").clearContent();
  sheet.getRange("B5").clearContent();
  sheet.getRange("B6").clearContent();
  sheet.getRange("B7").clearContent();
  sheet.getRange("B8").clearContent();
  sheet.getRange("B9").clearContent();
  sheet.getRange("B10").clearContent();
  sheet.getRange("B11").clearContent();
  sheet.getRange("B12").clearContent();
  sheet.getRange("B13").clearContent();
}
```

3.コードを保存して予約シートに内容を入力し、メニューから「予約」を押下します。

▼結果
![image (18).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1242838/c96323e3-03e1-2ec0-e1d3-6ca8f575b965.png)



## おわりに
今回はGASを使用した例を紹介しました。
手書になる作業など、これは自動化してほしい！という作業がまだたくさんあると思いました。
GASを応用して、他にも自動化できる管理作業があれば、少しでも楽になるように色々試してみたいと思います！

共同開発者：@k-sato-ice