自分が運営しているハウススタジオの空き状況を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
のパラーメータを設定する時にクラス内のプロパティを探したのですが見当たらず少し迷いましたが、基底クラスを辿っていくことで理解することが出来ました。
ソース見るの大事だなって改めて思いました。
以上。