0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Grafanaのダッシュボード上にGoogle Calendarを表示する

0
Last updated at Posted at 2025-03-15

概要

Grafanaのダッシュボード上に、Google Calendar上の予定を表示する方法です。
以下を利用します。

GCalJSON は安全な場所にホスティングする必要があります。

in a nutshell

動作イメージ

GrafanaのダッシュボードにBusiness Calendar Pluginを利用してGoogle Calendarの予定が表示されている様子

上記は月表示の例です。
Business Calendar Plugin は日・週・平日・年の表示や、予定のリスト表示が可能です。

構成図

構成図は以下の通りです。

GCalJSONが、Google Calendar API への認証、応答のキャッシュ、データの変換を行います。
Google Calendar API へのリクエストはサービスアカウントで行い、認証情報は環境変数で与えます。

無理やり図にすると、以下の通りです。

対象となる利用者のイメージ

  • Grafana を独自にホスティングして運用している
  • Google Calendar を Grafana のダッシュボード上に表示したい

構成図のとおり、Grafana Cloud を利用するユーザーは念頭にありません。
ただ、良い感じに読み替えていただければ、なんとかなるとは思います。

GCalJSON は、Google Calendar APIのサービスアカウントを利用して、カレンダー情報を応答するAPIです。
つまり、GCalJSON のエンドポイントは無認証でカレンダー情報を応答します。
エンドポイントは安全な場所にホスティングするか、隠し通す必要があります。あるいは、公開してもいいカレンダーのみに限定しましょう。

私の場合は、LAN 内の Raspberry Pi に docker compose で一緒にデプロイしています。
WANからLANを受け付けていない状態、また、念の為、対象のカレンダーには個人情報を書かない状態で運用しています。

設定準備

Google Calendar API をリクエストするサービスアカウントの作成

Google Calendar APIを有効にしたプロジェクトで、サービスアカウントを発行し、クレデンシャルを取得します。

  • Google Cloud Consoleにアクセスしてください。
  • 新しいプロジェクトを作成します。既存のプロジェクトがあれば、それを選択してもOKです。
  • Google Calendar API を有効にしてください。
  • APIとサービス > 認証情報 から、新しいサービスアカウントを作成してください。
  • 鍵を作成し、JSON 形式でダウンロードしてください。

詳しくは、以下のドキュメントが参考になるかもしれません。

ダウンロードした鍵ファイル(JSON)は後ほど使いますので、大切に保管してください。

また、発行したサービスアカウントのメールアドレス <サービスアカウント名>@XXXXXX.iam.gserviceaccount.com をメモしておいてください。
Google Cloud Console 上でも確認できますし、ダウンロードした鍵ファイルの client_email フィールドにも記載されています。

Google Calendar の設定

Google Calendarを開いてください。
Grafanaで表示したいカレンダーの設定画面を開きます。

Google Calendar の 設定と共有メニュー

「カレンダーの統合」部分に、カレンダーIDが表示されていますので、メモしておいてください。

Google Calendar 設定の「カレンダーの統合」に表示されたカレンダーID

次に、先ほど発行したサービスアカウントに、このカレンダーの読み取り権限を付与します。
「共有する相手」部分の「ユーザーやグループを追加」ボタンを押下します。
先ほどメモしておいたサービスアカウントのメールアドレス <サービスアカウント名>@XXXXXX.iam.gserviceaccount.com を入力します。
権限は、予定の詳細参照権限である「予定の表示(すべての予定の詳細)」を指定してください。

Google Calendar の共有先にサービスアカウントのメールアドレスを設定する

GCalJSON の設定と起動

GCalJSONには、3つの設定値を環境変数で渡すことができます。

  • GCALJSON_GOOGLE_CREDENTIAL : カレンダー情報を取得するサービスアカウントの鍵(Base64符号化したもの)2
  • GCALJSON_GOOGLE_CALENDAR_ID : 表示したいカレンダーID
  • GCALJSON_CACHE_DURATION : キャッシュ時間の設定

GCALJSON_GOOGLE_CREDENTIAL

まず、先程ダウンロードした鍵ファイル(JSON)をBase64符号化します。

base64 -w 0 credentials.json

Macであれば、こんな感じでクリップボードにコピーできます。

base64 -w 0 -i ~/Downloads/XXXXXXX.json | pbcopy

.envファイルに、以下のように記載してください。

GCALJSON_GOOGLE_CREDENTIAL='Base64符号化した鍵'

GCALJSON_GOOGLE_CALENDAR_ID

カレンダーの設定画面で、「カレンダーの統合」部分からコピーしたカレンダーIDを、記載してください。

.envファイルに、以下のように追記してください。

GCALJSON_GOOGLE_CALENDAR_ID='XXXXXXXXX@group.calendar.google.com'

GCALJSON_CACHE_DURATION (任意)

指定しない場合、5分キャッシュとなります。

