もがき系プログラマの日常

もがき系エンジニアの勉強したこと、日常のこと、気になっている技術、備忘録などを紹介するブログです。

phpでGoogleCalendarAPIを使って祝日の情報を取得する

はじめに

こんばんは。

もうコレ関連やるたびに毎回ググって時間かかっちゃうので、まとめときます。

GoogleのDeveloperサイトで、GoogleCalendarAPIのサービスの使用を許可しているのが前提です。

本題

1. 必要パッケージのインストール

以下を落としてきます。

packagist.org

composer require google/apiclient

2. 使用するクラス群

GoogleCalendarConfig.php

<?php


namespace Kojirock\Resource;

class GoogleCalendarConfig
{
    /**
     * @var string
     */
    private $authConfigPath;

    /**
     * @var string
     */
    private $calendarId;

    /**
     * GoogleCalendarConfig constructor.
     * @param array $configData
     */
    public function __construct(array $configData)
    {
        foreach ($this as $key => $val) {
            if (!isset($configData[$key])) {
                throw new \InvalidArgumentException("{$key} is property nothing");
            }
            $this->$key = $configData[$key];
        }
    }

    /**
     * @return string
     */
    public function getAuthConfigPath()
    {
        return $this->authConfigPath;
    }

    /**
     * @return string
     */
    public function getCalendarId()
    {
        return $this->calendarId;
    }
}

GoogleCalendar.php

<?php


namespace Kojirock\Infrastructure\Adapter\Google;

use Kojirock\Resource\GoogleCalendarConfig;

class GoogleCalendar
{
    /**
     * @var GoogleCalendarConfig
     */
    private $googleCalendarConfig;

    /**
     * GoogleCalendar constructor.
     * @param GoogleCalendarConfig $googleCalendarConfig
     */
    public function __construct(GoogleCalendarConfig $googleCalendarConfig)
    {
        $this->googleCalendarConfig = $googleCalendarConfig;
    }

    /**
     * @return \Google_Service_Calendar
     * @throws \Google_Exception
     */
    public function createInstanceGoogleCalendarService()
    {
        $client = new \Google_Client();
        $client->setAuthConfig($this->googleCalendarConfig->getAuthConfigPath());
        $client->setScopes(\Google_Service_Calendar::CALENDAR_EVENTS_READONLY);
        return new \Google_Service_Calendar($client);
    }

    /**
     * 祝日データを取得する
     * @param string $startDate
     * @param string $endDate
     * @return array
     * @throws \Google_Exception
     */
    public function fetchHolidays($startDate, $endDate)
    {
        $service  = $this->createInstanceGoogleCalendarService();
        $response = $service->events->listEvents($this->googleCalendarConfig->getCalendarId(), [
            'timeMin'      => $startDate,
            'timeMax'      => $endDate,
            'singleEvents' => true,
            'orderBy'      => 'startTime',
            'timeZone'     => 'Asia/Tokyo',
        ]);

        $results = [];
        foreach ($response->getItems() as $k => $item) {
            $results[$item->getStart()->getDate()] = $item->getSummary();
        }

        return $results;
    }
}

execute.php

<?php

$googleCalendarConfig = new \Kojirock\Resource\GoogleCalendarConfig([
    'authConfigPath' => 'DeveloperサイトからDLしてきたJsonファイルまでのパス',
    'calendarId'     => 'ja.japanese#holiday@group.v.calendar.google.com',
]);

$googleCalendar = new \Kojirock\Infrastructure\Adapter\Google\GoogleCalendar($googleCalendarConfig);

// 例えば、今月から1年先の祝日データを取得する
$startDate = \Carbon\Carbon::now()->startOfMonth()->format('c');
$endDate   = \Carbon\Carbon::now()->startOfMonth()->addYear(1)->format('c');
$holidays  = $googleCalendar->fetchHolidays($startDate, $endDate);
var_dump($holidays);

実行結果

array(22) {
  '2019-08-11' =>
  string(9) "山の日"
  '2019-08-12' =>
  string(22) "山の日 振替休日"
  '2019-09-16' =>
  string(12) "敬老の日"
  '2019-09-23' =>
  string(12) "秋分の日"
  '2019-10-14' =>
  string(12) "体育の日"
  '2019-10-22' =>
  string(39) "即位礼正殿の儀の行われる日"
  '2019-11-03' =>
  string(12) "文化の日"
  '2019-11-04' =>
  string(25) "文化の日 振替休日"
  '2019-11-23' =>
  string(18) "勤労感謝の日"
  '2020-01-01' =>
  string(6) "元日"
  '2020-01-13' =>
  string(12) "成人の日"
  '2020-02-11' =>
  string(18) "建国記念の日"
  '2020-02-23' =>
  string(15) "天皇誕生日"
  '2020-02-24' =>
  string(28) "天皇誕生日 振替休日"
  '2020-03-20' =>
  string(12) "春分の日"
  '2020-04-29' =>
  string(12) "昭和の日"
  '2020-05-03' =>
  string(15) "憲法記念日"
  '2020-05-04' =>
  string(15) "みどりの日"
  '2020-05-05' =>
  string(15) "こどもの日"
  '2020-05-06' =>
  string(28) "憲法記念日 振替休日"
  '2020-07-23' =>
  string(9) "海の日"
  '2020-07-24' =>
  string(12) "体育の日"
}

終わりに

こんな感じ祝日データをとってきました。

GoogleCalendarAPIを使って祝日とってくる作業って、記憶に残ってるだけで4回目くらいだったのに、それでも毎回忘れてるのでコードそのまま残しときました。

↓を見る限り、一日100万回の制限があるっぽいんですが、バッチとかで1日1回取得して、RedisとかにキャッシュしとけばOKかなとか思います。

developers.google.com

現場からは以上です。