Wpis ten przedstawia jak z pomocą PHP tworzyć zdarzenia w swoim kalendarzu Google
1. Tworzenie aplikacji w Google API
Pierwszą rzeczą jaką musimy zrobić jest stworzenie aplikacji w Google API Console: https://console.developers.google.com/
Jeśli nie mamy stworzonego projektu klikamy na „Stwórz projekt” (u góry strony).
Następnie przechodzimy na stronę naszego projektu, klikamy na „Biblioteka” (w menu po lewej stronie), szukamy i klikamy na „Calendar API” a następnie na „Włącz” („Enable”).
Następnie klikamy w lewym menu na „Dane logowania” („Credentials”). Klikamy na „Utwórz dane logowania” i z listy wybieramy „Id klienta OAuth” („OAuth client ID”). Wybieramy typ aplikacji jako „Aplikacja internetowa”.
W sekcji „Autoryzowane źródła JavaScript” i „Autoryzowane identyfikatory URI przekierowania” (redirect URI) wpisujemy adres URL naszej strony www. W tym miejscu możemy dodać nawet localhost (parametry są przesyłane żądaniami GET, więc będzie to działać). Możemy też zostawić te pola puste. Klikamy przycisk „Utwórz”.
Na ekranie wyświetli się Identyfikator klienta (App Client ID) oraz Tajny klucz klienta (App secret). Zapisujemy je w bezpiecznym miejscu, będą nam potrzebne.
Na następnej stronie klikamy zakładkę „Ekran zgody OAuth” („OAuth Consent Screen”). Tutaj możemy dodać adres email i nazwę naszej aplikacji.
2. Logowanie do Google OAuth
Przed używaniem aplikacji na naszej stronie www musimy zalogować się w niej na swoje konto Google poprzez Google OAuth i uzyskać Access Token.
Najpierw stwórzmy plik settings.php w którym będą zapisane ustawienia aplikacji:
<?php /* Google App Client Id */ define('CLIENT_ID', 'xxxxxxxxxxxx'); /* Google App Client Secret */ define('CLIENT_SECRET', 'xxxxxxxxxxxx'); /* Google App Redirect Url */ define('CLIENT_REDIRECT_URL', 'xxxxxxxxxxxx');
Uzupełniamy wszystkie 3 pola, wpisując uzyskane z Google APP wartości. W ostatnim polu wpisujemy adres URL naszej strony, na której uruchomimy plik index.php
Tworzymy plik index.php i w nim wklejamy następującą treść:
<?php require_once('settings.php'); $login_url = 'https://accounts.google.com/o/oauth2/v2/auth?scope=' . urlencode('https://www.googleapis.com/auth/calendar') . '&redirect_uri=' . urlencode(CLIENT_REDIRECT_URL) . '&response_type=code&client_id=' . CLIENT_ID . '&access_type=offline&prompt=consent'; ?> <a href="<?= $login_url ?>">Login with Google</a>
Istotne są te wartości: access_type=offline&prompt=consent
Dzięki temu nie będziemy musieli prosić użytkownika o ponowne logowanie się do aplikacji.
Jeśli teraz wejdziemy na naszą stronę www zobaczymy link do logowania się w Google. Po kliknięciu przekierowuje nas na stronę logowania Google, na której musimy potwierdzić uprawnienia aplikacji do używania kalendarza. Po zalogowaniu się skrypt wraca na naszą stronę mając w zmiennej GET wartość „code”. Teraz musimy ją wykorzystać do uzyskania tokenu:)
3. Uzyskanie Access Token
Zmieniamy nasz plik index.php na poniższy:
<?php require_once('settings.php'); require_once('google-calendar-api.php'); $login_url = 'https://accounts.google.com/o/oauth2/v2/auth?scope=' . urlencode('https://www.googleapis.com/auth/calendar') . '&redirect_uri=' . urlencode(CLIENT_REDIRECT_URL) . '&response_type=code&client_id=' . CLIENT_ID . '&access_type=offline&prompt=consent'; if(isset($_GET['code'])) { try { $capi = new GoogleCalendarApi(); $data = $capi->GetAccessToken(CLIENT_ID, CLIENT_REDIRECT_URL, CLIENT_SECRET, $_GET['code']); print_r($data); exit(); } catch(Exception $e) { echo $e->getMessage(); exit(); } } ?> <a href="<?= $login_url ?>">Login with Google</a>
W pliku google-calendar-api.php mamy wszystkie funkcje, które będą nam potrzebne. Oto zawartość pliku (wszystkie pliki możesz pobrać klikając w link na końcu tego wpisu)
<?php class GoogleCalendarApi { public function GetRefreshedAccessToken($client_id, $refresh_token, $client_secret) { $url_token = 'https://accounts.google.com/o/oauth2/token'; $curlPost = 'client_id=' . $client_id . '&client_secret=' . $client_secret . '&refresh_token='. $refresh_token . '&grant_type=refresh_token'; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url_token); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt($ch, CURLOPT_POSTFIELDS, $curlPost); $data = json_decode(curl_exec($ch), true); //print_r($data); $http_code = curl_getinfo($ch,CURLINFO_HTTP_CODE); if($http_code != 200) throw new Exception('Error : Failed to refresh access token'); return $data; } public function GetAccessToken($client_id, $redirect_uri, $client_secret, $code) { $url = 'https://accounts.google.com/o/oauth2/token'; $curlPost = 'client_id=' . $client_id . '&redirect_uri=' . $redirect_uri . '&client_secret=' . $client_secret . '&code='. $code . '&grant_type=authorization_code'; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt($ch, CURLOPT_POSTFIELDS, $curlPost); $data = json_decode(curl_exec($ch), true); $http_code = curl_getinfo($ch,CURLINFO_HTTP_CODE); if($http_code != 200) throw new Exception('Error : Failed to receive access token'); return $data; } public function GetUserCalendarTimezone($access_token) { $url_settings = 'https://www.googleapis.com/calendar/v3/users/me/settings/timezone'; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url_settings); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_HTTPHEADER, array('Authorization: Bearer '. $access_token)); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); $data = json_decode(curl_exec($ch), true); //echo '<pre>';print_r($data);echo '</pre>'; $http_code = curl_getinfo($ch,CURLINFO_HTTP_CODE); if($http_code != 200) throw new Exception('Error : Failed to get timezone'); return $data['value']; } public function GetCalendarsList($access_token) { $url_parameters = array(); $url_parameters['fields'] = 'items(id,summary,timeZone)'; $url_parameters['minAccessRole'] = 'owner'; $url_calendars = 'https://www.googleapis.com/calendar/v3/users/me/calendarList?'. http_build_query($url_parameters); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url_calendars); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_HTTPHEADER, array('Authorization: Bearer '. $access_token)); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); $data = json_decode(curl_exec($ch), true); //echo '<pre>';print_r($data);echo '</pre>'; $http_code = curl_getinfo($ch,CURLINFO_HTTP_CODE); if($http_code != 200) throw new Exception('Error : Failed to get calendars list'); return $data['items']; } public function CreateCalendarEvent($calendar_id, $summary, $all_day, $event_time, $event_timezone, $access_token) { $url_events = 'https://www.googleapis.com/calendar/v3/calendars/' . $calendar_id . '/events'; $curlPost = array('summary' => $summary); if($all_day == 1) { $curlPost['start'] = array('date' => $event_time['event_date']); $curlPost['end'] = array('date' => $event_time['event_date']); } else { $curlPost['start'] = array('dateTime' => $event_time['start_time'], 'timeZone' => $event_timezone); $curlPost['end'] = array('dateTime' => $event_time['end_time'], 'timeZone' => $event_timezone); } $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url_events); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt($ch, CURLOPT_HTTPHEADER, array('Authorization: Bearer '. $access_token, 'Content-Type: application/json')); curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($curlPost)); $data = json_decode(curl_exec($ch), true); $http_code = curl_getinfo($ch,CURLINFO_HTTP_CODE); if($http_code != 200) throw new Exception('Error : Failed to create event'); return $data['id']; } } ?>
Teraz po kliknięciu na „Login with Google” na naszej stronie i przekierowaniu z powrotem zobaczymy na ekranie wydrukowaną tablicę z m.in. wartościami: access_token i refresh_token
Na końcu pliku settings.php dodajemy taką linię, w której wstawiamy wygenerowaną wartość „refresh_token”
define('REFRESH_TOKEN', 'xxxxxxxxxxxxxx');
To pozwoli nam uzyskiwać Access Token bez potrzeby ponownego logowania użytkownika.
Następnie zmieniamy nasz plik index.php na taki:
<?php require_once('settings.php'); require_once('google-calendar-api.php'); try { $capi = new GoogleCalendarApi(); $data = $capi->GetRefreshedAccessToken(CLIENT_ID, REFRESH_TOKEN, CLIENT_SECRET); $access_token = $data['access_token']; exit($access_token); } catch(Exception $e) { echo $e->getMessage(); exit(); }
Przy każdym odświeżeniu strony widzimy nowy Access Token – czyli wszystko działa jak należy:)
4. Uzyskiwanie strefy czasowej kalendarza
Aby móc poprawnie dodać zdarzenia do kalendarza musimy uzyskać strefę czasową. Możemy oczywiście ją ręcznie wpisać, jednak jest także możliwość uzyskania do niej dostępu poprzez taki kod pliku index.php:
<?php require_once('settings.php'); require_once('google-calendar-api.php'); try { $capi = new GoogleCalendarApi(); $data = $capi->GetRefreshedAccessToken(CLIENT_ID, REFRESH_TOKEN, CLIENT_SECRET); $access_token = $data['access_token']; $user_timezone = $capi->GetUserCalendarTimezone($access_token); exit($user_timezone); } catch(Exception $e) { echo $e->getMessage(); exit(); }
Na ekranie zobaczmy strefę czasową danego kalendarza.
5. Dodawanie zdarzeń do kalendarza
Nowe zdarzenie w kalendarzu możemy stworzyć z tablicy w PHP, przykładowa może wyglądać w ten sposób:
$event = array( 'title' => 'test', 'event_time' => Array ( 'start_time' => '2017-06-18T12:12:00', 'end_time' => '2017-06-19T12:12:00', 'event_date' => ''), 'all_day' => 0 );
Sam proces dodania do kalendarza realizuje ta funkcja:
$event_id = $capi->CreateCalendarEvent('primary', $event['title'], $event['all_day'], $event['event_time'], $user_timezone, $access_token); echo 'Event has been created with ID ' . $event_id;
Pierwszy parametr funkcji to ID naszego kalendarza. Wartość 'primary’ powoduje że zdarzenie zostanie dodane do głównego kalendarza.
Po zmianie naszego pliku index.php na taką zawartość i odświeżeniu strony powinniśmy zobaczyć wiadomość z ID zdarzenia z kalendarza:
<?php require_once('settings.php'); require_once('google-calendar-api.php'); $event = array('title' => 'test', 'event_time' => Array ( 'start_time' => '2017-06-22T12:12:00', 'end_time' => '2017-06-26T12:12:00', 'event_date' => ''), 'all_day' => 0 ); try { $capi = new GoogleCalendarApi(); $data = $capi->GetRefreshedAccessToken(CLIENT_ID, REFRESH_TOKEN, CLIENT_SECRET); $access_token = $data['access_token']; $user_timezone = $capi->GetUserCalendarTimezone($access_token); $event_id = $capi->CreateCalendarEvent('primary', $event['title'], $event['all_day'], $event['event_time'], $user_timezone, $access_token); echo 'Event has been created with ID ' . $event_id; } catch(Exception $e) { echo $e->getMessage(); exit(); }
Uwaga! Wielokrotnie wywołując funkcję dodającą to samo zdarzenie uzyskamy błąd. Należy zmienić nazwę i daty zdarzenia.
Mam nadzieje że ten wpis pomoże komuś w tworzeniu zdarzeń w Kalendarzu na Google 🙂
Link do pobrania archiwum z przykładem na GitHub: https://github.com/kamilwyremski/google-calendar
Wpis został oparty na poniższych artykułach:
http://usefulangle.com/post/29/google-calendar-api-create-event-php
http://usefulangle.com/post/9/google-login-api-with-php-curl