0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

APIを使って、googleカレンダの予定を受け取る

0
Posted at

現在、知り合いのクソみたいな要件のアプリを開発中。アルゴ的には実現ハードルが高すぎるので、使えるものにはならないと思うが、勉強ついでに手伝っている。今回は、その一歩として、「Google Calendar APIを使って、自分のカレンダーの予定を取得する」 ところまでを実装する。備忘録として、その方法を記載する。

Google Cloud Platform (GCP) での準備

まずは、Googleと通信する事ができないと始まらないので、そこら辺の設定をする。どうやら、Google Cloud Platformというのを使えばできるらしい。

Google Cloud Platform

Google Cloud Platform (GCP) とは、Google が提供するクラウドコンピューティングのプラットフォームです。インターネット経由で、データストレージ、コンピュータリソース、ネットワーキング、ビッグデータ、AIツールなどを使うことができるサービスをまとめたものです。
初心者の方でも理解しやすいように言うと、GCPはあなたのビジネスやプロジェクトのために、必要なデジタル環境を整えるための道具箱のようなものです。例えば、ウェブサイトのホスティング、アプリのバックエンド、データの保存や解析など、さまざまな用途に使われます。
https://www.kiyono-co.jp/post/google-cloud-platform

初心者の僕にはよくわからん。まぁ、Google Cloudを使うためのPlatformなわけで、これを使うことで、Google Cloudがつかえるわけだ。

プロジェクトの作成

Google Cloud Console にアクセスする。左上のプロジェクト選択プルダウンから「あたらしいプロジェクト」を作成する(名前は適当でよい)。

スクリーンショット 2026-02-08 16.00.10.png

APIの有効化

プロジェクトを作ったら、次はAPIを有効化する必要がある。

「APIとサービス」 > 「ライブラリ」へ移動して、検索バーに Google Calendar API と入力。

Google Calendar APIを有効にする。

OAuth同意画面の設定

今回はお試しなので、appとかではなくて、ローカルPCで動かすものとして認証する。その前にOAuthとはなにか

OAuth

ユーザーはIDやパスワードを直接そのサービスに渡す必要はなく、かわりにGoogleやTwitterなど信頼できる提供元に一度だけ認証してもらい、その“証明書”を相手のサービスに提示することでアクセスが可能になります。これにより、複数のサービスで同じパスワードを入力するリスクを避けることができ、利便性と安全性を両立できるというわけです。
https://auth0.com/jp/intro-to-iam/what-is-oauth-2

あんまりよくわかってないが、ここらへんが概念的にはわかりやすい。要はユーザーがパスワードとかの認証をしなくても、ユーザが過去認証したことのある手段を中間的に用いて、ユーザの認証をスキップする事ができる。というふうに理解している。

「APIとサービス」 > 「OAuth同意画面」へ。

User Type は 「外部 (External)」 を選択して、アプリ名とメールアドレスを入力して保存。

テストユーザーの追加

これだけでは、現在アプリはテスト環境にあるらしく、テスト環境は一部の人間しか触ることができない。そのため、この一部の人間というのを登録する必要がある。

「APIとサービス」 > 「OAuth同意画面」 > 「対象」へ。

「テストユーザ」の欄で、自分のGoogleアカウント(Gmailアドレス)を追加する。これを忘れると Error 403: access_denied で弾かれます。

認証情報 (Credentials) の作成

「APIとサービス」 > 「認証情報」へ。

「認証情報を作成」 > 「OAuth クライアント ID」 を選択する。アプリケーションの種類は「デスクトップ アプリ」とする。

作成したら、JSONファイルをダウンロードというボタンを押して、JSONファイルをダウンロードする。ダウンロードされたものをcredentials.json という名前にリネームして、ローカルのプロジェクトフォルダに配置する。

Python環境の構築

実際にデータを受け取るプログラムを考える。言語としてはPythonを採用して、環境はuvで構築する。

# プロジェクト作成
mkdir project_name
cd project_name
uv init
# 必要なライブラリのインストール
uv add google-api-python-client google-auth-httplib2 google-auth-oauthlib

