Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

PHP、GoogleCalendarAPIで特定の日時の予定が埋まっているかチェック

More than 3 years have passed since last update.

自分が運営しているハウススタジオの空き状況をGoogleカレンダーで管理しています。
予約入った際に自動でGoogleカレンダーに予定が入っているかチェック、予定が無ければ新規の予定を入れる、という処理を実装しました。

新規で予定を入れる、という部分は記事があったのでそれを参考にしました。
Laravel と Google カレンダーを自動で同期
ただ、特定の日時に予定が入っているかどうかチェックする方法が無かったので、ソースコードを掘ってみたりして実装したのでここにメモしておきます。

手順

1.Google Calendar API を使って読み込み、書き込み、削除ができるよう設定する

手順1については先ほども紹介したこちらの記事を参照ください。
Laravel と Google カレンダーを自動で同期

2.Google Calendar APIを使って予定チェックの実装をする

実装

GoogleCalendarクラスを作り、その中でGoogleCalendarAPIを使った実装をしています。
カレンダーがGoogleカレンダーから別のカレンダーに移行する可能性も鑑みてCalendarInterfaceを実装する形にしています。

なお、予定有無のチェックにはFreebusyというAPIを使います。

use Asobiba\Domain\Models\Calendar\CalendarInterface;
use Google_Client;
use Google_Service_Calendar;
use Google_Service_Calendar_FreeBusyRequest;

class GoogleCalendar implements CalendarInterface
{

    private $client;
    private $service;
    private $calendarId;
    private $freebusyReq;

    public function __construct()
    {
        //先ほど紹介した記事を参考に共通で必要な準備部分をコンストラクタで行なっている
        $key_path = storage_path('json/google_api_secret_key.json');//指定ファイルへのフルパス
        putenv('GOOGLE_APPLICATION_CREDENTIALS='. $key_path);//カレントリクエスト実行時のみの環境変数を設定
        $this->client = new Google_Client();//クライアント作成
        $this->client->useApplicationDefaultCredentials();
        $this->client->addScope(Google_Service_Calendar::CALENDAR);//https://www.googleapis.com/auth/calendar
        $this->service = new \Google_Service_Calendar($this->client);
        $this->calendarId = env('GOOGLE_CALENDAR_ID');

    }


    public function isBusy(string $startDateTime,string $endDateTime): bool
    {
        //freebusy用のリクエスト作成(このパラメータはリファレンスに記載されているパラメータ
        //Google_Service_Calendar_FreeBusyRequestの基底クラスである、Google_Collectionの基底クラスであるGoogle_Modelのコンストラクタで、引数に与えられたパラメータをプロパティに設定しているっぽい
        $this->freebusyReq = new Google_Service_Calendar_FreeBusyRequest(
            [
                'timeMin' => $startDateTime,//ISO8601日付 (2004-02-12T15:19:21+00:00)
                'timeMax' => $endDateTime,
                'timeZone' => 'Asia/Tokyo',
                'items' => [
                    ['id' => $this->calendarId]
                ]
            ]
        );

        //Google_Service_Calendar_FreeBusyResponseが$resultに入る
        $result = $this->service->freebusy->query($this->freebusyReq);

        //Google_Service_Calendar_FreeBusyResponseのgetCalendars()メソッドでGoogle_Service_Calendar_FreeBusyCalendarの配列が取得できる。
     //Google_Service_Calendar_FreeBusyCalendarのキーに自分のカレンダーIDを指定する
    //getBusy()メソッドでbusyの値を取得できる。busyが空の配列([])だったら予定無し
        if($result->getCalendars()[$this->calendarId]->getBusy() === []){
            return false;
        }
        return true;
    }
}

busyの値を取得して予定有無を判定する部分がもう少しスマートに出来そうですが、とりあえずこれで出来ました。

Google_Service_Calendar_FreeBusyRequestのパラーメータを設定する時にクラス内のプロパティを探したのですが見当たらず少し迷いましたが、基底クラスを辿っていくことで理解することが出来ました。
ソース見るの大事だなって改めて思いました。

以上。

Yorinton
NetFlix、Hulu、U-next、T-verを経てAmazonプライムに流れ着く。3度の飯より好きなものは特に無いけど、3度の飯時には必ずと言っていいほどアニメを嗜む。PHP、JS、TS、Vue.js、Laravel、少しだけGo. 開発責任者.
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away