Google カレンダーに予定をpythonで追加する

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

を実行すれば
無事に予定が追加される

とりあえず予定の追加はできたので
次に予定の取得をする
まずは今週の予定から

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です