linking google calendar API with laravel to create calendars and events - php

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

Related

PHP Google Service account auth Calendar API

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);
}
}

How to get refreshed token from Google Calendar API

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.

Understanding my code, Where are the tokens coming from?

i need to add events to the google calendar with the api, on my localhost i made it work, however i cant remember where the token comes from, can you guys remind me this? the toke.json file
<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
// If you've used composer to include the library
require '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('Calendar API Test');
$client->setScopes( ['https://www.googleapis.com/auth/calendar'] );
// $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.
// 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: ';
// Check Param on redirected URL, for ?code=#############
// you have to copy only ?code= $_GET parms data and paste in console
$authCode = trim(fgets(STDIN)); // Get code after Authentication
// 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;
}
$client = getClient();
$accessToken = $client->getAccessToken();
$service = new Google_Service_Calendar($client);
$summary = $_POST['summary'];
$description = $_POST['description'];
$fecha_inicio = $_POST['fecha_inicio'];
$hora_inicio = $_POST['hora_inicio'];
$fecha_fin = $_POST['fecha_fin'];
$h_inicio = explode(" ",$hora_inicio);
$hora = $h_inicio[0].":00";
$minutos = "00:30:00";
$secs = strtotime($minutos)-strtotime("00:00:00");
$result = date("H:i:s",strtotime($hora)+$secs);
$inicio = $fecha_inicio."T".$hora_inicio;
$fin = $fecha_fin."T".$result;
$attendee = $_POST['attendee'];
$_info = array(
'summary' => $summary,
'location' => 'address',
'description' => $description,
'start' => array(
'dateTime' => $inicio,
'timeZone' => 'America/Bogota',
),
'end' => array(
'dateTime' => $fin,
'timeZone' => 'America/Bogota',
),
'attendees' => array(
array('email' => $attendee)
),
'reminders' => array(
'useDefault' => FALSE,
'overrides' => array(
array('method' => 'email', 'minutes' => 24 * 60),
array('method' => 'popup', 'minutes' => 10),
),
),
);
//die(var_dump($_info));
$event = new Google_Service_Calendar_Event($_info);
$opts = array('sendNotifications' => true, 'conferenceDataVersion' => true); // send Notification immediately by Mail or Stop Hangout Call Link
$event = $service->events->insert( 'primary', $event, $opts );
die(var_dump($event));
printf('Event created: %s\n', $event->htmlLink);
?>
When your code runs the first time the user will be asked to consent to your application accessing their data. If the user consents then your code is storing the access token and refresh token in a file called token.json.
The next time the code runs it will check isAccessTokenExpired if it is it will use the refresh token stored in token.json to request a new access token and grant you access to the users data.
The way your code is written this will only be working for a single user as you are only storing to a single token.json file.

Cannot Create Google Docs using PHP API

$client->setAccessToken($_SESSION['access_token']);
$service = new Google_Service_Docs($client);
$title = $_SESSION['class'].' - '.date("Y-m-d");
$document = new Google_Service_Docs_Document(array(
'title' => $title
));
//everything works until here. For some reason, this line doesn't run. It doesn't even proceed.
$document = $service->documents->create($document);
//this line isn't even printed
print_r("success!");
$documentId = $document->documentId;
header('Location: https://docs.google.com/document/d/'.$documentId);
exit();
I've been scratching my head over this for hours. I have no idea why I can't create a new Google Doc. There's absolutely no examples of this online other than from Google and most of the code here is copied straight from them.
This is what I get when I print $document after assigning the title but before executing the service to create a new document.
Google_Service_Docs_Document Object
(
[bodyType:protected] => Google_Service_Docs_Body
[bodyDataType:protected] =>
[documentId] =>
[documentStyleType:protected] => Google_Service_Docs_DocumentStyle
[documentStyleDataType:protected] =>
[footersType:protected] => Google_Service_Docs_Footer
[footersDataType:protected] => map
[footnotesType:protected] => Google_Service_Docs_Footnote
[footnotesDataType:protected] => map
[headersType:protected] => Google_Service_Docs_Header
[headersDataType:protected] => map
[inlineObjectsType:protected] => Google_Service_Docs_InlineObject
[inlineObjectsDataType:protected] => map
[listsType:protected] => Google_Service_Docs_DocsList
[listsDataType:protected] => map
[namedRangesType:protected] => Google_Service_Docs_NamedRanges
[namedRangesDataType:protected] => map
[namedStylesType:protected] => Google_Service_Docs_NamedStyles
[namedStylesDataType:protected] =>
[positionedObjectsType:protected] => Google_Service_Docs_PositionedObject
[positionedObjectsDataType:protected] => map
[revisionId] =>
[suggestedDocumentStyleChangesType:protected] => Google_Service_Docs_SuggestedDocumentStyle
[suggestedDocumentStyleChangesDataType:protected] => map
[suggestedNamedStylesChangesType:protected] => Google_Service_Docs_SuggestedNamedStyles
[suggestedNamedStylesChangesDataType:protected] => map
[suggestionsViewMode] =>
[title] => Computer 9 - Charity - 2021-01-04
[internal_gapi_mappings:protected] => Array
(
)
[modelData:protected] => Array
(
)
[processed:protected] => Array
(
)
)
PHP Quickstart provides full tutorial on how to read Google Document using Google Docs API.
To create new document, use the example above and replace:
$documentId = '195j9eDD3ccgjQRttHhJPymLJUCOUjs-jmwTrekvdjFE';
$doc = $service->documents->get($documentId);
printf("The document title is: %s\n", $doc->getTitle());
with:
$title = 'My Document';
$document = new Google_Service_Docs_Document(array(
'title' => $title
));
$document = $service->documents->create($document);
printf("Created document with title: %s\n", $document->title);
Also, Make sure to change the SCOPE of your project to Google_Service_Docs::DOCUMENTS and before running your code, delete the Token.json to restart the process of verification and to create a new token with the scope you've specified.
Your code should look like these:
<?php
require __DIR__ . '/vendor/autoload.php';
/**
* Returns an authorized API client.
* #return Google_Client the authorized client object
*/
function getClient()
{
$client = new Google_Client();
$client->setApplicationName('Google Docs API PHP Quickstart');
$client->setScopes(Google_Service_Docs::DOCUMENTS);
$client->setAuthConfig('credentials.json');
$client->setAccessType('offline');
// Load previously authorized credentials from a file.
$credentialsPath = expandHomeDirectory('token.json');
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();
$service = new Google_Service_Docs($client);
$title = 'My Document';
$document = new Google_Service_Docs_Document(array(
'title' => $title
));
$document = $service->documents->create($document);
printf("Created document with title: %s\n", $document->title);
Reference:
DocsScopes
Creating Document

Google Calendar Push Notifications SetUp

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

Categories