ども!久しぶりに金曜日もお家で、ブログを執筆している龍ちゃんです。突然ですが、Google Calendar使っていますか?僕は入社してから、いろいろな予定をGoogle Calendarで管理するようになりました。ほぼ、TODOリスト化しています。手動で管理するのもいいんですが、システム化できそうと思っちゃったので検証したのでその報告になります。 今回は、Google Apps Script(GAS)を使ってGoogle Calendarに予定の登録・取得についてまとめました。ドキュメントは充実していましたが、例がなんとも言えない感じだったのでGoogle Calendarヘビーユーザーの皆さんに代わってソースコードを用意したので、コピペして動かしながら試してください。 事前準備 検証を進めていくにあたっての準備なので、ソースを知りたい方は読み飛ばしていただいて大丈夫です。 新しいGoogle Calendarを用意する うっかり、「メインのカレンダーの予定を消してしまった!」なんてことにならないように、検証用の新しいカレンダーを用意しておきましょう。 https://calendar.google.com/ にアクセスして、新しいカレンダーを作成しましょう。 今回は「GAS API Test」という名前のカレンダーを用意しました。次に、カレンダーの設定に入り「 カレンダーの統合>カレンダーID 」というIDを控えてください。 こちらのIDを用いてカレンダーにアクセスするので、この手順を覚えておきましょう。 共通設定:GASでGoogle Calndarにアクセス準備 まずは、GASエディタ上でGoogle Calndar APIへのサービス追加を行います。こちらを設定することでサジェスチョン機能が有効になります。 次に、カレンダーへのアクセス処理をグローバル変数として設置します。カレンダーへの参照はすべてのコードの前段として必要になります。先ほど事前準備で取得した カレンダーID を以下の xxxxx 部分に変更してください。 const calenarID = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" // カレンダーへの参照 const calendar = CalendarApp.getCalendarById(calenarID) JSのDate型で日付と時間を指定する 今回の内容で取り扱う、Date型セットを用意しました。 // 実行したタイミングの日付情報を取得する const date = new Date() Logger.log(date) // 年:月:日をそれぞれ取得する // 月も日も0からカウントされるため、実世界と合わせるためには+1する Logger.log(`${date.getFullYear()}:${date.getMonth()+1}:${date.getDate()+1}`) // 西暦で設定する date.setFullYear(2024) Logger.log(date) // 次の月に設定 date.setMonth(date.getMonth()+1) Logger.log(date) // 次の日に設定 date.setDate(date.getDate()+1) Logger.log(date) // 時間情報をセットする // 0時12分00秒 date.setHours(00, 12, 00) Logger.log(date) 取得:年・月・日 const date = new Date() Logger.log(date) // 年:月:日をそれぞれ取得する Logger.log(`${date.getFullYear()}:${date.getMonth()+1}:${date.getDate()}`) 月に関しては、 0 からカウントがスタートします。そのため、現実と合わせるためには月は +1 させることで現実と即した値になります。 情報設定(日付): setFullYear / setMonth / setDate const date = new Date() Logger.log(date) // 西暦で設定する date.setFullYear(2024) Logger.log(date) // 次の月に設定 date.setMonth(date.getMonth()+1) Logger.log(date) // 次の日に設定 date.setDate(date.getDate()+1) Logger.log(date) 月は情報は、 0 からカウントがスタートします。月情報が12月を超えて設定した場合は、年が +1 されます。日付情報が有効な日付の場合は設定され、超えた場合は月が +1 されます。 情報設定(時間情報): setHours const date = new Date() Logger.log(date) // 時間情報をセットする // .setHours(hours, min, sec) date.setHours(00, 12, 00) Logger.log(date) 時間情報設定する setHours の引数は3つあります。 パラメータ 説明 hours 時間を設定する(0~23):24以降では日付がプラスされる min 分を設定する(0~59) sec 秒を設定する(0~59) こちらの設定方法は、現実と即した形で設定することができます GASでGoogle Calendarを操作する よく使用する登録・取得の方法についてまとめていきます。コマンドの種類が豊富なので、用途別にまとめて行きます。公式リファレンスでオブジェクトの説明があるので開きながら見てもらえると良いですね。 説明 URL Google Calendarで扱えるオブジェクト https://developers.google.com/apps-script/reference/calendar/calendar?hl=ja Eventオブジェクト https://developers.google.com/apps-script/reference/calendar/calendar-event?hl=ja こちらで、カレンダーオブジェクトの取得が完了します。 単一の予定を追加する: createEvent ドキュメントとしては、 こちら になります。サンプルでは、実行した当日のカレンダーに対して、15:00~16:00の一時間で予定が追加されます。 const calenarID = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" const calendar = CalendarApp.getCalendarById(calenarID) const setEvent = () => { const startTime = new Date() startTime.setHours(15, 0, 0) const endTime = new Date() endTime.setHours(16, 0, 0) const options = { // description: "説明", // location:"自宅", // <guests:"example1@example.com>, example2@example.com", // sendInvites:false } const event = calendar.createEvent("title", startTime, endTime, options) } createEvents の引数は、4つです。それぞれ、以下を設定することができます。 名前 型 説明 title String イベントのタイトル:必須 startTime Date イベントの開始日時:必須 endTime Date イベントの終了日時:必須 options Object イベントの詳細設定:オプション options は名前の通り、設定しなくても動作します。optionsで設定できる値としては、以下のようになります。 名前 型 説明 description String イベントの説明 location String イベントの場所 guests String ゲストとして追加するメールアドレス(複数人の場合はカンマ区切り) sendInvites boolean 招待メールを送信するか(デフォルト:false) コメントアウトを外して実行すると、optionsで指定した内容のカレンダー予定が登録されます。 終日のイベントを追加する: createAllDayEvent ドキュメントとしては、 こちら になります。サンプルでは、終日(一日)・終日(二日)・終日(二日:詳細付き)の予定が3つ登録されます。 const calenarID = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" const calendar = CalendarApp.getCalendarById(calenarID) const setAllDayEvent = () => { const startTime = new Date() calendar.createAllDayEvent("test", startTime) // 終了日は含まれないため(予定を入れたい日+1)指定 const endTime = new Date() endTime.setDate(endTime.getDate() + 2) calendar.createAllDayEvent("test", startTime, endTime) const options = { description: "説明", location: "自宅", guests: "example1@example.com, example2@example.com", sendInvites: false } calendar.createAllDayEvent("test", startTime, endTime, options) } createAllDayEvent の引数は、4つです。 名前 型 説明 title String イベントのタイトル:必須 startTime Date イベントの開始日時(日付のみが参照される):必須 endTime Date イベントの終了日時(日付のみが参照され、終了日は範囲に含まれない):オプション options Object イベントの詳細設定:オプション optionsで設定することができる値は、以下になります。 名前 型 説明 description String イベントの説明 location String イベントの場所 guests String ゲストとして追加するメールアドレス(複数人の場合はカンマ区切り) sendInvites boolean 招待メールを送信するか(デフォルト:false) createAllDayEvent で気を付けたい点としては、 endTime を設定する場合です。終了日は含まれません。設定したい期間通りに設定できているかを注意深く確認する必要があります。 繰り返し単一の予定を追加する: createEventSeries それぞれ、単一・終日の登録を見てきました。それぞれのイベント形態を繰り返し登録することができる関数が createEventSeries ・ createAllDayEventSeries です。こちらのサンプルは createEventSeries です。サンプルでは、「一か月間、水曜日と木曜日の15:00~16:00に予定」が登録されます。 const calenarID = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" const calendar = CalendarApp.getCalendarById(calenarID) const setSeriesEvent = () => { const startTime = new Date() startTime.setHours(15, 0, 0) const endTime = new Date() endTime.setHours(16, 0, 0) const endScedule = new Date() endScedule.setMonth(endScedule.getMonth() + 1) const recurrence = CalendarApp.newRecurrence() .addWeeklyRule() .onlyOnWeekdays([CalendarApp.Weekday.THURSDAY, CalendarApp.Weekday.TUESDAY]) .until(endScedule) const options = { description: "説明", location:"自宅", guests:"example1@example.com, example2@example.com", sendInvites:false } calendar.createEventSeries("title", startTime, endTime, recurrence, options) } createEventSeries で登録することができる引数は5つです。 名前 型 説明 title String イベントのタイトル:必須 startTime Date イベントの開始日時(最初のイベント):必須 endTime Date イベントの終了日時(最初のイベント):必須 recurrence EventRecurrence 繰り返しのルール:必須 options Object イベントの詳細設定:オプション optionsの設定する値は、 createEvent と共通です。この関数で重要になるのは recurrence の設定項目です。指定することができるパラメーターとしては、 こちらにまとまっています 。 繰り返し終了条件を決定する方法として、繰り返し回数( .times(number) )と期間( .until(Date) )があります。これらを使用用途によって使い分けてください。 以下に汎用性が高い、繰り返しルールを記載しておきます。 特定曜日のみ繰り返すサンプル ホワイトリスト方式とブラックリスト方式のそれぞれの方式で記載します。 // 記載されている曜日を削除することで機能する:ホワイトリスト方式 // 週単位で、特定の曜日のみ繰り返す const sceduleRule = CalendarApp.newRecurrence() .addWeeklyRule() .onlyOnWeekdays([ CalendarApp.Weekday.SUNDAY, CalendarApp.Weekday.MONDAY, CalendarApp.Weekday.TUESDAY, CalendarApp.Weekday.WEDNESDAY, CalendarApp.Weekday.THURSDAY, CalendarApp.Weekday.FRIDAY, CalendarApp.Weekday.SATURDAY ]).times(10) // 除外したい曜日を記載することで機能する:ブラックリスト方式 // 毎日繰り返して、特定の曜日のみ除外する const sceduleRule = CalendarApp.newRecurrence() .addDailyRule() .addWeeklyExclusion() .onlyOnWeekdays([CalendarApp.Weekday.SUNDAY]) .times(10) 特定間隔(日ごと・隔週) 特定の間隔( .interval(number) )でルールを休眠させることができます。intervalでは前段に記載され//ているルールによって間隔を決定してくれます。 addWeeklyRule では休眠期間1週間、 addDailyRule では休眠期間1日間になります。 // interval(1)で1週間になる const sceduleRule = CalendarApp.newRecurrence().addWeeklyRule().interval(2).times(10); // interval(1)で1日間隔になる const sceduleRule = CalendarApp.newRecurrence().addDailyRule().interval(2).times(10); 第三水曜日のみ addMonthlyRule と onlyOnWeekday をこねくり回して実現できないか試してみたのですが、実装が完成しませんでした。有識者の方教えてもらえると助かります。 でも、ここまでくるとGUIか月初めにトリガーで動かすプログラムを組んだ方が良い気がしています。てか月に一回しかやらない系のイベントなら手で設定するほうが確実だよな? 特定の日付の予定を取得する: getEventsForDay ドキュメントとしては、 こちら になります。指定した日付の予定情報をすべて取得します。サンプルでは、「実行当日の予定をすべて取得し、イベント名とイベントの合計時間を取得」となります。 const calenarID = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" const calendar = CalendarApp.getCalendarById(calenarID) const getEventsForDay = () => { const startTime = new Date() const options = { // start: 0, // max: 10, // author: "", // search: "", // statusFilters: [ // CalendarApp.GuestStatus.OWNER, // CalendarApp.GuestStatus.INVITED, // CalendarApp.GuestStatus.YES, // CalendarApp.GuestStatus.MAYBE, // CalendarApp.GuestStatus.NO // ] } const events = calendar.getEventsForDay(startTime, options) // 各イベント情報をそれぞれ表示する events.forEach((event) => { console.log({ "id": event.getId(), "title": event.getTitle(), "time": (event.getEndTime() - event.getStartTime()) / 360 / 10000, "owner": event.isOwnedByMe(), "isAllDayEvent": event.isAllDayEvent(), "eventType": event.getEventType().toString(), "Mystatus": event.getMyStatus().toString() }) }) // イベントの合計時間を何時間表記で取得する const total = events.reduce((prev, event) => { const isAllDayEvent = event.isAllDayEvent() if (isAllDayEvent) { return prev } return prev + (event.getEndTime() - event.getStartTime()) / 360 / 10000 }, 0) Logger.log(total) } getEventsForDay の引数は2つになります。時間情報は参照されずに、年・月・日の情報のみ使用されます。 名前 型 説明 date Date イベント取得日時:必須 options Object イベントの詳細設定:オプション options情報としては、以下の情報を設定することができます。 名前 型 説明 start int 返答されるイベントのインデックス(何番目のイベントから取得するか) max int 返答されるイベントの最大数 author String イベント参加者のフィルタ(メールアドレス) search String フィルタリングに使用される全文検索クエリ statusFilters GuestStatus [] フィルタリングに使用されるステータスの配列(参加・未定・不参加 etc…) 特筆する点としては、 search ・ statusFilters[] になります。 search では、全文検索クエリとなっています。部分一致で検索することができます。Prefixなどを付けて予定を登録すると管理がしやすいですね。 statusFilters は、イベントに対するステータスで検索することができます。プロパティの説明は こちら にあります。カレンダー上で参加状況をちゃんと解答していれば、フィルターで情報を分析することができます。 こちらのサンプルでは、「招待されて参加したイベント・自分が発行したイベントの情報を取得して、合計時間を計算」となります。 const calenarID = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" const calendar = CalendarApp.getCalendarById(calenarID) const getEventsJoinTotalTime = () => { const startTime = new Date() const options = { statusFilters: [ CalendarApp.GuestStatus.OWNER, CalendarApp.GuestStatus.YES ] } const events = calendar.getEventsForDay(startTime, options) // イベントの合計時間を何時間表記で取得する const total = events.reduce((prev, event) => { // 終日イベントを除外する const isAllDayEvent = event.isAllDayEvent() if (isAllDayEvent) { return prev } return prev + (event.getEndTime() - event.getStartTime()) / 360 / 10000 }, 0) Logger.log(total) } 特定の期間の予定を取得する: getEvents ドキュメントとしては、 こちら になります。 getEventsForDay と使用感はほぼ一緒ですが、期間を明確に設定することができます。サンプルでは、「実行当日の8:00~18:30のイベントを取得」です。 const calenarID = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" const calendar = CalendarApp.getCalendarById(calenarID) const getEvents = () => { const startTime = new Date() startTime.setHours(8, 0, 0) const endTime = new Date() endTime.setHours(18, 30, 0) const events = calendar.getEvents(startTime, endTime) events.forEach((event) => { Logger.log({ "id": event.getId(), "title": event.getTitle(), "time": (event.getEndTime() - event.getStartTime()) / 360 / 10000, "owner": event.isOwnedByMe(), "isAllDayEvent": event.isAllDayEvent(), "eventType": event.getEventType().toString(), "Mystatus": event.getMyStatus().toString() }) }) } getEvents で設定できる引数は3つです。使用時に注意が必要なのは endTime です。こちらは、イベントの開始時間が、 endTime よりも速い場合はイベントがヒットします。 名前 型 説明 startTime Date イベントの開始日時:必須 endTime Date イベントの終了日時(イベントの開始時間が含まれる場合は検索に含む):必須 options Object イベントの詳細設定:オプション options で設定することができるのは、 getEventsForDay と同じになります。 終わり 今回は、GASでGoogle Calendarを操作する方法についてまとめました。こちらで紹介したコードと他の機能を組み合わせることで、Google Calendarを含めた自動化もできると思います。 今回紹介したコードを参考に、皆さんも自分なりのGoogle Calendar活用方法を見つけてみてください。もし、わからないことがあれば、コメント欄でお気軽に質問してくださいね。(第三水曜日を指定する方法がわかったらこっそり教えてください) それでは、また次回の記事でお会いしましょう! GAS関連ブログ 2024-02-01 GASで月初めにメールを送信する:祝日・土日対応 2023-09-04 Google Apps Script(GAS)でスプレッドシートを新規シート作成 ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post 【サンプルコード付き】GASでGoogle Calendarを操作する方法を徹底解説 first appeared on SIOS Tech. Lab .