📅

Google CalendarのスケジュールをGoogle Sheetへ入出力

2022/06/26に公開

はじめに

  • Google Calendar と Google Spread Sheet で入出力
  • アロー関数式の練習
  • Logger.logじゃなくてconsole.log使ったばあいの差異

Apps Script

サービス

Google APIでCalendarを追加しています。

シートの状態

出力用

カレンダーに入れたスケジュールを書き出すためのシート

入力用

カレンダーに追加したいスケジュールを記載します。
全日で登録する前提にしています。
スケジュールに時間まで含める場合はJSONを変更すれば可能です。

を目的に書いています。

const CALENDAR_ID = "xxxxx"
const MILLIS_PER_DAY = 1000 * 60 * 60 * 24;
const INPUT_SHEET_NAME = "カレンダーデータ"
const OUTPUT_SHEET_NAME = "出力用"

const outSheet = () =>{  
  let startDate = new Date();
  let endDate = new Date(startDate.getTime() + MILLIS_PER_DAY * 7)
  let events = getCalenderEvent(CALENDAR_ID,startDate,endDate)
  const book = SpreadsheetApp.getActiveSpreadsheet()
  const sheet = book.getSheetByName(OUTPUT_SHEET_NAME)

  // console.log(`イべント数:${events.length}`)
  let data = parseCalendarData(events)
  // console.log(`${data.length},${data[0].length},${data[0]}`)
  sheet.clear()//シートを初期化
  if (data == null ||  data.length == 0){
    return
  }
  sheet.getRange(1, 1, data.length, data[0].length).setValues(data)
}

//一行目のデータはフィールド名なので除外する
const filterCalendarData = (data) => {
  return data.filter((d, index) => {
    return index > 0
  })
}

const entryCalendarData = () => {
  let data = filterCalendarData(getSheetData(INPUT_SHEET_NAME))
  let entry = parseSheetData(data)
  for (i in entry){
    let result = Calendar.Events.insert(entry[i],CALENDAR_ID)
    console.log(result)
    //連続でAPIをリクエストしすぎないようにwaitをかけます
    Utilities.sleep(1000)
  }
}

//シートからデータを全部取得する
const getSheetData = (name) => {
  const book = SpreadsheetApp.getActiveSpreadsheet()
  const sheet = book.getSheetByName(name)
  return sheet.getDataRange().getValues()
}

//CalendarDataからGoogleSheet用のデータに変換
const parseCalendarData = filtered => {
  return filtered.map(d => {
    return [d.start.date,d.end.date,d.summary]
  })
}

//GoogleSheet用のデータからCalendarに登録する用のJSONデータに変換
//'date'を'dateTime'にしてtoISOString()で登録すると?
const parseSheetData = filtered => {
  return filtered.map(d => {
    return {
      start: {
      'date':`${Utilities.formatDate(d[0],'Asia/Tokyo','yyyy-MM-dd')}`,
      'timeZone':'Asia/Tokyo'
      },
      end: {
      'date':`${Utilities.formatDate(d[1],'Asia/Tokyo','yyyy-MM-dd')}`,
      'timeZone':'Asia/Tokyo'
      },
      summary: d[2],
    }
  })
}

//https://developers.google.com/calendar/api/v3/reference/events/list
//https://stackoverflow.com/questions/32918350/how-can-i-retrieve-an-extended-property-for-a-google-calendar-event
//maxResultsを1に変更すればpageTokenの動作の確認ができます
const getCalenderEvent = (calendarID,startDate,endDate) => {
  let data = []
  let param = {
    timeMin: startDate.toISOString(),
    timeMax: endDate.toISOString(),
    singleEvents: true,
    orderBy: 'startTime',
    maxResults: 200,
    pageToken: null
  }
  do {
    let events = Calendar.Events.list(calendarID,param)
    if (events.items && events.items.length > 0){
      Array.prototype.push.apply(data,events.items)
    }
    param.pageToken = events.nextPageToken
    //連続でAPIをリクエストしすぎないようにwaitをかけます
    Utilities.sleep(1000)
  } while(param.pageToken)
  
  return data
}

//削除用も用意しておく
//https://developers.google.com/calendar/api/v3/reference/events/delete#examples
const deleteCalendarEvent = () =>{
  let startDate = new Date();
  let endDate = new Date(startDate.getTime() + MILLIS_PER_DAY * 7)
  let events = getCalenderEvent(CALENDAR_ID,startDate,endDate)
  _deleteCalendarEvent(events)
}

const _deleteCalendarEvent = (data) => {
  for(let i in data){
    Calendar.Events.remove(CALENDAR_ID,data[i].id)
    //連続でAPIをリクエストしすぎないようにwaitをかけます
    Utilities.sleep(1000)
}
}

最後に

カレンダーイベントを削除するときのメソッドがremoveって・・・deleteとややこしい

参考にしたサイト

https://developers.google.com/apps-script/reference/calendar/calendar
https://developers.google.com/calendar/api/v3/reference/events/list
https://zenn.dev/offers/articles/20220616-google-app-script-technique
https://stackoverflow.com/questions/32918350/how-can-i-retrieve-an-extended-property-for-a-google-calendar-event

Discussion