Как создать запись в календаре Google без пользователя?
Недавно я решил предоставить пользователям на своем сайте следующую функциональность: онлайн-бронирование временных интервалов в календарях моих сотрудников. У всех сотрудников есть аккаунты Google, связанные с нашим доменом в Google Apps (бесплатная версия). Пользователи делают бронирование в каком-либо интерфейсе (например, не напрямую в календарях сотрудников Google), затем запрос обрабатывается на нашем PHP-сервере, и, если он правильный, сервер должен иметь возможность создавать новую запись календаря в выбранном календаре Google сотрудника. Примечание - ни пользователь, ни сотрудник не должны запрашивать аутентификацию при бронировании.
Я отсканировал API и форумы Google Calendar v3 и до сих пор не получил ни четкого ответа, ни кратких примеров - возможен ли такой сценарий с календарем Google? Может ли кто-нибудь помочь мне ответить на вопрос (и, если возможно, поделиться ссылкой с соответствующим примером)?
1 ответ
Вы знакомы с добавлением события с аутентификацией? Как я ответил здесь.
И как в коде ниже. Если вы... вы можете перейти на следующий уровень;)
(Вы можете скачать Php-клиент Google Api на этой странице. На этой странице есть учебник. Он предназначен для Google+, но принцип тот же)
В первый раз вам всегда понадобится аутентификация. Обойти это невозможно. В приведенном ниже примере вы получите token
обратно после аутентификации, которая включает access_token и refresh_token. Access_token действителен только в течение 3600 секунд и используется для прямого доступа. По истечении срока действия access_token вы получаете ошибку 401 и можете использовать refresh_token (вместе с client_id, client_secret и правильным grant_type), чтобы запросить новый access_token.
Вы можете найти дополнительную информацию на этой странице (внизу "Использование маркера обновления"). Существуют некоторые ограничения по количеству запросов, упомянутые на этой странице внизу.
Это тестовый код, который я сделал в последний раз, когда помогал кому-то с этим. Это только показывает получение аутентификации и сохранение token
в печенье. Он не запрашивает новый access_token после истечения срока его действия.
Но, как я уже сказал, вам нужно хранить token
(в базе данных?) и когда вы получаете 401, вам нужно запросить новый access_token с client_id, client_secret, правильный grant_type и refresh_token. Для этого не требуется (повторная) аутентификация.
<?php
error_reporting(E_ALL);
require_once 'google-api-php-client/src/Google_Client.php';
require_once 'google-api-php-client/src/contrib/Google_CalendarService.php';
session_start();
if ((isset($_SESSION)) && (!empty($_SESSION))) {
echo "There are cookies<br>";
echo "<pre>";
print_r($_SESSION);
echo "</pre>";
}
$client = new Google_Client();
$client->setApplicationName("Google Calendar PHP Starter Application");
$client->setClientId('###');
$client->setClientSecret('###');
$client->setRedirectUri('http://###/add_calendar.php'); // <- registered web-page
//$client->setDeveloperKey('###'); // <- not always needed
$cal = new Google_CalendarService($client);
if (isset($_GET['logout'])) {
echo "<br><br><font size=+2>Logging out</font>";
unset($_SESSION['token']);
}
if (isset($_GET['code'])) {
echo "<br>I got a code from Google = ".$_GET['code']; // You won't see this if redirected later
$client->authenticate(); // $_GET['code']
$_SESSION['token'] = $client->getAccessToken();
header('Location: http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF']);
// not strictly necessary to redirect but cleaner for the url in address-bar
echo "<br>I got the token = ".$_SESSION['token']; // <-- not needed to get here unless location uncommented
}
if (isset($_SESSION['token'])) {
echo "<br>Getting access";
$client->setAccessToken($_SESSION['token']);
}
if ($client->getAccessToken()){
echo "<hr><font size=+1>I have access to your calendar</font>";
$event = new Google_Event();
$event->setSummary('=== I ADDED THIS ===');
$event->setLocation('The Neighbourhood');
$start = new Google_EventDateTime();
$start->setDateTime('2013-11-29T10:00:00.000-05:00');
$event->setStart($start);
$end = new Google_EventDateTime();
$end->setDateTime('2013-11-29T10:25:00.000-05:00');
$event->setEnd($end);
$createdEvent = $cal->events->insert('###', $event); // <- ### = email of calendar
echo "<br><font size=+1>Event created</font>";
echo "<hr><br><font size=+1>Already connected</font> (No need to login)";
} else {
$authUrl = $client->createAuthUrl();
print "<hr><br><font size=+2><a href='$authUrl'>Connect Me!</a></font>";
}
$url = 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'];
echo "<br><br><font size=+2><a href=$url?logout>Logout</a></font>";
?>
Редактировать:
Если вы не хотите первоначальной аутентификации, у Google есть "Сервисные учетные записи", как вы указали.
(Я не знал об этом:)
Я выкопал несколько ссылок, где вы можете найти код для использования после того, как вы получили файл ключа.
Изменить события календаря Google из учетной записи службы Google: 403
Доступ к событиям календаря Google из учетной записи службы: {"error": "access_denied"}. Нет приложений Google
Учетная запись службы Google OAuth 2.0 - API календаря (клиент PHP)
https://groups.google.com/forum/
https://groups.google.com/forum/?fromgroups
Редактировать № 2: ДА, все заработало. (даже с моей бесплатной учетной записью Google;)
Вот рабочий код:
<?
error_reporting(E_ALL);
require_once 'google-api-php-client/src/Google_Client.php';
require_once 'google-api-php-client/src/contrib/Google_CalendarService.php';
session_start();
echo "Busy<br>";
const CLIENT_ID = 'xxxxxxxxxx.apps.googleusercontent.com';
const SERVICE_ACCOUNT_NAME = 'xxxxxxxxxxx@developer.gserviceaccount.com';
const KEY_FILE = 'xxxxxxxxxxxxxxxxxxx-privatekey.p12';
const CALENDAR_NAME = 'xxxxxxx@gmail.com';
$client = new Google_Client();
$client->setApplicationName("mycal");
if (isset($_SESSION['token'])) {
$client->setAccessToken($_SESSION['token']);
}
$key = file_get_contents(KEY_FILE);
$client->setClientId(CLIENT_ID);
$client->setAssertionCredentials(new Google_AssertionCredentials(
SERVICE_ACCOUNT_NAME,
array('https://www.google.com/calendar/feeds/'),
$key)
);
$client->setClientId(CLIENT_ID);
$service = new Google_CalendarService($client);
$event = new Google_Event();
$event->setSummary('=== I MADE THIS ===');
$event->setLocation('Somewhere else');
$start = new Google_EventDateTime();
$start->setDateTime('2013-11-30T10:00:00.000-02:00');
$event->setStart($start);
$end = new Google_EventDateTime();
$end->setDateTime('2013-11-30T10:25:00.000-02:00');
$event->setEnd($end);
$createdEvent = $service->events->insert(CALENDAR_NAME, $event);
echo "Done<br>";
?>
Мне нужно было сделать "новый проект" на https://cloud.google.com/console. Я не мог использовать существующий. После активации "Calendar API" и регистрации нового веб-приложения с сертификатом мне нужно было только поделиться своим календарем с кодом xxxx@developer.gserviceaccount.com и выше, который работал
(без аутентификации).
Редактирование #3: и теперь оно также работает в стандартном проекте Google+ API по умолчанию