Pythonスクリプトで、文章から予定を抽出、自動でからGoogle カレンダーに予定登録なんてできたらおもしろいですよね!
今回はGoogle Calender APIを使用して、PythonからGoogle カレンダーを操作する方法についてまとめました。
Google のAPIは使用までの事前準備がけっこう大変なんですよね。
めんどうな準備はしたくないという方のために、Google のチュートリアルを応用して最速で準備する方法も紹介します。
事前準備
前準備として、次の3つを行う必要があります。
①認証用JSONファイルの用意
②必要なモジュールインストール
③Google APIへのアクセストークン要求
④カレンダー操作用インスタンス作成
③と④は、Pythonスクリプトで定型文のようなものを書けばOKです。
大変なのは①の認証用JSONファイル作成です。
①認証用JSONファイルの用意
今回はGoogleのチュートリアルを使用して、最速で準備します。
まず次のGoogle Calender API Quickstartにアクセスします。
Enable the Google Calendar APIをクリックします。
しばらくすると、次のポップアップが出ます。
DONLOAD CLIENT CONFIGURATIONをクリックして、認証用JSONファイルをダウンロードします。
簡単にJSONファイルが作成されました。
Pythonスクリプト内で、この認証情報をGoolgleに渡して、APIへのアクセストークンを取得します。
JSONファイル、Client ID・Secretは…
①人に渡さない!
②安全な場所に保管する!
というのを忘れずに!上の図でもしっかり塗りつぶしています!
また、本格的にGoogle Cloud Platformでプロジェクトを作成して、認証用JSONファイルを用意したい方は次の過去記事を参考にしてみてください。
②必要なモジュールインストール
Google Calendar APIを使用するため必要なモジュールは次の3点です。
①google-api-python-client
②google-auth-httplib2
③google-auth-oauthlib
Anaconda を使用している方は、conda-forgeからインストールできます。
新たに仮想環境を作成する場合(NAMEは作りたい仮想環境の名前):
今の環境にインストールする場合:
conda-forgeからのインストールについて詳しく知りたい方はこちら!
仮想環境って?という方は、次の記事で理解が深まるかと思います。
③Google APIへのアクセストークン要求
スクリプトを書く前に、先ほどダウンロードした認証用JSONファイルをプロジェクトのフォルダに移動しておきます。
PyCharmならドラッグアンドドロップで移動できます。
ここからやっとPythonスクリプトを書きます。
初めはアクセストークン要求用の定型文です。
こちらは、Python Quickstart | Calendar API | Google Developersのスクリプトを読み書き可に変更したものです。
# 必要なモジュールをインポート
import pickle
import os.path
import datetime
from googleapiclient.discovery import build from google_autoauthlib.flow import InstalledAppFlow from google.auth.transport.requests import Request
# カレンダーAPIで操作できる範囲を設定(今回は読み書き) SCOPES = ['https://www.googleapis.com/auth/calendar']
# Google にcalendarへのアクセストークンを要求してcredsに格納します。 creds = None
# 有効なトークンをすでに持っているかチェック(2回目以降の実行時に認証を省略するため) if os.path.exists('token.pickle'): with open('token.pickle', 'rb') as token: creds = pickle.load(token) # 期限切れのトークンを持っているかチェック(認証を省略するため)
if not creds or not creds.valid: if creds and creds.expired and creds.refrestoken: creds.refresh(Request()) # アクセストークンを要求
else: flow = InstalledAppFlow.from_client_secrets_file( 'credentials.json', SCOPES) creds = flow.run_local_server(port=0) # アクセストークン保存(2回目以降の実行時に認証を省略するため) with open('token.pickle', 'wb') as token: pickle.dump(creds, token)
アクセストークンを初めて要求する場合、ブラウザが立ち上がります。
Google アカウントでログインして認証します。
ログインするとこうなります(ビックリ!!!)
Google の verification process に従って安全性を確認していないために表示されるそうです。
今回は、自分用のプログラムなので強行突破します(自己責任でお願いします)。
詳細を表示して、安全ではないページに移動します。
再度ログインすると、権限付与の画面が出るので許可します。
続いて似たような画面がでますが、許可しておきます。
最後に次の文章が表示されれば認証完了です!
アクセストークン取得のフローについては、次の記事で詳しく解説しています。
③カレンダー操作用インスタンス作成
# カレンダーAPI操作に必要なインスタンス作成
service = build('calendar', 'v3', credentials=creds)
このserviceを利用して、予定を読み書きします。
予定読み込み
次のスクリプトで現在から10件の予定を取得してみます。
# 現在時刻を取得 now = datetime.datetime.utcnow().isoformat() + 'Z' # 'Z' indicates UTC time # カレンダーから予定を取得 events_result = service.events().list(calendarId='primary', timeMin=now, maxResults=10, singleEvents=True, orderBy='startTime').execute() events = events_result.get('items', []) # 予定がない場合には、Not found 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'])
実行結果はこちらです。
予定作成
辞書型で予定を準備します。
・タイトル:summary→文字列
・開始時刻:start→文字列(ISOフォーマットの時刻)
・終了時刻:end→文字列(ISOフォーマットの時刻)
ISOフォーマットの時刻は、datetime.isoformat()を使用すると楽です。
body = { # 予定のタイトル 'summary': 'Pythonの本を読む', # 予定の開始時刻 'start': { 'dateTime': datetime.datetime(2020, 2, 6, 10, 30).isoformat(), 'timeZone': 'Japan' }, # 予定の終了時刻 'end': { 'dateTime': datetime.datetime(2020, 2, 6, 12, 00).isoformat(), 'timeZone': 'Japan' }, }
次のスクリプトで書き込みます。
event = service.events().insert(calendarId='primary', body=body).execute()
実行結果はこちらです。
応用例
今回は予定作成、読み込みの方法に関してご紹介しました。
ここまでできれば他のスクリプトと組み合わせて、もっとおもしろいことができます!
例えば、文章から予定を抽出して、自動で予定作成なんてできたらおもしろいですよね!
①クリップボードの値を取得→pyperclip
②スケジュール名と時間を取得→正規表現
③Googleカレンダーに登録→Google API
pythonでクリップボードを操作できるPyperclipと組み合わせれば、かなり強力なツールになると思います。
このへんはまたの機会に!
もっと本格的に設定したい人は?
本格的にGoogle Cloud Platformでプロジェクトを作成して、認証用JSONファイルを用意したい方は次の過去記事を参考にしてみてください。
Google APIに関する書籍は少ないのですが、次の本のChapter11にも解説がありました。