GCP で Google Calendar を CalDAV サーバに複製する
概要
Python バッチスクリプトで Google Calendar からスケジュール情報を採取し、CalDAV サーバへ複製する例を紹介します。
- GSuite 上の任意のユーザの Calendar に、Google Calendar API を介してアクセスする
- GCP の Cloud Functions にデプロイした Pythonバッチスクリプトを、Cloud Scheduler + Pub/Sub で定時実行する
- APIアクセス認証をGCPのサービスアカウントキーで行い、個々のカレンダーオーナーからのアクセス許可は不要とする
サンプルコード
構成
グレーは環境設定、ブルーはバッチ処理です。
1. GSuiteでAPIアクセスを許可する
アクセス対象としたいカレンダーが存在する GSuite 環境に対して、外部からのAPIアクセスを受付可能に設定をします。公式ドキュメントの、管理コンソールで API アクセスを有効にする 手順になります。
APIリファレンスを有効にする
APIアクセスを有効にする
2. GCPにサービスアカウントを作成しキーを得る
今回は サービスアカウントキー
を用いた認証ストラテジで Calendar API を利用します。なお、サービスアカウントではなくパーソナルなアカウントの認証ストラテジでAPIを利用する方式もありますが、当記事では対象外です。認証ストラテジの選択肢と差の解説は、こちらの公式ドキュメントが分かりよいと思います。
IAMと管理
> サービスアカウント
でサービスアカウントを作成します。
サービスアカウントの鍵を生成し、JSON形式で取得します。鍵は、バッチスクリプトがAPIアクセス認証時に使います。
サービスアカウントのクライアントIDを確認します。クライアントIDは、バッチスクリプトの認証情報および、GSuiteのAPIクライアントアクセス許可対象として使います。
3. GSuiteでAPIクライアントアクセスを許可する
GSuite で、どのリソースに対するAPIアクセス操作を、誰に許可するかを設定します。設定手順は、OAuth: API クライアント アクセスの管理 になります。
設定内容は、クライアント名
には先にGCP上で作成したサービスアカウントの クライアントID
を指定し、
スコープ
には https://www.googleapis.com/auth/calendar.readonly
, https://www.googleapis.com/auth/calendar.events.readonly
を指定して承認します。
余談ですが、指定可能なスコープとAPIの仕様は APIリファレンス に書かれています。
4. CalDAV サーバを立てる
当サンプルでは、CalDAV サーバである Radicale に、Google Calendar から採取した情報を吐き出して、ユーザに利用させます。試験版のRadicaleは dockerコンテナ で立てるのが手っ取り早いです。
起動するとこんな感じです。サーバのURLがアプリに与える環境変数の CALDAV_SERVER_URL
、 ログイン情報が CALDAV_SERVER_USER
, CALDAV_SERVER_PASS
です。
ログインすると、即カレンダーの作成画面になりますので、こんな感じで作ります。Titleがカレンダー名であり、アプリに与える環境変数の CALDAV_SERVER_CALENDAR_NAME
です。
作成したカレンダーのURLは、http://${HOSTNAME}:5232/${USERNAME}/${CALENDAR_ID}/
になり、環境変数 CALDAV_SERVER_URL
に相当します。
- 余談
5. GCP上にバッチ処理を設置する
Pub/Subの作成
トピックを作成し、トピックの名前を確認しておきます。
作成したトピックに対する、Pullタイプのサブスクリプションを作成します。サブスクライバとなるCloudFunction宛のメッセージングを定義する事に相当します。
Cloud Scheduleの登録
先ほど作成したPub/Subトピックをターゲットとするスケジュールを作成します。スケジュールが、Pub/Subに対するパブリッシャとなる事に相当します。
作成したら、試しにジョブを実行して Publish メッセージングが成功する事を確認しておきます。
Pythonスクリプトのデプロイ準備をする
Cloud Storageに、非公開バケット function-codes
を1つ作ります。
次に、スクリプトの credentials.json
を、先の手順で取得したサービスアカウントのJSON形式の鍵に差し替えて、Pipfile
, Pipfile.lock
, main.py
および、差し替え後の credential.json
を1つのZipファイル gcalendar-fetcher.zip
に圧縮し、先に作成したCloud Storageのバケットにアップロードします。
PythonスクリプトをFunctionsにデプロイする
バケット内のZipファイル gcalendar-fetcher.zip
をソースとする関数を定義します。トリガーには、Pub/Sub に作成したトピック test-getting-gcal-events
トピックを指定します。実行する関数には main関数 を指定します。
また、環境変数は こちらに定義した変数 を与えます。
6. 実行して結果を確認してみる
Cloud Scheduler に作成したタスクが実行済の場合は結果欄に「成功」が出ていると思います。まだスケジュールが走っていない場合は、実行ボタンを押下し発火させた結果を同様に確認します。
また、Function にデプロイしたスクリプトが、Pub/Sub メッセージングを介して実行されていることも確認します。
いずれも成功なら、CalDAVサーバに登録されたはずのカレンダー情報を閲覧してみます。radicale から ical をダウンロードして中身を確認してみましょう。icalフォーマットのデータが得られます。
BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//PYVOBJECT//NONSGML Version 1//EN
X-WR-CALDESC;VALUE=TEXT:test
X-WR-CALNAME;VALUE=TEXT:test
BEGIN:VEVENT
UID:[email protected]
DTSTART:20190913T013000Z
DTEND:20190913T084500Z
DTSTAMP:20190726T050838Z
LAST-MODIFIED:20190726T050856Z
STATUS:CONFIRMED
SUMMARY:展示会にいく
TRANSP:OPAQUE
URL:https://www.google.com/calendar/event?eid=XXXXXXXXXXXXXXXXXXXXXXXX
END:VEVENT
BEGIN:VEVENT
UID:[email protected]
DTSTART:20191004T040000Z
...
END:VEVENT
END:VCALENDAR
ThunderbirdのLightning拡張でネットワークカレンダーとして見る方法もあります。
環境変数 CALDAV_SERVER_URL
に与えたURLが、ネットワークカレンダーの場所に相当します。
よく採れてます、使えそうですね。
空き時間調整くんとか、あなた会議長杉くんとかを作ってみるつもりです。
追記
生のクレデンシャルファイルをデプロイソースに含めて保管しておくのが怖いので、クレデンシャルを暗号化して取り扱うコード修正を加えてみました。Before/After形式の続き記事の体裁で書いたのでどうぞ。
Author And Source
この問題について(GCP で Google Calendar を CalDAV サーバに複製する), 我々は、より多くの情報をここで見つけました https://qiita.com/coleyon/items/44e278f96ac1a4868f7a著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .