I'm trying to setup a Push Notifications for Google Calendar using PHP and V3 api.
I've got the Auth2.0 Permission and I'm able to create events on google from my application. Now I want to know when a user makes any change on google calendar (CRUD Operations).
This is my code:
private $imageService;
public $google_client;
public $google_calendar;
public function __construct()
{
$this->imageService = new ImageService();
$this->google_client = new Google_Client();
$this->google_client->setApplicationName($_ENV['GOOGLE_APP_NAME']);
$this->google_client->setDeveloperKey($_ENV['GOOGLE_API_KEY']);
$this->google_client->setClientId($_ENV['CLIENT_ID']);
$this->google_client->setClientSecret($_ENV['CLIENT_SECRET']);
$this->google_client->setAccessType('offline');
$this->google_client->setIncludeGrantedScopes(true);
$this->google_client->setScopes(array('email', 'profile', 'https://www.googleapis.com/auth/plus.me', 'https://www.googleapis.com/auth/calendar'));
$this->google_calendar = new Google_Service_Calendar($this->google_client);
}
public function googleCalendarWatch($uuid){
$channel = new Google_Service_Calendar_Channel($this->google_client);
$channel->setId($uuid);
$channel->setType('web_hook');
$channel->setAddress("https://example.com/google/googleNotifications");
$channel->setExpiration("1919995862000");
$this->google_calendar->events->watch('primary', $channel);
}
And this is the output:
Google_Service_Calendar_Channel Object (
[internal_gapi_mappings:protected] => Array ( )
[address] =>
[expiration] => 1426272395000
[id] => aee2b430-34bf-42bc-a597-ada46db42799
[kind] => api#channel
[params] =>
[payload] =>
[resourceId] => 51IKGpOwCJ6EMraQMUc1_04MODk
[resourceUri] => https://www.googleapis.com/calendar/v3/calendars/primary/events?key=AIzaSyBFUvq3OZO6ugAKvz7l8NgLS0V6DUJq8Vc&alt=json
[token] =>
[type] =>
[modelData:protected] => Array ( )
[processed:protected] => Array ( ) )
This far I don't know why address returns null, maybe that's the problem. But I don't know how to fix it.
Also reading this: #26730263 and looking my own code there's no much difference.
I did all the stuff that google says, Register domain, add credentials, api key, push domain allowed and all..
Create a notification channel for every individual resource, then any modification to that resource you will be then notified. Information below is directly from Google (Creating notification channels).
Making watch requests:
Each watchable Google Calendar API resource has an associated watch method at a URI of the following form:
https://www.googleapis.com/**apiName**/**apiVersion**/**resourcePath**/watch
To set up a notification channel for messages about changes to a particular resource, send a POST request to the watch method for the resource.
Each notification channel is associated both with a particular user and a particular resource (or set of resources). A watch request will not be successful unless the current user owns or has permission to access this resource.
Example:
Start watching for changes to a collection of events on a given calendar:
POST https://www.googleapis.com/calendar/v3/calendars/my_calendar#gmail.com/events/watch
Authorization: Bearer auth_token_for_current_user
Content-Type: application/json
{
"id": "01234567-89ab-cdef-0123456789ab", // Your channel ID.
"type": "web_hook",
"address": "https://example.com/notifications", // Your receiving URL.
...
"token": "target=myApp-myCalendarChannelDest", // (Optional) Your channel token.
"expiration": 1426325213000 // (Optional) Your requested channel expiration time.
}
}
Reference: Google (Creating notification channels) (19-Mar-2018).
Address?
Token?
<?php
require __DIR__ . '/vendor/autoload.php';
if (php_sapi_name() != 'cli') {
throw new Exception('This application must be run on the command line.');
}
/**
* Returns an authorized API client.
* #return Google_Client the authorized client object
*/
function getClient()
{
$client = new Google_Client();
$client->setApplicationName('Google Calendar API PHP Quickstart');
$client->setScopes(Google_Service_Calendar::CALENDAR_READONLY);
$client->setAuthConfig('credentials.json');
$client->setAccessType('offline');
$client->setPrompt('select_account consent');
// Load previously authorized token from a file, if it exists.
// The file token.json stores the user's access and refresh tokens, and is
// created automatically when the authorization flow completes for the first
// time.
$tokenPath = 'token.json';
if (file_exists($tokenPath)) {
$accessToken = json_decode(file_get_contents($tokenPath), true);
$client->setAccessToken($accessToken);
}
// If there is no previous token or it's expired.
if ($client->isAccessTokenExpired()) {
// Refresh the token if possible, else fetch a new one.
if ($client->getRefreshToken()) {
$client->fetchAccessTokenWithRefreshToken($client->getRefreshToken());
} else {
// Request authorization from the user.
$authUrl = $client->createAuthUrl();
printf("Open the following link in your browser:\n%s\n", $authUrl);
print 'Enter verification code: ';
$authCode = trim(fgets(STDIN));
// Exchange authorization code for an access token.
$accessToken = $client->fetchAccessTokenWithAuthCode($authCode);
$client->setAccessToken($accessToken);
// Check to see if there was an error.
if (array_key_exists('error', $accessToken)) {
throw new Exception(join(', ', $accessToken));
}
}
// Save the token to a file.
if (!file_exists(dirname($tokenPath))) {
mkdir(dirname($tokenPath), 0700, true);
}
file_put_contents($tokenPath, json_encode($client->getAccessToken()));
}
return $client;
}
// Get the API client and construct the service object.
$client = getClient();
$service = new Google_Service_Calendar($client);
// Print the next 10 events on the user's calendar.
$calendarId = 'primary';
$optParams = array(
'maxResults' => 10,
'orderBy' => 'startTime',
'singleEvents' => true,
'timeMin' => date('c'),
);
$results = $service->events->listEvents($calendarId, $optParams);
$events = $results->getItems();
if (empty($events)) {
print "No upcoming events found.\n";
} else {
print "Upcoming events:\n";
foreach ($events as $event) {
$start = $event->start->dateTime;
if (empty($start)) {
$start = $event->start->date;
}
printf("%s (%s)\n", $event->getSummary(), $start);
}
}
Full Tutorial
Related
I would like to share and add events to my own google calendar from my website.
So, I don't want the oauth prompt. Because users who visite my website can also add event to my calendar.
I think I did the right thing but I have this error : Client is unauthorized to retrieve access tokens using this method, or client not authorized for any of the scopes requested
So, I don't sur if I need a paid workspace account to do that.
If not, I can't understand where I failed ?
here is my code :
$client = new Google\Client();
$client->setAuthConfig('./secret.json');
$client->setApplicationName('app name');
$client->addScope(Google\Service\Calendar::CALENDAR_EVENTS);
$client->setSubject('mail#gmail.com');
$client->setAccessType('offline');
$service = new Google\Service\Calendar($client);
$event = new Google\Service\Calendar\Event(array(
'summary' => 'summary',
'location' => 'street bla bla',
'description' => 'first event',
'start' => array(
'dateTime' => '2021-11-30T10:00:00.000-05:00',
'timeZone' => 'Europe/Brussels',
),
'end' => array(
'dateTime' => '2021-11-30T10:00:00.000-05:00',
'timeZone' => 'Europe/Brussels',
)
));
$service->events->insert('calendar_id', $event);
Thanks
The issue is that you are trying to set the subject or delegate to a normally Gmail email address $client->setSubject('mail#gmail.com');
Service accounts only work with Google workspace domain accounts and only after you have properly set up delegation to a user on the domain.
Im sorry to tell you that you will not be able to use a service account with your gmail email address.
What you could do is run the code from the Sample project which uses an installed application and stores the refresh token. This code will be single user. You will have to monitor it a little as refresh tokens can expire although its not that common once your project is set into prodctuion.
require __DIR__ . '/vendor/autoload.php';
if (php_sapi_name() != 'cli') {
throw new Exception('This application must be run on the command line.');
}
/**
* Returns an authorized API client.
* #return Google_Client the authorized client object
*/
function getClient()
{
$client = new Google_Client();
$client->setApplicationName('Google Calendar API PHP Quickstart');
$client->setScopes(Google_Service_Calendar::CALENDAR_READONLY);
$client->setAuthConfig('credentials.json');
$client->setAccessType('offline');
$client->setPrompt('select_account consent');
// Load previously authorized token from a file, if it exists.
// The file token.json stores the user's access and refresh tokens, and is
// created automatically when the authorization flow completes for the first
// time.
$tokenPath = 'token.json';
if (file_exists($tokenPath)) {
$accessToken = json_decode(file_get_contents($tokenPath), true);
$client->setAccessToken($accessToken);
}
// If there is no previous token or it's expired.
if ($client->isAccessTokenExpired()) {
// Refresh the token if possible, else fetch a new one.
if ($client->getRefreshToken()) {
$client->fetchAccessTokenWithRefreshToken($client->getRefreshToken());
} else {
// Request authorization from the user.
$authUrl = $client->createAuthUrl();
printf("Open the following link in your browser:\n%s\n", $authUrl);
print 'Enter verification code: ';
$authCode = trim(fgets(STDIN));
// Exchange authorization code for an access token.
$accessToken = $client->fetchAccessTokenWithAuthCode($authCode);
$client->setAccessToken($accessToken);
// Check to see if there was an error.
if (array_key_exists('error', $accessToken)) {
throw new Exception(join(', ', $accessToken));
}
}
// Save the token to a file.
if (!file_exists(dirname($tokenPath))) {
mkdir(dirname($tokenPath), 0700, true);
}
file_put_contents($tokenPath, json_encode($client->getAccessToken()));
}
return $client;
}
// Get the API client and construct the service object.
$client = getClient();
$service = new Google_Service_Calendar($client);
// Print the next 10 events on the user's calendar.
$calendarId = 'primary';
$optParams = array(
'maxResults' => 10,
'orderBy' => 'startTime',
'singleEvents' => true,
'timeMin' => date('c'),
);
$results = $service->events->listEvents($calendarId, $optParams);
$events = $results->getItems();
if (empty($events)) {
print "No upcoming events found.\n";
} else {
print "Upcoming events:\n";
foreach ($events as $event) {
$start = $event->start->dateTime;
if (empty($start)) {
$start = $event->start->date;
}
printf("%s (%s)\n", $event->getSummary(), $start);
}
}
My goal is to retrieve events from google calendar in cron function, I need to do that without authorizing the requests every 1 hour since the access token expires.
From many related stack overflow questions I understood that in the beginning I gain an access token from authorizing the request, then the token get written in a token.json file. After the first access, every time I need to access the calendar the function fGetClient control if the token is expired or not, IF I PREVIOUSLY SET
$client->setAccessType('offline');
the function should refresh the token and i should access the calendar's event without authorizing any further request.
My problem is that i can't get the refreshed token, it expires in an hour and then i need to manually copy the link ,authorize the request and then copy and paste the verification code.
I leave the code below.
public function fGoogleCalendar($operazione=null){
//require_once $this->config["googlecalendardir"].'vendor/autoload.php';
// Get the API client and construct the service object.
$client = $this->fGCGetClient();
$service = new Google_Service_Calendar($client);
// Print the next 10 events on the user's calendar.
$calendarId = 'primary';
$optParams = array(
'maxResults' => 10,
'orderBy' => 'startTime',
'singleEvents' => true,
'timeMin' => date('c'),
);
$results = $service->events->listEvents($calendarId, $optParams);
$events = $results->getItems();
if (empty($events)) {
$aEventi="0 events found";
} else {
// "Upcoming events:\n";
foreach ($events as $event) {
$start = $event->start->dateTime;
if (empty($start)) {
$start = $event->start->date;
}
$end = $event->end->dateTime;
if (empty($end)) {
$end = $event->end->date;
}
$aEventi[]=array(
"nome" => $event->getSummary(),
"startdate" => $start,
"enddate" => $end
);
$start);
}
}
return $aEventi;
}
public function fGCGetClient(){
require_once $this->config["googlecalendardir"].'vendor/autoload.php';
$client = new Google_Client();
//die("ok");
$client->setApplicationName('Google Calendar API PHP Quickstart');
$client->setScopes(Google_Service_Calendar::CALENDAR_READONLY);
$client->setAuthConfig($this->config["googlecalendardir"].'credentials.json');
$client->setAccessType('offline');
//$client->setApprovalPrompt('auto');
$client->setPrompt('consent');
// Load previously authorized token from a file, if it exists.
// The file token.json stores the user's access and refresh tokens, and is
// created automatically when the authorization flow completes for the first
// time.
$tokenPath = $this->config["googlecalendardir"].'token.json';
if (file_exists($tokenPath)) {
$accessToken = json_decode(file_get_contents($tokenPath), true);
$client->setAccessToken($accessToken);
}
// If there is no previous token or it's expired.
//if (true) {
if ($client->isAccessTokenExpired()) {
// Refresh the token if possible, else fetch a new one.
if ($client->getRefreshToken()) {
//$client->fetchAccessTokenWithRefreshToken($client->getRefreshToken());
$client->fetchAccessTokenWithRefreshToken($client->getRefreshToken());
$client->setAccessToken($client->getAccessToken());
} else {
// Request authorization from the user.
$authUrl = $client->createAuthUrl();
printf("Open the following link in your browser:\n%s\n", $authUrl);
print 'Enter verification code: ';
$authCode = trim(fgets(STDIN));
// Exchange authorization code for an access token.
$accessToken = $client->fetchAccessTokenWithAuthCode($authCode);
$client->setAccessToken($accessToken);
// Check to see if there was an error.
if (array_key_exists('error', $accessToken)) {
throw new Exception(join(', ', $accessToken));
}
}
// Save the token to a file.
if (!file_exists(dirname($tokenPath))) {
mkdir(dirname($tokenPath), 0700, true);
}
file_put_contents($tokenPath, json_encode($client->getAccessToken()));
}
return $client;
}
if you follow php quick start you will notice that it request offline access this means that the first time the user authorizes this application that the refresh token will be returned its then stored in $tokenPath
<?php
require __DIR__ . '/vendor/autoload.php';
if (php_sapi_name() != 'cli') {
throw new Exception('This application must be run on the command line.');
}
/**
* Returns an authorized API client.
* #return Google_Client the authorized client object
*/
function getClient()
{
$client = new Google_Client();
$client->setApplicationName('Google Calendar API PHP Quickstart');
$client->setScopes(Google_Service_Calendar::CALENDAR_READONLY);
$client->setAuthConfig('credentials.json');
$client->setAccessType('offline');
$client->setPrompt('select_account consent');
// Load previously authorized token from a file, if it exists.
// The file token.json stores the user's access and refresh tokens, and is
// created automatically when the authorization flow completes for the first
// time.
$tokenPath = 'token.json';
if (file_exists($tokenPath)) {
$accessToken = json_decode(file_get_contents($tokenPath), true);
$client->setAccessToken($accessToken);
}
// If there is no previous token or it's expired.
if ($client->isAccessTokenExpired()) {
// Refresh the token if possible, else fetch a new one.
if ($client->getRefreshToken()) {
$client->fetchAccessTokenWithRefreshToken($client->getRefreshToken());
} else {
// Request authorization from the user.
$authUrl = $client->createAuthUrl();
printf("Open the following link in your browser:\n%s\n", $authUrl);
print 'Enter verification code: ';
$authCode = trim(fgets(STDIN));
// Exchange authorization code for an access token.
$accessToken = $client->fetchAccessTokenWithAuthCode($authCode);
$client->setAccessToken($accessToken);
// Check to see if there was an error.
if (array_key_exists('error', $accessToken)) {
throw new Exception(join(', ', $accessToken));
}
}
// Save the token to a file.
if (!file_exists(dirname($tokenPath))) {
mkdir(dirname($tokenPath), 0700, true);
}
file_put_contents($tokenPath, json_encode($client->getAccessToken()));
}
return $client;
}
// Get the API client and construct the service object.
$client = getClient();
$service = new Google_Service_Calendar($client);
// Print the next 10 events on the user's calendar.
$calendarId = 'primary';
$optParams = array(
'maxResults' => 10,
'orderBy' => 'startTime',
'singleEvents' => true,
'timeMin' => date('c'),
);
$results = $service->events->listEvents($calendarId, $optParams);
$events = $results->getItems();
if (empty($events)) {
print "No upcoming events found.\n";
} else {
print "Upcoming events:\n";
foreach ($events as $event) {
$start = $event->start->dateTime;
if (empty($start)) {
$start = $event->start->date;
}
printf("%s (%s)\n", $event->getSummary(), $start);
}
}
In your current directory delete this file token.json
It's where the token is saved if you delete the file your program won't find the token therefore create a new token.
I am trying to use Google's calendar API to create calendars and save them into my google calendar directly through my app, I would also like to create events but I cant seem to get this to work, there's no error whatsoever but still I don't see the calendar in my list.
$client = new \Google_Client();
$client->setApplicationName("GOOGLE CALENDAR");
$client->addScope(\Google_Service_Calendar::CALENDAR);
$client->setAuthConfig('pr-test-4ad4a00e3031.json');
$client->setAccessType("offline");
$service = new \Google_Service_Calendar($client);
$calenders = new \Google_Service_Calendar_Calendar();
$calenders->setDescription('ramzi');
$calenders->setSummary('test');
$service->calendars->insert($calenders);
print_r($calenders);
the JSON file has the credentials.
And this is the output I get when I print the variable $calenders
Google_Service_Calendar_Calendar Object
(
[conferencePropertiesType:protected] => Google_Service_Calendar_ConferenceProperties
[conferencePropertiesDataType:protected] =>
[description] => ramzi
[etag] =>
[id] =>
[kind] =>
[location] =>
[summary] => test
[timeZone] =>
[internal_gapi_mappings:protected] => Array
(
)
[modelData:protected] => Array
(
)
[processed:protected] => Array
(
)
)
This code will help you to achieve what you are trying to do(Create new calendars and events in them):
<?php
require __DIR__ . '/vendor/autoload.php';
function getClient(){
$client = new Google_Client();
$client->setApplicationName('Calendar API PHP');
$client->addScope(Google_Service_Calendar::CALENDAR);
$client->setAuthConfig('credentials.json');
$client->setAccessType('offline');
$client->setPrompt('select_account consent');
// Load previously authorized token from a file, if it exists.
// The file token.json stores the user's access and refresh tokens, and is
// created automatically when the authorization flow completes for the first
// time.
$tokenPath = 'token.json';
if (file_exists($tokenPath)) {
$accessToken = json_decode(file_get_contents($tokenPath), true);
$client->setAccessToken($accessToken);
}
// If there is no previous token or it's expired.
if ($client->isAccessTokenExpired()) {
// Refresh the token if possible, else fetch a new one.
if ($client->getRefreshToken()) {
$client->fetchAccessTokenWithRefreshToken($client->getRefreshToken());
} else {
// Request authorization from the user.
$authUrl = $client->createAuthUrl();
printf("Open the following link in your browser:\n%s\n", $authUrl);
print 'Enter verification code: ';
$authCode = trim(fgets(STDIN));
// Exchange authorization code for an access token.
$accessToken = $client->fetchAccessTokenWithAuthCode($authCode);
$client->setAccessToken($accessToken);
// Check to see if there was an error.
if (array_key_exists('error', $accessToken)) {
throw new Exception(join(', ', $accessToken));
}
}
// Save the token to a file.
if (!file_exists(dirname($tokenPath))) {
mkdir(dirname($tokenPath), 0700, true);
}
file_put_contents($tokenPath, json_encode($client->getAccessToken()));
}
return $client;
}
function createCalendar($service){
$calendar = new Google_Service_Calendar_Calendar();
$calendar->setSummary('calendarSummary');
$calendar->setTimeZone('America/Los_Angeles');
try {
$createdCalendar = $service->calendars->insert($calendar);
echo $createdCalendar->getId();
return $createdCalendar->getId();
} catch(Exception $e) {
printf('An error occured creating the Calendar ' . $e->getMessage());
return null;
}
}
function insertMyevents($service, $calendarId){
$event = new Google_Service_Calendar_Event(array(
'summary' => 'Google I/O 2019',
'location' => '800 Howard St., San Francisco, CA 94103',
'description' => 'A chance to hear more about Google\'s developer products.',
'start' => array(
'dateTime' => '2019-11-13T09:00:00-07:00',
'timeZone' => 'America/Los_Angeles',
),
'end' => array(
'dateTime' => '2019-11-14T17:00:00-07:00',
'timeZone' => 'America/Los_Angeles',
)
));
try{
$event = $service->events->insert($calendarId, $event);
} catch(Exception $e) {
printf('An error occured inserting the Events ' . $e->getMessage());
}
}
if (php_sapi_name() != 'cli') {
throw new Exception('This application must be run on the command line.');
}
/**
* Returns an authorized API client.
* #return Google_Client the authorized client object
*/
// Get the API client and construct the service object.
$client = getClient();
$service = new Google_Service_Calendar($client);
// Creeate new calendar
$calendarId = createCalendar($service);
// Insert events into new Calendar if it was created succesfully
if($calendarId){
insertMyevents($service, $calendarId);
}
You were creating the $client in the wrong way without setting all the previous steps as it is said in the Quickstart. I also recommend you to check the next links, which bring some examples on how to use the Calendar API for PHP and the docs from all the methods you could use:
Calendars: insert
Events: insert
Calendar API - PHP
I need to use google calendar on my site.
I tested it on my local and it works:
require_once (load_runner::get_dir('LIBS') . "/google-api-php-client-2.2.0/vendor/autoload.php");
define('APPLICATION_NAME', 'Google Calendar API PHP Quickstart');
define('CREDENTIALS_PATH', '~/.credentials/calendar-php-quickstart.json');
define('CLIENT_SECRET_PATH', __DIR__ . '/client_secret.json');
// If modifying these scopes, delete your previously saved credentials
// at ~/.credentials/calendar-php-quickstart.json
define('SCOPES', implode(' ', array(
Google_Service_Calendar::CALENDAR)
));
/*
if (php_sapi_name() != 'cli') {
throw new Exception('This application must be run on the command line.');
}*/
/**
* Returns an authorized API client.
* #return Google_Client the authorized client object
*/
function getClient() {
$client = new Google_Client();
$client->setApplicationName(APPLICATION_NAME);
$client->setScopes(SCOPES);
$client->setAuthConfig(CLIENT_SECRET_PATH);
$client->setAccessType('offline');
// Load previously authorized credentials from a file.
$credentialsPath = expandHomeDirectory(CREDENTIALS_PATH);
if (file_exists($credentialsPath)) {
$accessToken = json_decode(file_get_contents($credentialsPath), true);
} else {
// Request authorization from the user.
$authUrl = $client->createAuthUrl();
printf("Open the following link in your browser:\n%s\n", $authUrl);
print 'Enter verification code: ';
$authCode = trim(fgets(STDIN));
// Exchange authorization code for an access token.
$accessToken = $client->fetchAccessTokenWithAuthCode($authCode);
// Store the credentials to disk.
if(!file_exists(dirname($credentialsPath))) {
mkdir(dirname($credentialsPath), 0700, true);
}
file_put_contents($credentialsPath, json_encode($accessToken));
printf("Credentials saved to %s\n", $credentialsPath);
}
$client->setAccessToken($accessToken);
// Refresh the token if it's expired.
if ($client->isAccessTokenExpired()) {
$client->fetchAccessTokenWithRefreshToken($client->getRefreshToken());
file_put_contents($credentialsPath, json_encode($client->getAccessToken()));
}
return $client;
}
/**
* Expands the home directory alias '~' to the full path.
* #param string $path the path to expand.
* #return string the expanded path.
*/
function expandHomeDirectory($path) {
$homeDirectory = getenv('HOME');
if (empty($homeDirectory)) {
$homeDirectory = getenv('HOMEDRIVE') . getenv('HOMEPATH');
}
return str_replace('~', realpath($homeDirectory), $path);
}
// Get the API client and construct the service object.
$client = getClient();
$guzzleClient = new \GuzzleHttp\Client(array( 'curl' => array( CURLOPT_SSL_VERIFYPEER => false, ), ));
$client->setHttpClient($guzzleClient);
$service = new Google_Service_Calendar($client);
// Print the next 10 events on the user's calendar.
$calendarId = 'primary';
$optParams = array(
'maxResults' => 10,
'orderBy' => 'startTime',
'singleEvents' => TRUE,
'timeMin' => date('c'),
);
$results = $service->events->listEvents($calendarId, $optParams);
if (count($results->getItems()) == 0) {
print "No upcoming events found.\n";
} else {
print "Upcoming events:\n";
foreach ($results->getItems() as $event) {
$start = $event->start->dateTime;
if (empty($start)) {
$start = $event->start->date;
}
printf("%s (%s)\n", $event->getSummary(), $start);
}
}
Tutorial says that I need to run my app with command line ( for get verification code). But how run my script without command line?
Assuming you are following this guide
it states
The authorization flow in this example is designed for a command-line application. For information on how to perform authorization in a web application, see Using OAuth 2.0 for Web Server Applications.
See Using OAuth 2.0 for Web Server Applications:
Open the Credentials page in the API Console.
Click "Create credentials > OAuth client ID."
Complete the form. Set the application type to Web application. > > Applications that use languages and frameworks like PHP, Java, Python, Ruby, and .NET must specify authorized redirect URIs. The redirect URIs are the endpoints to which the OAuth 2.0 server can send responses. For testing, you can specify URIs that refer to the local machine, such as http://localhost:8080.
I am creating a booking engine which uses Google calendar.
Needed:
Get all events in time frame (day, week, month)
Check availability for time frame, freebusy (30 min, hour)
Post event if #2 was true
Currently I can get the events and check availability using the command line app I created following this tutorial by Google. But it still asks me to authenticate in browser, which is not what I want, as the calendar would always be the same and user won't have access to it.
My code so far:
<?php
require_once 'vendor/autoload.php';
define('APPLICATION_NAME', 'Google Calendar API PHP Quickstart');
define('CREDENTIALS_PATH', '~/.credentials/calendar-php-quickstart.json');
define('CLIENT_SECRET_PATH', 'client_secret.json');
// If modifying these scopes, delete your previously saved credentials
// at ~/.credentials/calendar-php-quickstart.json
define('SCOPES', implode(' ', array(
Google_Service_Calendar::CALENDAR_READONLY)
));
if (php_sapi_name() != 'cli') {
throw new Exception('This application must be run on the command line.');
}
/**
* Returns an authorized API client.
* #return Google_Client the authorized client object
*/
function getClient() {
$client = new Google_Client();
$client->setApplicationName(APPLICATION_NAME);
$client->setScopes(SCOPES);
$client->setAuthConfigFile(CLIENT_SECRET_PATH);
$client->setAccessType('offline');
// Load previously authorized credentials from a file.
$credentialsPath = expandHomeDirectory(CREDENTIALS_PATH);
if (file_exists($credentialsPath)) {
$accessToken = file_get_contents($credentialsPath);
} else {
// Request authorization from the user.
$authUrl = $client->createAuthUrl();
printf("Open the following link in your browser:\n%s\n", $authUrl);
print 'Enter verification code: ';
$authCode = trim(fgets(STDIN));
// Exchange authorization code for an access token.
$accessToken = $client->authenticate($authCode);
// Store the credentials to disk.
if(!file_exists(dirname($credentialsPath))) {
mkdir(dirname($credentialsPath), 0700, true);
}
file_put_contents($credentialsPath, $accessToken);
printf("Credentials saved to %s\n", $credentialsPath);
}
$client->setAccessToken($accessToken);
// Refresh the token if it's expired.
if ($client->isAccessTokenExpired()) {
$client->refreshToken($client->getRefreshToken());
file_put_contents($credentialsPath, $client->getAccessToken());
}
return $client;
}
/**
* Expands the home directory alias '~' to the full path.
* #param string $path the path to expand.
* #return string the expanded path.
*/
function expandHomeDirectory($path) {
$homeDirectory = getenv('HOME');
if (empty($homeDirectory)) {
$homeDirectory = getenv("HOMEDRIVE") . getenv("HOMEPATH");
}
return str_replace('~', realpath($homeDirectory), $path);
}
// Get the API client and construct the service object.
$client = getClient();
$service = new Google_Service_Calendar($client);
// Print the next 10 events on the user's calendar.
$calendarId = 'pgsgh5dp4a5seur91fvn86bn3o#group.calendar.google.com';
$optParams = array(
'maxResults' => 10,
'orderBy' => 'startTime',
'singleEvents' => TRUE,
'timeMin' => '2005-08-15T15:52:01+0000',
);
$results = $service->events->listEvents($calendarId, $optParams);
if (count($results->getItems()) == 0) {
print "No upcoming events found.\n";
} else {
print "Upcoming events:\n";
foreach ($results->getItems() as $event) {
$start = $event->start->dateTime;
if (empty($start)) {
$start = $event->start->date;
}
printf("%s (%s)\n", $event->getSummary(), $start);
}
}
?>
Next steps:
How to skip the client side authentication?
How to turn everything into a web application instead of command line one?