Google カレンダーに予定をpythonで追加する
実行環境
M1 MacbookAir 16GB
APIなどの登録が必要になるので
[初心者向け] GoogleカレンダーにPythonから予定を追加・編集してみた
を参考に行う
https://developers.google.com/calendar/api/v3/reference/calendarList?hl=ja
がリファレンス
なお情報の取得も後で必要になるので
Googleカレンダー情報を取得する
も参考にする
まずは google カレンダーのAPIを有効にする
流れとしては
* 認証情報の発行
* 認証情報を使ってPythonのプログラムを実行
Google Cloudのコンソールにログイン
プロジェクトはすでに作成しているものを選択
APIとサービスをクリック
APIとサービスを有効にするをクリック
calendar
で検索する
なお日本語でカレンダーとしても出ないので注意
Google Calendar API をクリック
有効にするをクリック
これでOK
認証関連のJSONファイルは以前Gmailで作成してるので
今回もいずれGmailを使うので省略
mkdir week_calendar_voice
で作業ディレクトリを作成
ここに
cp ../mail_auto/*.json .
で以前作成したプロジェクトから
credentials.json
token.json
をコピーする
import os.path from google.oauth2.credentials import Credentials from google_auth_oauthlib.flow import InstalledAppFlow from google.auth.transport.requests import Request from googleapiclient.discovery import build # カレンダーAPIのスコープ(Google Calendarの読み書き権限) SCOPES = ['https://www.googleapis.com/auth/calendar'] # 既存の token.json を使用 creds = None if os.path.exists('token.json'): creds = Credentials.from_authorized_user_file('token.json', SCOPES) # トークンが無効またはスコープが一致しない場合は再認証 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) # トークンを保存 with open('token.json', 'w') as token: token.write(creds.to_json()) # Google Calendar APIサービスを構築 service = build('calendar', 'v3', credentials=creds) # イベントの詳細を設定 event = { 'summary': 'APIを使って追加したイベント', 'location': 'オンライン', 'description': 'Google Calendar APIで追加されたイベントです。', 'start': { 'dateTime': '2024-10-05T09:00:00', 'timeZone': 'Asia/Tokyo', }, 'end': { 'dateTime': '2024-10-05T10:00:00', 'timeZone': 'Asia/Tokyo', }, 'attendees': [ {'email': 'example@example.com'}, ], 'reminders': { 'useDefault': False, 'overrides': [ {'method': 'email', 'minutes': 24 * 60}, {'method': 'popup', 'minutes': 10}, ], }, } # カレンダーにイベントを挿入 event = service.events().insert(calendarId='primary', body=event).execute() print(f"イベントが作成されました: {event.get('htmlLink')}")
がchatgpt で生成されたコードだが
追加する予定は
# イベントの詳細を設定 event = { 'summary': 'APIを使って追加したイベント', 'location': 'オンライン', 'description': 'Google Calendar APIで追加されたイベントです。', 'start': { 'dateTime': '2024-10-05T09:00:00', 'timeZone': 'Asia/Tokyo', }, 'end': { 'dateTime': '2024-10-05T10:00:00', 'timeZone': 'Asia/Tokyo', }, 'attendees': [ {'email': 'example@example.com'}, ], 'reminders': { 'useDefault': False, 'overrides': [ {'method': 'email', 'minutes': 24 * 60}, {'method': 'popup', 'minutes': 10}, ], }, }
このうち
summaryがカレンダーに表示する予定
locationが場所で住所や会場名を指定することも可能
descriptionが詳細な説明
‘start’: イベントの開始時刻
‘end’: イベントの終了時刻
‘attendees’: 出席者のリスト 多分これは使わない
‘reminders’: リマインダーの設定 これも使わない
とりあえずテストなので
attendersと reminders を削除して予定を追加してみる
touch add_calendar.py
でファイルを作成
これで実行したら
Traceback (most recent call last): File "/Users/snowpool/aw10s/week_calendar_voice/add_calendar.py", line 18, in <module> creds.refresh(Request()) File "/Users/snowpool/.pyenv/versions/3.10.6/lib/python3.10/site-packages/google/oauth2/credentials.py", line 335, in refresh ) = reauth.refresh_grant( File "/Users/snowpool/.pyenv/versions/3.10.6/lib/python3.10/site-packages/google/oauth2/reauth.py", line 351, in refresh_grant _client._handle_error_response(response_data, retryable_error) File "/Users/snowpool/.pyenv/versions/3.10.6/lib/python3.10/site-packages/google/oauth2/_client.py", line 73, in _handle_error_response raise exceptions.RefreshError( google.auth.exceptions.RefreshError: ('invalid_scope: Bad Request', {'error': 'invalid_scope', 'error_description': 'Bad Request'})
これはgmailの許可はあるけど
Calendar のAPIのスコープがないのが原因
なので
一度 token.jsonを削除して再度実行したけどだめだった
これは認証関連の問題で
再度
rm token.json
で削除してから
import datetime import os.path from google.oauth2.credentials import Credentials from google_auth_oauthlib.flow import InstalledAppFlow from google.auth.transport.requests import Request from googleapiclient.discovery import build # スコープの設定 SCOPES = ['https://www.googleapis.com/auth/calendar'] # トークンファイルのチェック creds = None if os.path.exists('token.json'): creds = Credentials.from_authorized_user_file('token.json', SCOPES) # トークンがない場合、新しい認証を実行 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) # トークンを保存 with open('token.json', 'w') as token: token.write(creds.to_json())
を
touch test2.py
で作成して
python test2.py
を実行することで認証画面になるので
そのまま進めていけば認証が完了する
再度
python add_calendar.py
を実行すれば
無事に予定が追加される
とりあえず予定の追加はできたので
次に予定の取得をする
まずは今週の予定から