Mokerの徒然日記2.0

技術系のことをつらつらと。情報に責任は負いません。

Google Calendar APIをPythonから扱う

技術関連備忘録シリーズ第2弾。今回はPythonからgoogle calendar apiを扱う編です。普通に公式チュートリアルやってみたよ、というお話。

今回の目標

例の目覚まし制作シリーズの一環で、本日のスケジュールを読み上げてもらいたいのでgoogle calendar apiを使ってみようと思います。

公式チュートリアル

基本は公式ドキュメント(Python Quickstart  |  Calendar API  |  Google Developers)を参照。
API自体は既にアクティベートしてあったので、そこはスキップ。
ライブラリは今回pyenv内に作成。近いうちにpipenvも試してみたいですね。
実行したら普通に動きました。あまりに問題なく動いたので書くこと無し。 チュートリアルプログラム自体も読めばわかります。ただpickleってライブラリだけは調べました(PythonのPickleモジュールを理解したいだけの人生だった - Qiita)。

自作class

尺伸ばしじゃないけど、あまりに書くことないので自作class書いときます。上で書いた目覚ましで使う、特定の日付のスケジュールリストを取得するやつです。どうせあとで拡張する予定もないので適当なコードですが許してください。

from datetime import datetime, date, time
from pytz import timezone
import pickle
import os.path
from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request


class GoogleApiTest:
    def __init__(self):
        self.calendarIdList = ['xxxxx@xxxxxx', 'xxxx@xxxx']     # TODO: setterつくる
        self.jst = timezone('Asia/Tokyo')

    def login(self):
        creds = None
        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.refresh_token:
                creds.refresh(Request())
                print("[Info]Credential Refreshed.")
            else: 
                flow = InstalledAppFlow.from_client_secrets_file('credentials.json', ['https://www.googleapis.com/auth/calendar.readonly'])
                creds = flow.run_local_server()
            with open('token.pickle', 'wb') as token:
                pickle.dump(creds, token)
        
        self.creds = creds
    

    def logout(self):
        pass
        # TODO : pickleファイル消去、creds=None


    def get_schedule(self, schedule_date):
        service = build('calendar', 'v3', credentials=self.creds)
        begin_time = datetime.combine(schedule_date, time(0, 0))
        begin_time = self.jst.localize(begin_time)
        finish_time = datetime.combine(schedule_date, time(23,59,59))
        finish_time = self.jst.localize(finish_time)

        result = []
        for calendarId in self.calendarIdList:
            events_result = service.events().list(calendarId=calendarId, timeMin=begin_time.isoformat(), timeMax=finish_time.isoformat()).execute()
            events = events_result.get('items', [])
            for e in events:
                result.append(e.get('summary', 'タイトル無し'))
        
        return result