📅

LaravelとGoogleカレンダーの連携

に公開

はじめに

GoogleカレンダーとLaravelを連携させることで、アプリケーションから直接Googleカレンダーへスケジュールを登録できるようになります
今回はGoogle Cloud ConsoleでのAPI有効化や認証情報の作成、Laravel側でのライブラリ導入やイベント登録処理まで、ステップごとに丁寧に解説しています

「とにかく手順通りに実装したい!」という方も進められる内容です

Google Cloud APIs設定

ここではLaravelからGoogle Calendar APIを安全かつ正しく利用するための準備を行っていきます。
Googleが提供するAPIにアクセスするには、認証情報(OAuthまたはサービスアカウント)とAPIの有効化が必要であり、これを行うのが本手順の目的です
この準備を完了することで、LaravelからGoogleカレンダーへイベントをプログラムで作成・操作できる状態になります

https://cloud.google.com/apis?hl=ja

■Google Cloud APIsへアクセス→「コンソール」→「API APIとサービス」→「プロジェクト作成」

  1. プロジェクト作成

  2. 作成したプロジェクトを選択して、APIを作成

  3. Google Calendar APIを選択し、次の画面で「有効」をクリック

  4. 認証情報を作成

  5. (1)認証情報の種類

  6. (2)OAuth同意画面

  7. (3)スコープ ※任意で選択ください

  8. (4)OAuthクライアントID

    上記を設定したら作成し、クライアント情報をダウンロード → 完了となります

  9. サービスアカウントを作成します
    「認証情報」→「サービスアカウント管理」→「サービスアカウント作成」へ

  10. サービスアカウントの詳細

  11. Grant this service account access to project

  12. Grant users access to this service account(※スキップで省略可)

  13. 作成後

サービスアカウントと共有アカウントを連携

  1. 作成したサービスアカウントのメールアドレスをコピー

  2. サービスアカウントを共有するユーザーに追加
    Goolgleカレンダーアプリへ移ります
    マイカレンダーから共有するユーザーアカウントの三点リーダーから「設定と共有」を選択

    「+ユーザーやグループを追加」で、コピーしたサービスアカウントのメールアドレスを追加します


    追加後、権限を「変更および共有の管理権限」へ変更

Laravel連携に必要な情報の取得

  1. キー情報の設定とダウンロード
    キー(秘密鍵)を作成後、ダウンロードします(後ほど使うため保管)
    ※キーのタイプはJSONを選択

  2. 共有ユーザーのカレンダーID取得
    Goolgleカレンダーアプリを開き、マイカレンダーから共有するアカウントの「設定と共有」をクリック。
    下に「カレンダーの統合」にカレンダーIDがあるのでコピー

Laravel側

アプリ側ではカレンダーの「タイトル」「説明文」「日付」の3つを用意して登録できるように準備します

Googleが提供している PHP用ライブラリをインストール

composer require google/apiclient

※google/apiclientは他のGoogleアプリとも連携できます

Google API 主な機能内容
Google Calendar API イベントの登録・取得・更新・削除
Google Drive API ファイルのアップロード・共有・ダウンロード
Google Sheets API スプレッドシートの読み書き
Gmail API メールの送受信・検索・ラベル操作
Google Analytics API アクセス解析レポートデータの取得(GA4含む)
  1. .envにカレンダーIDを設定します
GOOGLE_CALENDAR_ID=カレンダーID
  1. config/services.php
# 以下追加
'google' => [
   'calendar_id' => env('GOOGLE_CALENDAR_ID', ''),
],
  1. キーファイルを設置
    storage/app配下に「google-calendar/credentials.json」を作成

    ダウンロードしたキーファイルの中身を貼り付け

  2. Controller

public function store(Request $request): RedirectResponse
{
    try {
        $todoData = $request->substitutable();
        $this->todo->fill($todoData)->save();

        // Googleカレンダーにイベント作成
        $client = new Google_Client();
        $client->setAuthConfig(storage_path('app/google-calendar/credentials.json'));
        $client->addScope(Google_Service_Calendar::CALENDAR);

        $service = new Google_Service_Calendar($client);
        $startDateTime = Carbon::createFromFormat('Y-m-d\TH:i', $request->date, 'Asia/Tokyo');
        $endDateTime = $startDateTime->copy()->addHour();

        new Google_Service_Calendar_Event([
            'summary' => $request->title,
            'description' => $request->message,
            'start' => [
                'dateTime' => $startDateTime->toISOString(),
                'timeZone' => 'Asia/Tokyo',
            ],
            'end' => [
                'dateTime' => $endDateTime->toISOString(),
                'timeZone' => 'Asia/Tokyo',
            ],
        ]);

        return to_route('todos.index')->with('status', 'Todoとカレンダーイベントを作成しました');

    } catch (\Exception $e) {
        \Log::error('Todo作成エラー: ' . $e->getMessage());
        return back()->withInput()->with('error', '作成に失敗しました');
    }
}
  1. balade.php
<div class="grid grid-cols-1 gap-y-6 gap-x-4 sm:grid-cols-6">
    <div class="sm:col-span-4">
        <label for="title" class="block text-sm font-medium text-gray-700">
            タイトル<span class="text-red-500">*</span>
        </label>
        <div class="mt-1">
            <input type="text" name="title" id="title" required
                class="shadow-sm focus:ring-purple-500 focus:border-purple-500 block w-full sm:text-sm border-gray-300 rounded-md">
        </div>
    </div>

    <div class="sm:col-span-4">
        <label for="message" class="block text-sm font-medium text-gray-700">
            本文<span class="text-red-500">*</span>
        </label>
        <div class="mt-1">
            <textarea name="message" id="message" rows="4" required
                class="shadow-sm focus:ring-purple-500 focus:border-purple-500 block w-full sm:text-sm border-gray-300 rounded-md"></textarea>
        </div>
    </div>

    <div class="sm:col-span-4">
        <label for="date" class="block text-sm font-medium text-gray-700">
            イベント日付<span class="text-red-500">*</span>
        </label>
        <div class="mt-1">
            <input type="datetime-local" name="date" id="date" required
                class="shadow-sm focus:ring-purple-500 focus:border-purple-500 block w-full sm:text-sm border-gray-300 rounded-md">
        </div>
    </div>
</div>

Laravel側の設定は以上となります

アプリ側からカレンダー登録

最後にカレンダーを登録できるか確認します

「タイトル」「説明文」「日付」を送信すると、、、

Googleカレンダーへ追加されました🎉

プロジェクトの削除

不要になったプロジェクトを削除するとき、削除の場所が見つかりにくかったので、こちらも記載しておきます

■プロジェクトを選択し「ダッシュボード」→「プロジェクト設定に移動」→「シャットダウン」



まとめ

今回は、Google Cloud PlatformのAPI設定から始まり、Laravelアプリケーション上でGoogleカレンダーにイベント登録を行う手順までを解説しました

Googleカレンダーとの連携は、スケジューラーやタスク管理系のアプリケーションにおいてとても便利な機能です。また、Googleの各種API(Drive、Sheets、Gmailなど)とも共通の手順で連携が可能なため、今後拡張していく際の基盤としても活用できます

参考になれば幸いです

Discussion