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
を実行すれば
無事に予定が追加される
とりあえず予定の追加はできたので
次に予定の取得をする
まずは今週の予定から