予定を取得するコード

実際に予定を受け取るコードを書いていく。と言ってもLLMに書いてもらったので、さして理解していない。どうやら、日付を引数にすることで、指定された期間の予定を取ってくる事ができるらしい。

import datetime
import json
import os.path
from google.auth.transport.requests import Request
from google.oauth2.credentials import Credentials
from google_auth_oauthlib.flow import InstalledAppFlow
from googleapiclient.discovery import build

# 読み取り専用スコープ(書き込みたい場合は .readonly を外す)
SCOPES = ['https://www.googleapis.com/auth/calendar.readonly']

def get_calendar_events(days=7):
    creds = None
    # 1. 以前の認証情報があればロード
    if os.path.exists('token.json'):
        creds = Credentials.from_authorized_user_file('token.json', SCOPES)
    
    # 2. 認証情報がない、または期限切れならログイン画面を出す
    if not creds or not creds.valid:
        if creds and creds.expired and creds.refresh_token:
            creds.refresh(Request())
        else:
            flow = InstalledAppFlow.from_client_secrets_file(
                'credentials.json', SCOPES)
            creds = flow.run_local_server(port=0)
        # 次回用に保存
        with open('token.json', 'w') as token:
            token.write(creds.to_json())

    # 3. APIクライアントの構築
    service = build('calendar', 'v3', credentials=creds)

    # 4. 取得範囲の設定(現在時刻〜指定日数後まで)
    now = datetime.datetime.utcnow()
    time_min = now.isoformat() + 'Z' 
    time_max = (now + datetime.timedelta(days=days)).isoformat() + 'Z'

    print(f"🔍 取得範囲: {time_min} 〜 {time_max}")

    # 5. データ取得実行
    events_result = service.events().list(
        calendarId='primary',
        timeMin=time_min,
        timeMax=time_max,
        singleEvents=True,
        orderBy='startTime'
    ).execute()

    events = events_result.get('items', [])

    # 6. 結果の表示
    if not events:
        print("予定はありません。")
    else:
        print(f"✅ {len(events)} 件の予定が見つかりました。\n")
        # 最初の1件だけ生データを表示してみる
        print(json.dumps(events[0], indent=2, ensure_ascii=False))

if __name__ == "__main__":
    get_calendar_events(days=7)

実行結果とデータの構造

実行するとブラウザが立ち上がり、Googleアカウントでのログインを求められます。許可すると、コンソールにデータが表示されます。

取得できた生データ(抜粋)

{
  "kind": "calendar#event",
  "id": "abcde12345...",
  "status": "confirmed",
  "summary": "朝ごはんを食べる",
  "description": "納豆・卵かけご飯",
  "start": {
    "dateTime": "2026-02-09T08:00:00+09:00",
    "timeZone": "Asia/Tokyo"
  },
  "end": {
    "dateTime": "2026-02-09T08:30:00+09:00",
    "timeZone": "Asia/Tokyo"
  }
}

それぞれのデータの意味

  • kind: データの種類。「calendar#event」はこれが「カレンダーの予定」であることを示す

  • etag : データが変更されたかを識別するためのタグ

  • id: この予定を特定するための固有ID

  • status: 予定の状態。confirmed は「確定済み(キャンセルされていない)」という意味

  • htmlLink: ブラウザでこの予定を開くためのURL

  • created: この予定が最初に作られた日時

  • updated: この予定が最後に更新された日時

  • summary: 予定のタイトル

  • description: メモ・詳細

  • creator: 予定を作成した人(メールアドレス)。self: true は自分自身であることを示します

  • organizer: 予定の主催者(カレンダーの所有者)

  • start: 開始日時

  • dateTime: 日時(日付と時刻)

  • timeZone: タイムゾーン

  • end: 終了日時

  • dateTime: 日時(日付と時刻)

  • iCalUID: 異なるカレンダーシステム間で連携するためのID

  • sequence: 変更回数

  • reminders: 通知設定。useDefault: true はカレンダーのデフォルト設定を使うという意味

  • eventType: 予定のタイプ。default は通常の予定

0
0
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
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?