例えば、1分キャッシュにしたい場合は、以下のように設定してください。
.envファイルに、以下のように追記してください。

GCALJSON_CACHE_DURATION='1m'

docker compose での設定と起動

https://github.com/watahari/GCalJSON/tree/main/sampleを参照するほうが分かりやすいかもしれません。

GCalJSONの設定

docker-compose.yaml を作成します。

version: "3"
services:
  gcaljson:
    image: watahari/gcaljson
    ports:
      - "8080:8080"
    environment:
      - GCALJSON_GOOGLE_CREDENTIAL=${GCALJSON_GOOGLE_CREDENTIAL}
      - GCALJSON_GOOGLE_CALENDAR_ID=${GCALJSON_GOOGLE_CALENDAR_ID}
      - GCALJSON_CACHE_DURATION=${GCALJSON_CACHE_DURATION}

docker compose up -d でコンテナを起動してください。
http://localhost:8080/eventsで、カレンダーの予定イベントが取得できているはずです。

$ docker compose up -d
$ curl "http://localhost:8080/events"
[{"title":"予定のタイトル","start":"2025-02-02T11:00:00+09:00","end":"2025-02-02T14:00:00+09:00"},...中略...]
$ curl -s "http://localhost:8080/events" | jq . | head -15
[
  {
    "title": "予定のタイトル ほげほげ",
    "start": "2025-02-02T11:00:00+09:00",
    "end": "2025-02-02T14:00:00+09:00"
  },
  {
    "title": "予定のタイトル ふがふが",
    "start": "2025-02-05",
    "end": "2025-02-06"
  },
  {
    "title": "予定のタイトル ぴよぴよ",
    "start": "2025-02-06",
    "end": "2025-02-16"
$ docker compose down

Grafana の設定 (データソースを設定ファイルから Provisioning する)

既に、Grafana の docker-compose.yaml は書いてある前提で、話を進めます。

Grafana に Infinity data source plugin for Grafanaと、Business Calendar Plugin (marcusolsson-calendar-panel)をインストールする必要があります。
以下のように、GF_INSTALL_PLUGINS にプラグイン名を渡してください。

services:
  grafana:
    image: grafana/grafana
    environment:
      - GF_INSTALL_PLUGINS=yesoreyeram-infinity-datasource,marcusolsson-calendar-panel

次に、DataSourceとして、以下のように設定してください。

apiVersion: 1

datasources:
  - name: GCalJSON
    type: yesoreyeram-infinity-datasource
    url: http://gcaljson:8080/events

先ほどの docker-compose.yaml への記載によって、gcaljson という名前のコンテナが 8080 番ポートで受け付けています。
urlには、その /eventsエンドポイントを指定します。

(補足) Grafana 設定をWebUIで実施する場合

データソースを設定ファイルから Provisioning していない場合、つまり、GrafanaのWebUIからデータソースを設定している場合は、以下のように設定してください。

  • Grafana にログインし、Data Source 追加画面を開いてください。
  • "+ Add new data source" から、Infinity のデータソースを作成します。
  • Infinify データソースの Settings > URL, Headers & Params から、以下のように設定してください。

Grafana Infinity データソースに GCalJSON のエンドポイントを設定する

Base URL には、GCalJSONのエンドポイントを指定します。urlには、その /eventsエンドポイントを指定します。
先述の GCalJSONの設定 の通りにdocker-compose.yaml を記載してGCalJSONを記載しているのであれば、Base URLは http://gcaljson:8080/eventsとなります。

Grafanaダッシュボードを編集し、カレンダーを表示する

Business Calendar 公式ドキュメントを読むことを推奨します。

カレンダーを追加したい Grafana ダッシュボードを開き、編集モードに入ってください。
ビジュアライゼーションを追加し、Business Calendar を指定してください。

Business Calendar を追加する

以下の通りに設定します。

  • Table View を ON にする
  • Data Sourceに、GCalJSONを参照しているInfinity PluginのData Sourceを指定する
  • この状態で refresh すると、カレンダーの予定が表形式として表示されることが確認できるはず
  • Business Calendarの右メニュー設定で、Data を以下のように設定する
    • Start time : start カラムを指定する
    • End time : end カラムを指定する
    • Text : title カラムを指定する

以下の画像も参考にしてください。

Grafana Business Calendar に GCalJSON のカラムを設定する

Table View を OFF にすると、カレンダー形式で表示されているはずです。

Grafana Business Calendar に GCalJSON を設定した様子

この構成の利点

GCalJSON は、以下の3つの役割を持っています。

  • Google Cloud サービスアカウントの OAuth 2.0 認証を行なう
  • Google Calendar API をリクエストし、Business Calendar Plugin が扱いやすい JSON に変換して応答する
  • キャッシュした応答を提供する(デフォルトでは5分キャッシュ)

それぞれについて、GCalJSON を利用する利点を示します。

(1) 認証について

Infinity plugin でも OAuth 2.0 認証を通すことができます。3
しかし、GCalJSON を利用することで、認証のためのクレデンシャルを環境変数に隠蔽することができます。

Grafana Cloud を利用している場合や、Provisioning ではなく、手動設定とデータベース上での保存で良い場合には、この利点は関係ありません。

逆に言えば、Grafana のインスタンスを独自で起動して運用する場合、特にデータソースを設定ファイルから Provisioning したい場合は、どうやってクレデンシャルを隠蔽して構成管理を行なうかが重要です。
GCalJSON は、環境変数 GCALJSON_GOOGLE_CREDENTIAL に、Google Cloud サービスアカウントのクレデンシャル JSON を base64 化して渡すことができます。よって、構成管理で扱う秘密情報を環境変数に閉じ込めることができます。

(2) Google Calendar API のイベント情報について

Infinity Pluginで OAuth 2.0 認証を通し、Business Calendar Plugin で、直接 Google Calendar の Events: list API 4 をリクエストすることもできます。

しかし、その場合は以下の部分で工夫が必要です。

  • リクエストパラメータ timeMintimeMax を良い感じに絞る必要があります
    • Business Calendar の表示に合わせて対象の期間を指定する?どうやって?
    • テキトーに現在時刻のプラスマイナス1ヶ月程度に指定する?どうやって?
  • レスポンス items の中身を扱いやすいように変換する必要があります
    • 軽く試した感じだと、 Parsing options & Result fieldsRows/Rootitems を指定すればなんとかなりそうに思えました。
    • しかし、各イベントの startend には、date という日付のみが入った項目がある場合と、dateTime という日時が入った項目がある場合がありそうです。
    • Business Calendar は start と end にそれぞれ一つの項目のみを指定するため、難しそうです。
    • 終日イベントのみの場合は、Parsing options & Result fieldsColumns で、 start.date as start などとすればなんとかなりそうでした。
    • 終日イベントと時刻指定イベントが混在する場合は、、、どうやって・・・?

GCalJSON は、以下のように情報が整形されているため、簡単に Business Calendar の設定が可能です。

curl -s "http://XXXXX:8082/events" | jq . | head
[
  {
    "title": "時刻指定の予定",
    "start": "2025-02-01T11:00:00+09:00",
    "end": "2025-02-01T14:00:00+09:00"
  },
  {
    "title": "終日の予定",
    "start": "2025-02-05",
    "end": "2025-02-06"

(3) APIのリクエストリミット対策 (キャッシュ)

Google Calendar API のリクエスト制限については、以下のURLに記載があります。

https://developers.google.com/calendar/api/guides/quota

  • 2025年03月現在、追加料金なしで利用可能です。
  • 1分あたりの利用可能枠があるようですが、詳細は公開されていません。(噂によれば 5rps/user のようです。5
  • 枠を超えた場合、 403429 が応答されます。

よほどのことが無ければ、今回のような用途ではキャッシュは必要がないように思えます。
しかし、ダッシュボードを常時表示して自動更新させている場合や、複数ユーザがダッシュボードを表示する場合には注意が必要です。

そもそもカレンダーをよほど頻繁に更新しているのでも無い限り、ある程度のキャッシュを効かせてしまえば、余計なことを考える必要がなくなります。
GCalJSON はデフォルトで 5分のキャッシュを保持します。
なお、 GCALJSON_CACHE_DURATION でキャッシュ時間設定を変更することができます。

まとめ

Grafanaのダッシュボード上に、Google Calendar上の予定を表示する方法を紹介しました。
Google Calendar API、GCalJSON、Grafana、Grafana Infinity data source plugin、Grafana Business Calendar plugin によって実現しました。

私は、家庭内のスケジュール可視化に利用しています。6
応用例としては、オンコールスケジュールやプロジェクト計画などでの利用も考えられるかと思います。

以上、ご参考まで。

  1. GCalJsonは私が提供しているので、OSS公開しているものの、この記事が我田引水であることに注意してください。

  2. 環境変数でのJSON受け渡しが面倒なので、Base64符号化してプレーンテキストとして扱っています

  3. Google Calendar API を、Infinity Plugin でOAuth 2.0 認証を通して利用したい場合、Settings > Authenticationで 以下のように設定します。
    Auth type: OAuth2
    Auth details > Grant Type: JWT
    Auth details > Email: クレデンシャルJSONの client_email を設定する
    Auth details > Private Key: クレデンシャルJSONの private_key を設定する
    Auth details > Token URL: クレデンシャルJSONの token_uri を設定する
    Auth details > Scopes: https://developers.google.com/calendar/api/auth?hl=ja を参考に設定する
    Allowed hosts: https://www.googleapis.com/

  4. https://developers.google.com/calendar/api/v3/reference/events/list

  5. https://qiita.com/naka_kyon/items/56c3073aefafdc26b9a2

  6. https://github.com/watahari/myHomeAutomation/

0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?