LaravelとGoogleカレンダーの連携
はじめに
GoogleカレンダーとLaravelを連携させることで、アプリケーションから直接Googleカレンダーへスケジュールを登録できるようになります
今回はGoogle Cloud ConsoleでのAPI有効化や認証情報の作成、Laravel側でのライブラリ導入やイベント登録処理まで、ステップごとに丁寧に解説しています
「とにかく手順通りに実装したい!」という方も進められる内容です
Google Cloud APIs設定
ここではLaravelからGoogle Calendar APIを安全かつ正しく利用するための準備を行っていきます。
Googleが提供するAPIにアクセスするには、認証情報(OAuthまたはサービスアカウント)とAPIの有効化が必要であり、これを行うのが本手順の目的です
この準備を完了することで、LaravelからGoogleカレンダーへイベントをプログラムで作成・操作できる状態になります
■Google Cloud APIsへアクセス→「コンソール」→「API APIとサービス」→「プロジェクト作成」
- 
プロジェクト作成


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

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

 - 
認証情報を作成

 - 
(1)認証情報の種類

 - 
(2)OAuth同意画面

 - 
(3)スコープ ※任意で選択ください
 - 
(4)OAuthクライアントID

上記を設定したら作成し、クライアント情報をダウンロード → 完了となります - 
サービスアカウントを作成します
「認証情報」→「サービスアカウント管理」→「サービスアカウント作成」へ


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

 - 
Grant this service account access to project

 - 
Grant users access to this service account(※スキップで省略可)
 - 
作成後

 
サービスアカウントと共有アカウントを連携
- 
作成したサービスアカウントのメールアドレスをコピー

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

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


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

 
Laravel連携に必要な情報の取得
- 
キー情報の設定とダウンロード
キー(秘密鍵)を作成後、ダウンロードします(後ほど使うため保管)
※キーのタイプはJSONを選択

 - 
共有ユーザーのカレンダー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含む) | 
- .envにカレンダーIDを設定します
 
GOOGLE_CALENDAR_ID=カレンダーID
- config/services.php
 
# 以下追加
'google' => [
   'calendar_id' => env('GOOGLE_CALENDAR_ID', ''),
],
- 
キーファイルを設置
storage/app配下に「google-calendar/credentials.json」を作成

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

 - 
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', '作成に失敗しました');
    }
}
- 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