はじめに
部署やグループ全体のスケジュール調整にはGoogleカレンダーを利用するのが便利ですが、複数のカレンダーを同時に確認するのは手間がかかります。
そこで、GoogleカレンダーAPIを使用して複数人分のスケジュールを取得する方法を紹介します。この処理は主にAWS Lambdaを使用して実装しました。
1. GCPでサービスアカウントを用意
まず最初に、GoogleカレンダーAPIを利用するためには、Google Cloudのプロジェクトを作成し、サービスアカウントを設定する必要があります。
このサービスアカウントにドメイン全体の委任を行い、/auth/calendar.readonly
といったスコープを設定します。※ワークスペースの管理者権限が必要
このサービスアカウントのサービス アカウント キーやWorkload Identity 連携を利用しサービスアカウントの権限でAPIを叩きます。
2. 予定を取得するLambda関数
次に、実際に予定を取得する処理をAWS Lambdaで実装します。
実行者のメールアドレスをcredentialのsubjectに指定することにより、実行者から見える予定をすべて取得することができるようになります。
import boto3
import googleapiclient.discovery
from google.oauth2 import service_account
MYEMAIL="example1@email.com" # 実行者のメールアドレス
EMAILS=["example1@email.com,example2@email.com,example3@email.com"] # 予定を取得したいアカウントのリスト
# AWS Lambdaで使用するための設定。ここではサービスアカウントキーを使用する方法を取っている。
BUCKET = 'your-bucket-name'
KEY = 'path-to/your-key.json'
SCOPES = ['https://www.googleapis.com/auth/calendar.readonly']
# GoogleAPIのクレデンシャル情報の取得
s3 = boto3.client('s3')
key_data = json.loads(s3.get_object(Bucket=BUCKET, Key=KEY).read().decode('utf-8'))
credentials = service_account.Credentials.from_service_account_info(key_data, scopes=SCOPES)
delegated_credentials = credentials.with_subject(post_data[MYEMAIL])
# Google CalendarのAPIクライアントの作成
calendar = googleapiclient.discovery.build('calendar', 'v3', credentials=delegated_credentials)
全ての予定を取得する処理本体は時間がかかるため、人毎に非同期で行っています。
# 予定を取得する関数
# start_date_string,end_date_stringは予定を検索する範囲
async def get_busy_times(calendar, EMAILS, start_date_string, end_date_string):
tasks = {email: fetch_events_for_user(calendar, email, start_date_string, end_date_string) for email in EMAILS}
finished_tasks = await asyncio.gather(*tasks.values())
all_busy_times = {email: task for email, task in zip(tasks.keys(), finished_tasks)}
return all_busy_times
async def fetch_events_for_user(calendar, email, start_date_string, end_date_string):
busy_times = []
page_token = None
while True:
events_response = calendar.events().list(
calendarId=email,
timeMin=start_date_string,
timeMax=end_date_string,
singleEvents=True,
orderBy='startTime',
pageToken=page_token
).execute()
events = events_response.get('items', [])
busy_times.extend(events)
page_token = events_response.get('nextPageToken')
if not page_token:
break
return busy_times
まとめ
今回、GoogleカレンダーAPIを使用して複数のユーザーのスケジュール取得する方法を紹介しました。
この方法を使えば、複数の人の予定を比較して、共通の空き時間を見つけることができます。Slackなどと連携すれば、社内のだれでも利用できる便利ツールにすることも可能です。
もっと効率的な方法もあるかもしれませんが、この記事が少しでもスケジュール調整のお役に立てれば幸いです。