現在、Zoomの定期ミーティングを自動的に開始するソフトを作っています。ただRPAで開始するだけじゃつまらないので、Google Calendarから予定を取得し、その時刻の少し前にRPAを動かして定期ミーティングを開始するということを考えています。
今回は、Google Calendar APIを用いて、自分のカレンダーから予定を取得するところまでを作りました。
目次
1.Google Calendar APIを有効化する
1-1.Google Cloud Platformにアクセス
まずはGoogle Cloud Platformにアクセスします。
このような画面が出てきます。
複数のGoogleアカウントを持っている人は、どのアカウントを使うのかを決めて、そのアカウントでログインした状態にしてください。
1-2.新しいプロジェクトを作成する
先程のスクリーンショットにおいて、Google Cloud Platformの右にある”プロジェクトの選択”をプルダウンします。
そして、出てくるウィンドウの右上にある”新しいプロジェクトを作成”をクリックします。
プロジェクト名を入力して作成をクリックするとプロジェクトが作成されます。
ここでGoogle Cloud Platformのトップページに遷移するので、先程の”プロジェクトの選択”をクリックすると作成したプロジェクト一覧が出てきます。そこで先程作成したプロジェクトを選択してこの作業は終わりです。
1-3.APIの有効化
左上のハンバーガーアイコンからAPIとサービスをクリックします。そして、”APIとサービスの有効化”をクリックします。
APIライブラリにようこそと出てくるので、使いたいAPIを選択します。今回はGoogle Calendarから予定を取得したいので、Google Calendar APIを選択します。
”有効化”をクリックしてAPIを有効化します。
すると画面が遷移して、次のようになります。
APIを使用するには認証情報が必要らしいです。
1-4.認証情報の作成
“認証情報を作成”をクリックすると次のような画面になります。
今回はGoogle Calendar APIを使うので、プルダウンメニューからGoogle Calendar APIを選択します。
すると選択する項目が増えるので、次のように設定します。
UIを用いる場合などは適宜選択する項目を変更してください。
設定が終わったら、”必要な認証情報”をクリックして次の画面に遷移させます。
サービスアカウント名、ロールを選択します。キーのタイプはJSONのままにしておきます。
サービスアカウント名は何でもいいので、適当に設定します。
今回は個人開発なのでロールはプロジェクトオーナーにしておきます。
設定が終わったら”次へ”をクリックします。
すると、サービス アカウントとキーが作成されましたと出てくると同時にファイルのDLが始まります。秘密鍵ですので適切な場所に保管します。
1-5.OAuth 同意画面を構成
先程のページから認証情報の一覧のページに移動していると思います。
その時、一番上に「必ず、アプリケーションに関する情報を使用して OAuth 同意画面を構成してください。」と出てきているので、”同意画面を構成”をクリックします。
すると次のような画面になります。
User Typeの内部はG Suiteユーザでないと選択できないので、外部を選択して作成をクリックします。
次にアプリ登録の編集を行います。
こちらも適当に設定します。
“保存して次へ”をクリックすると、スコープの設定になります。今回は何も設定しなくてもいいので、何も設定せずに”保存して次へ”をクリックします。
テストユーザーでは、その名の通りテストユーザを設定します。ここで自分のGoogleアカウントを設定しておきます。
“ADD USERS”をクリックして、自分のgmailアドレスを入れて追加します。
最後に”保存して次へ”をクリックすると、OAuth 同意画面の構成は終了です。
1-6.OAuth 2.0 クライアント IDを作成
ダッシュボードに戻って、認証情報を選択して認証情報の一覧を表示させます。
今はサービスアカウントのみある状態ですので、OAuth 2.0 クライアント ID を作成します。
”認証情報を作成”をクリックして、OAuth クライアント IDを選択します。
そして表示される画面で次のように設定します。
作成をクリックすると、「OAuth クライアントを作成しました」と出ます。そして、先程の認証情報の一覧のOAuth 2.0 クライアント IDに先程作成されたクライアントIDが表示されます。
これでAPIを使う準備は終了です。
2.Googleカレンダーから予定を取得してみる
Quickstartに従います。
2-1.Step1:Google Calendar APIを有効化する
先程設定が終わったので飛ばします。
2-2.Google Client Libraryをインストールする
次のコマンドを入力します。
pip install --upgrade google-api-python-client google-auth-httplib2 google-auth-oauthlib
python3の場合はpip3コマンドのときもあるので、最初のpipをpip3に置き換えてください。
pip3 install --upgrade google-api-python-client google-auth-httplib2 google-auth-oauthlib
2-3.コードを作成する
1-4で作成したJSONファイルと同じディレクトリに新しいファイルであるquickstart.pyを作ります。また、JSONファイルの名前を”credentials.json”に変更しておいてください。
ファイルには次のようなコードを入力します。
from __future__ import print_function
import datetime
import pickle
import os.path
from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request
# If modifying these scopes, delete the file token.pickle.
SCOPES = ['https://www.googleapis.com/auth/calendar.readonly']
def main():
"""Shows basic usage of the Google Calendar API.
Prints the start and name of the next 10 events on the user's calendar.
"""
creds = None
# The file token.pickle stores the user's access and refresh tokens, and is
# created automatically when the authorization flow completes for the first
# time.
if os.path.exists('token.pickle'):
with open('token.pickle', 'rb') as token:
creds = pickle.load(token)
# If there are no (valid) credentials available, let the user log in.
if not creds or not creds.valid:
if creds and creds.expired and creds.refresh_token:
creds.refresh(Request())
else:
flow = InstalledAppFlow.from_client_secrets_file(
'credentials.json', SCOPES)
creds = flow.run_local_server(port=0)
# Save the credentials for the next run
with open('token.pickle', 'wb') as token:
pickle.dump(creds, token)
service = build('calendar', 'v3', credentials=creds)
# Call the Calendar API
now = datetime.datetime.utcnow().isoformat() + 'Z' # 'Z' indicates UTC time
print('Getting the upcoming 10 events')
events_result = service.events().list(calendarId='primary', timeMin=now,
maxResults=10, singleEvents=True,
orderBy='startTime').execute()
events = events_result.get('items', [])
if not events:
print('No upcoming events found.')
for event in events:
start = event['start'].get('dateTime', event['start'].get('date'))
print(start, event['summary'])
if __name__ == '__main__':
main()
2-4.コードを実行する
先程のquickstart.pyを実行します。
するとブラウザが開いてログインを求められます。このとき、ログインはテストユーザーで追加したGoogleアカウントにします。
最後に許可(Accept)をクリックしてこの作業は終わりです。この作業で開いたウィンドウやタブは閉じても構いません。
また、同時にquickstart.pyのあるディレクトリにtoken.pikleというファイルが作成されます。このファイルとダウンロードしたJSONファイルがあれば次回以降の認証がスキップされます。
2-5.実行結果を確認する
ターミナルなどを見てみると、「Getting the upcoming 10 events」と表示されて、次の行から予定が出力されていると思います。
エラーメッセージは出ていないが、予定を出力されない場合は、そもそもGoogleカレンダーに予定が登録されていないので、テストのために予定を登録しましょう。また、カレンダーを分けている場合、このquickstart.pyが取得してくるカレンダーはそのままだと一番最初から存在するカレンダーですので、次の部分を変更してください。
events_result = service.events().list(calendarId='calender ID', timeMin=now,
maxResults=10, singleEvents=True,
orderBy='startTime').execute()
calender IDと書かれた場所に、取得したいカレンダーのIDを置き換えてください。カレンダーIDの取得方法は次のとおりです。
- Googleカレンダーを開く
- マイカレンダー内の取得したいカレンダーにカーソルを合わせる
- カレンダー名の一番右に縦の三点リーダがあるので、それをクリック
- 設定を共有をクリック
- カレンダーの統合内のカレンダーIDをコピー
3.トラブルシューティング
3-1.ValueError: Client secrets must be for a web or installed app.
次のようなエラーメッセージが表示されます。
Traceback (most recent call last):
File "/Users/jago39/program/auto_zoom/auto_zoom/quickstart.py", line 59, in <module>
main()
File "/Users/jago39/program/auto_zoom/auto_zoom/quickstart.py", line 34, in main
flow = InstalledAppFlow.from_client_secrets_file(
File "/Users/jago39/.pyenv/versions/3.9.0/lib/python3.9/site-packages/google_auth_oauthlib/flow.py", line 206, in from_client_secrets_file
return cls.from_client_config(client_config, scopes=scopes, **kwargs)
File "/Users/jago39/.pyenv/versions/3.9.0/lib/python3.9/site-packages/google_auth_oauthlib/flow.py", line 164, in from_client_config
raise ValueError("Client secrets must be for a web or installed app.")
ValueError: Client secrets must be for a web or installed app.
認証情報が正しくない場合に発生しました。
解決方法は、OAuth 2.0 クライアント IDを作成することです。1-6を参考に設定してください。
3-2.”Request had insufficient authentication scopes.”
次のようなエラーメッセージが表示されます。
Getting the upcoming 10 events
Traceback (most recent call last):
File "/Users/jago39/program/auto_zoom/auto_zoom/quickstart.py", line 54, in <module>
main()
File "/Users/jago39/program/auto_zoom/auto_zoom/quickstart.py", line 41, in main
events_result = service.events().list(calendarId='primary', timeMin=now,
File "/Users/jago39/.pyenv/versions/3.9.0/lib/python3.9/site-packages/googleapiclient/_helpers.py", line 134, in positional_wrapper
return wrapped(*args, **kwargs)
File "/Users/jago39/.pyenv/versions/3.9.0/lib/python3.9/site-packages/googleapiclient/http.py", line 915, in execute
raise HttpError(resp, content, uri=self.uri)
googleapiclient.errors.HttpError: <HttpError 403 when requesting https://www.googleapis.com/calendar/v3/calendars/primary/events?timeMin=2021-02-02T11%3A06%3A13.012625Z&maxResults=10&singleEvents=true&orderBy=startTime&alt=json returned "Request had insufficient authentication scopes.". Details: "Request had insufficient authentication scopes.">
最初の認証時にブラウザが開き、ログインを求められるところでアクセスが拒否された場合です。
これはテストユーザに誰も設定していない、または追加したユーザ以外でログインしようとした場合に発生します。
OAuth 同意画面からテストユーザが正しく追加されているか、またテストユーザに追加したアカウントでログインを試みてください。
4.おわりに
わかってしまえばすぐにこの作業が終わります。しかし、ネット記事のスクリーンショットと今の設定項目がぜんぜん違うので時間がかかりました。
予定が取得できたので、次はRPAでロボを作成します。
。оО(。´•ㅅ•。)Оо。がんばっていこう・・・
5.参考文献
Google Calendarの予定をPython3から取得する
【Python】Google Calendar APIを使ってGoogle Calendarの予定を取得・追加する
[Google Calendar Insert API error “Insufficient Permission: Request had insufficien](