Thanks for your time. I've found documentation on how to do this for public calendars, but I need it for a calendar which won't be shared with the world.
This is my code:
include( __DIR__ . '/composer/vendor/google/apiclient/autoload.php' );
$client_email = 'me#googletokenaccount.com';
$private_key = file_get_contents('/home/serverSecret.json');
$scopes = array( Google_Service_Drive::DRIVE_METADATA_READONLY );
$credentials = new Google_Auth_AssertionCredentials( $client_email, $scopes, $private_key );
$client = new Google_Client();
$client->setAssertionCredentials($credentials);
if ( $client->getAuth()->isAccessTokenExpired() )
{
$client->getAuth()->refreshTokenWithAssertion();
}
$client->setApplicationName("A Calendar");
$cal = new Google_Service_Calendar($client);
$calendarId = 'me#gmail.com';
$params = array( 'singleEvents' => true, 'orderBy' => 'startTime', 'timeMin' => date(DateTime::ATOM), 'maxResults' => 7 );
$events = $cal->events->listEvents($calendarId, $params);
$calTimeZone = $events->timeZone;
date_default_timezone_set($calTimeZone);
foreach ($events->getItems() as $event)
{
// Get the timings
$eventDateStr = $event->start->dateTime;
if(empty($eventDateStr)) { $eventDateStr = $event->start->date; } // Handle all-day events
$temp_timezone = $event->start->timeZone;
// Timezone override if applicable
if (!empty($temp_timezone)) { $timezone = new DateTimeZone($temp_timezone); }
else { $timezone = new DateTimeZone($calTimeZone); }
// Set up the timings
$eventdate = new DateTime($eventDateStr,$timezone);
$link = $event->htmlLink;
$TZlink = $link . "&ctz=" . $calTimeZone;
$newmonth = $eventdate->format("M");
$newday = $eventdate->format("j");
?>
<div class="event-container">
<div class="eventDate">
<span class="month"><?=$newmonth?></span>
<br />
<span class="day"><?=$newday?></span>
<span class="dayTrail"></span>
</div>
<div class="eventBody">
<?=$event->summary?>
</div>
</div>
<?php
}
?>
The above works when I use it with a public calendar using a client key but not when the calendar is made private. I need to know how to authenticate for private calendars.
You need the OAuth 2.0 service to access the private data:You might need to create a service account:
Typically, an application uses a service account when the application
uses Google APIs to work with its own data rather than a user's data.
For example, an application that uses Google Cloud Datastore for data
persistence would use a service account to authenticate its calls to
the Google Cloud Datastore API.
https://developers.google.com/identity/protocols/OAuth2ServiceAccount
Related
Working on a WP plugin. It's end purpose is to serve as an inspection calendar for home inspectors. We're working with a Google Calendar that is already loaded full of events.
I am authenticating via Oauth2 & a Service account. The plugin needs only to access the inspection company's data, no other private user data.
Here's the code:
// Set up identity ------------------------------------.
$client_email = "XXXXXX#XXXXXXXXXX.iam.gserviceaccount.com";
$private_key = file_get_contents( EC_INSPECT_CAL_INC . "/HE_Web_1.p12" );
$scope = [ "https://www.googleapis.com/auth/calendar","https://www.googleapis.com/auth/calendar.readonly","https://www.google.com/calendar/feeds" ];
$credentials = new \Google_Auth_AssertionCredentials(
$client_email,
$scope,
$private_key
);
// Build Config Obj ------------------------------------.
$config = new \Google_Config();
$config->setClassConfig('Google_Cache_File', array('directory' => EC_INSPECT_CAL_INC . '/tmp/cache'));
// Instantiate Client Connection ------------------------.
$client = new \Google_Client( $config );
$client->setAssertionCredentials( $credentials );
if( $client->getAuth()->isAccessTokenExpired() )
$client->getAuth()->refreshTokenWithAssertion();
$service = new \Google_Service_Calendar( $client );
$calendarList = $service->calendarList->listCalendarList();
while( true )
{
foreach( $calendarList->getItems() as $calendarListEntry )
{
// get events
$events = $service->events->listEvents( $calendarListEntry->id );
foreach( $events->getItems() as $event )
echo "-----".$event->getSummary() . "<br>";
}
$pageToken = $calendarList->getNextPageToken();
if( !$pageToken ) break;
$optParams = array('pageToken' => $pageToken);
$calendarList = $service->calendarList->listCalendarList($optParams);
}
}
If I var_dump the following:
var_dump( $service->calendarList->listCalendarList() );
It results in:
array(0) { }
My wife would like me to stop cursing in front of the dogs, but I can't seem to figure out what I'm overlooking. The calendar is loaded with content, and I (AFAIK) am authenticating ... So where's the goods??
I use Google API to retrieve analytics data and display them on my website. it worked fine for a month, but the last four days I get this error :
Error refreshing the OAuth2 token, message: '{ "error" : "invalid_grant" }'
Here is the code :
<?php
require_once ('src/Google/autoload.php');
$client = new Google_Client();
$client->setApplicationName( 'GAFetchData' );
$client->setAssertionCredentials(
new Google_Auth_AssertionCredentials(
// Google client ID email address
'xxxxx-xxxxxxxxxx#developer.gserviceaccount.com',
array('https://www.googleapis.com/auth/analytics.readonly'),
file_get_contents( $Path.'gapii/'.'GAFetchData-xxxxxxxx.p12' )
)
);
$client->setClientId( 'xxxxx-xxxxxxxxxx.apps.googleusercontent.com' );
$client->setAccessType( 'offline_access' );
$analytics = new Google_Service_Analytics( $client );
$analytics_id = 'ga:xxxxxx';
try {
$optParams = array();
$metrics = 'ga:pageviews';
$start_date = '7daysAgo';
$end_date = 'today';
$optParams['dimensions'] = 'ga:pagePath';
$optParams['filters'] = 'ga:pagePath!#=rech;';
$optParams['max-results'] = '10000';
$result = $analytics->data_ga->get( $analytics_id, $start_date, $end_date, $metrics, $optParams);
if( $result->getRows() ) { $items = $result->getRows(); }
}
catch(Exception $e) { echo $e->getMessage();}
?>
Issue solved !
It was caused by the server's clock, I just synchronise it with a NTP server using the following command (Ubuntu in my case) :
sudo ntpdate 3.pool.ntp.org
You will find a list of time servers from the
public NTP time server list
hope that helps !
I'm using Google API PHP client to add events to my calendar. ID is returned successfully after the insert & When I fetch that event using the ID it displays summary & everything correctly & for some reason , the event is showing up in my calendar
I'm using Service Account Credentials. Is there something to be enabled to get this working?
Here's my Code
session_start();
require dirname(__FILE__).'/google-api-php-client-master/autoload.php';
$client_id = '<client ID>';
$service_account_name = '<Service Account Name>';
$key_file_location = dirname(__FILE__).'/API-Project-96c2a9122085.p12';
if (!strlen($service_account_name) || !strlen($key_file_location)) {
echo missingServiceAccountDetailsWarning();
}
$client = new Google_Client();
$client->setApplicationName("Client_Library_Examples");
$service = new Google_Service_Calendar($client);
if (isset($_SESSION['service_token'])) {
$client->setAccessToken($_SESSION['service_token']);
}
$key = file_get_contents($key_file_location);
$cred = new Google_Auth_AssertionCredentials($service_account_name,array('https://www.googleapis.com/auth/calendar'),$key);
$client->setAssertionCredentials($cred);
if ($client->getAuth()->isAccessTokenExpired()) {
$client->getAuth()->refreshTokenWithAssertion($cred);
}
$_SESSION['service_token'] = $client->getAccessToken();
$event = new Google_Service_Calendar_Event();
$event->setSummary("WHY IS THIS NOT WOKING?");
$start = new Google_Service_Calendar_EventDateTime();
$start->setDateTime(date('Y-m-d\TH:i:s',strtotime('2014-12-24 10:00:00')));
$start->setTimeZone('Australia/Melbourne');
$event->setStart($start);
$end = new Google_Service_Calendar_EventDateTime();
$end->setDateTime(date('Y-m-d\TH:i:s',strtotime('2014-12-26 12:00:00')));
$end->setTimeZone('Australia/Melbourne');
$event->setEnd($end);
$newEvent = $service->events->insert('primary', $event);
$newEvent->getId();
$event = $service->events->get('primary', $newEvent->getId());
echo '<pre>'; print_r($event); echo '</pre>';
With the new Google_Client API, you need to share your calendar to yourself.
$scope = new Google_Service_Calendar_AclRuleScope();
$scope->setType('user');
$scope->setValue( 'Your Email Goes Here' );
$rule = new Google_Service_Calendar_AclRule();
$rule->setRole( 'owner' );
$rule->setScope( $scope );
$result = $service->acl->insert('primary', $rule);
Let me know if you still have issue.
How do I use this function?
I have a userid and a group id.
The error message I get when I try to add my fields has to do with the Google_Member instance. How would I use this in my PHP code?
BTW it is from the Google Apps API
/**
* Add user to the specified group. (members.insert)
*
* #param string $groupKey Email or immutable Id of the group
* #param Google_Member $postBody
* #param array $optParams Optional parameters.
* #return Google_Member
*/
public function insert($groupKey, Google_Member $postBody, $optParams = array()) {
$params = array('groupKey' => $groupKey, 'postBody' => $postBody);
$params = array_merge($params, $optParams);
$data = $this->__call('insert', array($params));
if ($this->useObjects()) {
return new Google_Member($data);
} else {
return $data;
}
}
Follow the instructions listed here to setup the application in Google Console and to enable Domain Delegation of Authority.
http://jamespeckham.com/wordpress/?p=9 (Thank you JDPeckham)
Download the client from: https://code.google.com/p/google-api-php-client/downloads/list
Here is my working code:
require_once "google-api-php-client/src/Google_Client.php";
require_once "google-api-php-client/src/contrib/Google_DirectoryService.php";
require_once "google-api-php-client/src/contrib/Google_Oauth2Service.php";
session_start();
const GROUP_SCOPE = 'https://www.googleapis.com/auth/admin.directory.group';
const SERVICE_ACCOUNT_EMAIL = '.....#developer.gserviceaccount.com';
const SERVICE_ACCOUNT_PKCS12_FILE_PATH = '/path/to/...privatekey.p12';
const CLIENT_ID = '....apps.googleusercontent.com';
$userEmail = 'email-address-with-admin-rights#domain.com';
$key = file_get_contents(SERVICE_ACCOUNT_PKCS12_FILE_PATH);
$auth = new Google_AssertionCredentials(SERVICE_ACCOUNT_EMAIL, array(GROUP_SCOPE), $key, 'notasecret', 'http://oauth.net/grant_type/jwt/1.0/bearer', $userEmail);
$client = new Google_Client();
$client->setClientId(CLIENT_ID); // from API console
$client->setApplicationName("Project Name from API Console");
$client->setUseObjects(true);
$client->setAssertionCredentials($auth);
$member = new Google_Member(array('email' => 'abc#testing.com',
'kind' => 'admin#directory#member',
'role' => 'MEMBER',
'type' => 'USER'));
$service = new Google_DirectoryService($client);
$results = $service->members->insert('mailing-list-name#domain.com', $member);
print '<h2>Response Result:</h2><pre>' . print_r($results, true) . '</pre>';
require_once $_SERVER['DOCUMENT_ROOT'] . '/../vendor/autoload.php';
$updateName = $_POST["name"];
$updateEmail = $_POST["email"];
//USING A SERVICE ACCOUNT TO CALL GOOGLE CLIENT
putenv('GOOGLE_APPLICATION_CREDENTIALS=/home/myserver/mywebsite/credentialsfile.json');
$client = new Google\Client();
// MY ACCOUNT DATA HERE
$client_id = 'clientid';
$service_account_name = 'serviceaccountemailhere'; //Email Address
$key_file_location = '/home/myserver/mywebsite/mykeyfile.json'; //key.p12
$agencyAdminGroupKey = 'emailforGroupKey#gmial.com'; //agency admins group key
$memberKey = $updateEmail; //$memberemail
$domain = 'yourwebsite.com';
if (getenv('GOOGLE_APPLICATION_CREDENTIALS')) {
// use the application default credentials
$client->useApplicationDefaultCredentials();
} else {
echo missingServiceAccountDetailsWarning();
return;
}
// set the scope(s) that will be used
//$client->setScopes(array('https://www.googleapis.com/auth/admin.directory.group'));
$client->setScopes(array('https://www.googleapis.com/auth/admin.directory.group'));
// this is needed only if you need to perform
// domain-wide admin actions, and this must be
// an admin account on the domain; it is not
// necessary in your example but provided for others
$client->setSubject('yourgoogleaccountemail#domain.com');
$client->setApplicationName("Client_Library_Examples");
$client->setDeveloperKey("paste-your-developer-key");
$service = new Google_Service_Directory($client);
$member = new Google_Service_Directory_Member( array('email' => $updateEmail,
'kind' => 'admin#directory#member',
'role' => 'MEMBER',
'type' => 'USER',
"deliverySettings" => 'DAILY'));
//GET request to google groups server
// $results = $service->members->listMembers($groupKey);
$results = $service->members->insert($agencyAdminGroupKey, $member);
Here are some useful links:
https://github.com/googleapis/google-api-php-client
https://developers.google.com/admin-sdk/directory/v1/quickstart/php
https://developers.google.com/resources/api-libraries/documentation/admin/directory_v1/php/latest/class-Google_Service_Directory_Groups.html
https://developers.google.com/admin-sdk/directory/reference/rest/v1/members
i am trying to send a bunch of events via an Batch Request to Google Calendar.
But i cant figur out how to do. https://developers.google.com/google-apps/calendar/batch doesnt help me.
require_once 'google-api-php-client/src/Google_Client.php';
require_once 'google-api-php-client/src/contrib/Google_CalendarService.php';
$client = new Google_Client();
$client->setUseBatch(true);
$batch = new Google_BatchRequest();
$uri = 'http://www.google.com/calendar/feeds/default/private/full/batch';
$batchContent = file_get_contents('xxxxx/google-api-php-client/batch.xml');
$batch->add($batchContent);
batch.xml contains 2 -items.
Thats all so far. But nothing happened.
I also have tried
$batch->execute()
But thats throws error without message.
My question: How to send a Batch via PHP to Google Calendar ?
I'm using the latest version of Google APIs Client Library for PHP (Google Calendar v.3). I use batch operations for pushing instructor lessons to Google Calendar. Here is my example of code for you (multipleInsert function). Good luck!
<?php
require_once(APPPATH . 'libraries/Google/Client.php');
require_once(APPPATH . 'libraries/Google/Http/Batch.php');
require_once(APPPATH . 'libraries/Google/Service/Calendar.php');
class My_google_calendar
{
...
/** Add single Event for Student */
function addEvent($lesson, $instructor, $return_request = false, $enable_attendees = false)
{
$calendar = $this->getGoogleCalendar(); // get calendar service variable
$lesson_from = date(DATE_RFC3339, $lesson->from);
$lesson_to = date(DATE_RFC3339, $lesson->from + $lesson->duration);
$event = new Google_Service_Calendar_Event();
$event->setSummary('Lesson with student: '$lesson->student_full_name);
$start = new Google_Service_Calendar_EventDateTime();
$start->setDateTime($lesson_from);
$start->setTimeZone($this->getGoogleCalendarTimeZone());
$event->setStart($start);
$end = new Google_Service_Calendar_EventDateTime();
$end->setDateTime($lesson_to);
$end->setTimeZone($this->getGoogleCalendarTimeZone());
$event->setEnd($end);
$event->setColorId(4);
$description = "...";
$event->setDescription($description);
if (isset($student->email) && $enable_attendees) {
$attendee1 = new Google_Service_Calendar_EventAttendee();
$attendee1->setResponseStatus('needsAction');
$attendee1->setEmail($student->email);
$attendees = array($attendee1);
$event->setAttendees($attendees);
}
$createdEvent = $this->calendar->events->insert($this->calendar_id, $event, array('fields' => 'id'));
return $return_request ? $createdEvent : $createdEvent->getId();
}
/** Push group of events to the Calendar */
function multipleInsert ($lessons, $instructor)
{
$this->use_batch = true;
$this->client->setUseBatch($this->use_batch);
$batch = new Google_Http_Batch($this->client);
$optParams = array('fields' => 'status,updates');
foreach($lessons as $time => $lesson) {
$lesson = array_shift($group['lessons']);
$req = $this->addEvent($lesson, $instructor, true);
$batch->add($req, $time);
}
}
$results = $batch->execute();
return $results;
}
}
in the newer versions, you should use
$batch = $service->createBatch();
instead of
$batch = new Google_Http_Batch($this->client);
reference