DjangoでGoogle Calendarへアクセス①
こんなことがしたかった
- CreateViewでDBにデータがInsertされたときに、Google Calendarにもイベントを登録したかった
厳密にはもう少し複雑ではあるのだが、Djangoで作った予定管理アプリのようなものに予定を追加したときに、Google Calendarにも同期したかったのである。
最終的には双方向で同期するようにしたいのではあるが、とりあえずはDjangoアプリ→Google Calendarの方。
こんな感じ
前提として、Google Cloud ConsoleからGoogle Calendar APIを有効化し、サービスアカウントを作成しておく。
かつ、そのサービスアカウントにGoogle Calendarの予定の変更権限を渡しておく。
また、pipで必要な以下のライブラリも入れておく。
プログラムは以下。※動かなかったらごめんなさい
- Views.py
import requests import json import os.path import httplib2 from django.conf import settings from googleapiclient.discovery import build from oauth2client.service_account import ServiceAccountCredentials from google.auth.transport.requests import Request from app.forms import Form from app.models import Model class CreateView(CreateView): model = Model form_class = Form template_name = 'create.html' def form_valid(self, form): obj = form.save(commit=False) # Google Calendarに追加する予定のデータを作成 gcal_ctx={ 'summary':'タイトル', 'start':{ 'dateTime':予定の開始日時, 'timeZone':'UTC' }, 'end':{ 'dateTime':予定の終了日時, 'timeZone':'UTC' }, } # Google Calendarに予定データを渡してInsert、返り値のeventidを格納 gcal_eventid = self.insertgcal(gcal_ctx) # Google CalendarのイベントIDを記録 obj.gcal_eventid = gcal_eventid obj.save() return redirect('処理完了画面') # Google CalendarにInsertする関数 def insertgcal(self, body): # 認証情報を作成 credentials = ServiceAccountCredentials.from_json_keyfile_name( settings.GCAL_PRIVATE_KEY_PATH, scopes=settings.GCAL_SCOPES ) http = credentials.authorize(httplib2.Http()) service = build('calendar', 'v3', http=http) event = service.events().insert(calendarId=settings.GCAL_CALENDAR_ID, body=body).execute() # idを返してDBにidを入れる return event.get("id")
- settings.py
〜前略〜 # GCAL GCAL_PRIVATE_KEY_PATH = 'サービスアカウントのjson' GCAL_SCOPES = ['https://www.googleapis.com/auth/calendar'] GCAL_CALENDAR_ID = 'Google CalendarのID'
- その他 アプリケーションのルートに「サービスアカウントのjson」ファイルを配置しておくこと。
ようするに、InsertしたデータからGoogle Calendarのイベントを作り、認証をとおして、Google側が準備した「service.events().insert」を使ってカレンダー側にも反映させるのであった。
また、Google Calendar側のIDを取得しておき、Django側にも持たせておかないと、Google Calendar→Django側の取得のときに面倒なことになるので、そういった処理も入れている。
実装してみて
実装自体はそれほど難しくなかったのだが、Google APIの認証がちょっと厄介だった。
最初はブラウザでの認証が必要な別の方式でやっていたが、サーバに載せたときにサービスアカウント方式でないと詰まることがわかり急遽認証方式を変更したのが主なトラブル。
何に使うにしても汎用性は高そうな気もする。
参考文献
個人のGoogleカレンダーの予定をPythonで取得する | ヤマムギ
オフィスへの来訪申請をGoogleカレンダーと連携させて自動化してみたよ|Holidayおでかけラボ|note
【Python】Google Calendar APIを使ってGoogle Calendarの予定を取得・追加する | 無次元日記