I'm trying to find out how to integrate the Google calendar using the v3 API with an existing application for a local non-profit organization.
The intent is the following: our organisation has a general public Google calendar (with Google account) that both visitors and active volunteers can subscribe to or show in their own calendar. We are in the process of developing a simple management web application (written in PHP) in which task forces can be created and managed. The core functionality is planning meetings (and managing the notes of these meetings, but this is not relevant to the question.). Users are notified via e-mail when a meeting is planned. It would also be very nice if the planned meetings could be programmatically added to the Google calendar. I now have to do this manually for every planned meeting.
I've been reading the documentation over at developers.google.com and the Google Code page for the php library for two days now and I find myself lost in different authentication schemes, account types, keys and many more, to the point where I'm starting to think that this is not an intended use case.
To come to the core of my question: I need to access the organisations Google calendar, and be able to post events, without any human interaction. Is this even possible? If so, Which account do i need to create (web app, service account or installed app?) in the Google APIs console? How would I authenticate the application? Do I need to grant rights to the application somehow? Is there an example somewhere I can refer to (possibly with a different API?)?
From what I've seen, the critical difference with all examples in Google's documentation, is that I do not want to modify a current or end-user's calendar, but the same calendar, regardless of the logged in user. (user authentication does not happen with the Google api, we rolled our own.) The redirect/user consent mechanism isn't exactly useful for me.
In this question, the asker is trying to achieve something similar. The full answer is not provided however. I can't seem to find some of the sources referred to in the accepted response.
You should be able to make a start with the sample code from here: https://code.google.com/p/google-api-php-client/source/browse/trunk/examples/calendar/simple.php
And referring to here: https://developers.google.com/google-apps/calendar/v3/reference/events/quickAdd#examples
Regarding authentication, you'll need to visit https://code.google.com/apis/console?api=calendar to create and obtain the relevant keys, but it's not very clear so you might need to play around a bit.
I created a "service account" for API access, which gave me the client ID and let me download a private key, but I'm not sure without trying things further how that applies to the code sample linked above.
EDIT
I just found some old code that still works which creates events in calendars using the ZendGdata-1.10.2 library:
//for Google Calendar
set_include_path('./ZendGdata-1.10.2/library');
function createAlert($message, $date) {
$google = array();
// Define credentials for the Google Calendar account
$google['GCAL_USER'] = "info#example.com";
$google['GCAL_PASS'] = "password123";
// Include Zend GData client library
require_once 'Zend/Loader.php';
Zend_Loader::loadClass('Zend_Gdata');
Zend_Loader::loadClass('Zend_Gdata_ClientLogin');
Zend_Loader::loadClass('Zend_Gdata_Calendar');
// Get Google Calendar service name (predefined service name for calendar)
$service = Zend_Gdata_Calendar::AUTH_SERVICE_NAME;
// Authenticate with Google Calendar
$client = Zend_Gdata_ClientLogin::getHttpClient($google['GCAL_USER'], $google['GCAL_PASS'], $service);
date_default_timezone_set('GMT');
// Create a calendar object
$calendar = new Zend_Gdata_Calendar($client);
// Create a new event
$event = $calendar->newEventEntry();
$event->title = $calendar->newTitle($message);
// Add our message as the event content
$event->content = $calendar->newContent($message);
$when = $calendar->newWhen();
// Min time is 5 mins away
if ($date == "" || strtotime('+5 minute') >= strtotime($date)+300) {
$when->startTime = date("c", strtotime('+5 minute'));
$when->endTime = date("c", strtotime('+10 minute'));
} else {
$when->startTime = date("c", strtotime($date)+300);
$when->endTime = date("c", strtotime($date)+600);
}
$event->when = array($when);
// Setup reminders for event
$reminder = $calendar->newReminder();
$reminder->method = "all";
$when = $event->when[0];
$when->reminders = array($reminder);
// Send the new event to be added to Google Calendar
if (defined('GCAL_ID')) {
$newEvent = $calendar->insertEvent($event, 'http://www.google.com/calendar/feeds/' . $google['GCAL_ID'] . '/private/full');
} else {
$newEvent = $calendar->insertEvent($event);
}
// Check response
if (stripos($newEvent->id->text, "http://www.google.com/calendar/feeds/". str_replace('#', '%40', $google['GCAL_ID']) ."/private/full/") !== false) {
return "Sent!\n";
} else {
return $newEvent->id->text;
}
}
Related
I manage approximately 200 Google My business accounts, all being owned under an email XXX#YYY.com
I would like to use the Google My Business API using a PHP SDK to retrieve all types of stats regarding each accounts (ie. view per timeframe, view through map, view through SERP, etc...).
I did get the authorization to use the Google My Business API and I downloaded the php SDK: https://developers.google.com/my-business/samples/google-api-services-mybusiness-v4p9-php-rev-20210224-1.zip?hl=fr
I also created a service account (which I'm really not familiar with) in order to auth with the library.
Now here is my code :
$client = new Google_Client();
$client->useApplicationDefaultCredentials();
// set the service account json file location manually
$client->setAuthConfig(__DIR__.'/../global/yyyyy-xxxx-xxxxxxxxxx.json');
$client->setApplicationName("yyyyyb");
// set the scope to access GMBs
$client->setScopes([
"https://www.googleapis.com/auth/business.manage"
]);
$this->client = $client;
$mybusinessService = new Google_Service_Mybusiness($client);
$accounts = $mybusinessService->accounts;
$accountsList = $accounts->listAccounts()->getAccounts();
echo "<pre>";
print_r($accountsList);
echo "</pre>";
$locationNames = array("Paris");
$insightReqObj = new Google_Service_MyBusiness_ReportLocationInsightsRequest();
$insightReqObj->setLocationNames($locationNames);
$basicReqObj = new Google_Service_MyBusiness_BasicMetricsRequest();
// datetime range is mandatory
// TODO :: validate to not allow more than 18 months difference
$timeRangObj = new Google_Service_MyBusiness_TimeRange();
$timeRangObj->setStartTime("2020-01-01T15:01:23Z");
$timeRangObj->setEndTime("2021-01-11T15:01:23Z");
$metricReqObj = new Google_Service_MyBusiness_MetricRequest();
$metricReqObj->setMetric('ALL');
$basicReqObj->setMetricRequests(array($metricReqObj));
$basicReqObj->setTimeRange($timeRangObj);
$insightReqObj->setBasicRequest($basicReqObj);
$allInsights = $mybusinessService->accounts_locations->reportInsights("accounts/XXXXXXXX",$insightReqObj);
echo "<pre>";
print_r($allInsights);
echo "</pre>";
There are two issues :
When I print the accountlist, I only find information about my service account, I was expecting a list of all the accounts managed by my email : XXX#YYY.com ; I realise that it makes no sense since I don't even know how to grant the service account access to the My Business account managed by this email.
Also AllInsignt generate an error :
How can I access the statistics of all the accounts managed by my Gmail account : XXX#YYY.com ?
I'm trying to get a connexion between a google Calendar account and the google calendar API to update a MySQL database based on the events contained by the google calendar. It seems that my client is set up, and now I have to get the CalendarList, but I'm having trouble here.
I took inspiration on what have been done in the quickstart.php and what is explained in the google documentation to try some tests.
The problem is that all my requests return an empty result when I use the method getItems();
My code:
function getClient()
{
$client = new Google_Client();
$client->setApplicationName('Google Calendar API PHP synchroniser');
$client->setScopes(Google_Service_Calendar::CALENDAR_READONLY);
$client->setAuthConfig('Path/To/My/AccountService/File.json');
$client->setAccessType('online');
$client->setPrompt('MyCalendarWithMyData');
// 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 {
//I don't know what to put here.
}
}
*/
return $client;
}
$client = getClient(); // based on quickstart.php
$service = new Google_Service_Calendar($client);// from the sample on documentation
$calendarList = $service->calendarList->listCalendarList();
$calendars=$calendarList->getItems();
var_dump($calendars);
My goal is when I got the calendar list to get each events relative to each calendar in the calendar list to update my database.
Thanks
G.G
What you need to remember is that a Service account is not you. A service account is a dummy user. This user has its own google calendar account, drive account and probably a few more.
If you do a
$calendar = $service->calendars->get('primary');
echo $calendar->getSummary();
You will see that in fact your service account does have a calendar. What it doesnt have is anything by default in its calendar list.
If you want it to have access to your personal Google calendar then you will need to go to the google calendar website and share the calendar with the service accounts email address. then it should be able to do the following make sure you note the calendar id for the calendar you shared with it while you are in the settings.
$calendar = $service->calendars->get('calendarid');
echo $calendar->getSummary();
If you really want it in calendar list you can add it.
$calendarListEntry = new Google_Service_Calendar_CalendarListEntry();
$calendarListEntry->setId("calendarId");
$createdCalendarListEntry = $service->calendarList->insert($calendarListEntry);
echo $createdCalendarListEntry->getSummary();
Service account set up
As i have mentioned service accounts need to be preauthorized. You need to go to the Google Calendar website and under settings for the calendar you want it to be able to access you need to share the calendar with it as shown
useful links
Oauth2 service accounts
Google developer console Service accounts
I know how to access Google Analytics data with Data Studio or with Google Apps script in Javascript:
var account = Analytics.Management.Accounts.list().items[0];
var webProperties = Analytics.Management.Webproperties.list(account.id);
...
var report = Analytics.Data.Ga.get(tableId, startDate, endDate, metric,
options);
But in PHP, how is it possible to retrieve the number of visitors of a specific website or specific page, from a Google Analytics account / property / view? i.e.:
input: analytics account login/password/website code 'UA-XXXXX-Y'
output: [19873, 17873, 13999, 21032, ..., 16321] (i.e. the number of visits on www.example.com for each of the 30 last days, as a list of integers or JSON)
You can use Google Analytics API client in PHP.
Google analytic api client library
You can use the Query Explorer to create the queries to check.
Code Example:
$analytics = new analytics('username', 'password');
$analytics->setProfileByName('user.name');
//set the date range for which you want stats for
$analytics->setMonth(date('n'), date('Y'));
// it could also be $analytics->setDateRange('YYYY-MM-DD', 'YYYY-MM-DD'))
print_r($analytics->getVisitors());
print_r($analytics->getPageviews());
The above example used the Google Analytics API client in PHP. It was the first library released in PHP. Six years later, this software is outdated. Google changed the API.
As an alternative you can use GAPI library.
Above is the example how it would work, you can include gapi class to make it functional.
GAPI Analytic Library
Another way is that you can use the Google Analytics Reporting API v4 for PHP.
You can obtain this using composer:
composer require google/apiclient:^2.0
Guide to usage of this library is at github
I use this package:
https://github.com/google/google-api-php-client
You can use it to access all the Google APIs from PHP, including of course Google Analytics
Here's an example of how to use it:
// create client object and set app name
$client = new Google_Client();
$client->setApplicationName('Your app name'); // name of your app
// set assertion credentials
$client->setAssertionCredentials(
new Google_AssertionCredentials(
'your_analytics_email#gmail.com', // email you added to GA
[
'https://www.googleapis.com/auth/analytics.readonly'),
file_get_contents('/your/key/file.p12') // keyfile you downloaded
]
)
);
// other settings
$client->setClientId('your-client-id'); // from API console
$client->setAccessType('offline_access'); // this may be unnecessary?
// create service and get data
$service = new Google_AnalyticsService($client);
$from_date = date("Y-m-d",strtotime("-30 days")); // A month
$to_date = date("Y-m-d");
$response = $service->data_ga->get(
"ga:profile_id", // profile id
"$from_date", // start date
"$to_date", // end date
"ga:uniquePageviews",
[
'dimensions' => 'ga:pagePath', // Dimensions you want to include, pagePath in this example
'sort' => '-ga:uniquePageviews', // Sort order, order by unique page views from high to low in this case
'filters' => 'ga:pagePath=~\/articles\/[a-zA-Z0-9\-]+', // example url filter
'max-results' => '50' // Max results
]
);
foreach ($response["rows"] as $row) {
// ...do whatever you want with the results
}
Also, here's a guide on how to use the Google APIs:
https://developers.google.com/api-client-library/php/start/get_started
EDIT: You need to create credentials to access the Analytics API. You do it here: https://console.cloud.google.com/flows/enableapi?apiid=analyticsreporting.googleapis.com&credential=client_key. You need to register a project first, and then create the credentials. There are three options: API key, OAuth client ID and Service Account Key. I didn't want to use OAuth, so I used the Service Account Key. You can try using the API Key, in which case replace the $client->setAssertionCredentials(...) call for $client->setDeveloperKey(your_api_key). You can't use username and password directly AFAIK.
I've been taking a look at the Google API PHP Client and would like to use it to add rows to a Google Sheet. From the code, it looks like one would use this method:
public function insert($fileId, Google_Service_Drive_Property $postBody, $optParams = array())
{
$params = array('fileId' => $fileId, 'postBody' => $postBody);
$params = array_merge($params, $optParams);
return $this->call('insert', array($params), "Google_Service_Drive_Property");
}
but I can't really tell what the parameters would be. Am I heading in the right direction? Also, not quite sure on how to connect to a specific Sheet. Please advise.
Thanks!
Use Google sheets class from zend framework 1.12. They have very nicely coded library for Google Spreadsheets
https://github.com/zendframework/zf1/tree/master/library/Zend/Gdata/Spreadsheets
I figured out how to work this and wanted to share with you guys. As I stated in a comment, I did not think using Zend's GData class was a good way for me since it's very dependent on other classes throughout the framework, thus being too heavy.
So I ended up using this Spreadsheet Client on top of Google's API. Google's API is used to authenticate my service, then I start calling the Spreadsheet Client library afterwards.
After spending over a day of Googling for various problems I had for the authentication process, here's what I did to make things work:
Created a new project for Google API here
Clicked "APIs" menu on the left side under "APIs & Auth"
Searched the Drive API and enabled it (can't remember if it was necessary)
Clicked the "Credentials" menu on the left
Clicked "Create new Client ID" button under OAuth
Selected "Service Account"
After info showed & json downloaded (not needed), I clicked "Generate new P12 Key" button
I saved the p12 file somewhere I could access it through PHP
Then in the code, I added the following lines:
$email = 'somethingsomethingblahblah#developer.gserviceaccount.com';
$CLIENT_ID = $email;
$SERVICE_ACCOUNT_NAME = $email;
$KEY_FILE = 'path/to/p12/file';
$SPREADSHEETS_SCOPE = 'https://spreadsheets.google.com/feeds';
$key = file_get_contents($KEY_FILE);
$auth = new Google_Auth_AssertionCredentials(
$SERVICE_ACCOUNT_NAME,
array($SPREADSHEETS_SCOPE),
$key
);
$client = new Google_Client();
$client->setScopes(array($SPREADSHEETS_SCOPE));
$client->setAssertionCredentials($auth);
$client->getAuth()->refreshTokenWithAssertion();
$client->setClientId($CLIENT_ID);
$accessToken = $client->getAccessToken();
Also, I had to make sure I:
Shared my spreadsheet specifically with the email address on my service account in the code above
Synced my server's time (I'm running Vagrant CentOS so it's slightly different)
I believe you can run this code with other services beyond Spreadsheets, such as Youtube, Analytics, etc., but you will need to get the correct scope link (see $SPREADSHEETS_SCOPE above). Remember, this is only when using the Service Account on the Google Console, which means you are programmatically getting data from your code. If you are looking to have others users sign in using the API, then it's different.
I have very little experience working with the google api and I'm finding it difficult to find relevant information on certain subjects.
What I'm trying to do is create a calendar that requires no log in information from the user. I want my server to add events to the calendar based off of information in a database.
I have gone into my google calendars, created a new one, and worked up some code to add events to the calendar. Then I use the iframe code that google provides to embed the calendar into my site.
The problem I'm running into is that the server wants the user to be logged in as me to add events to the calendar. Since the server is the one adding the events, I'm not really sure how to work around this. I know I need to make/use a service account so my server can "delegate domain-wide authority", but I'm not sure how to do this using the client library for PHP. No examples are provided by google. I had to download a p12 file that my server needs to make these api calls, but I'm not sure how to point to the file using the client library. Is it possible to use the php client library to hook into a service account to make these api calls? If so, how?
Any help is greatly appreciated.
I had the same problem and found the solution (in a round about way) here:
Inserting Google Calendar Entries with Service Account
First thing is to set up your Google calendar correctly (see above mentioned post which describes it very well), then download the API code for the Calendar from here https://github.com/google/google-api-php-client
It's the Download ZIP link on the right of that page.
Then here is some sample code which works for me (private keys replaced with xxxx where appropriate, but otherwise it's exactly what I'm using).
I'm now trying to find out how to read & clear a Google Calendar, which is proving even more challenging!
<?php
//
// built from example at:
// https://stackoverflow.com/questions/26064095/inserting-google-calendar-entries-with-service-account
//
$startdate = new DateTime('2015-01-29 10:00', new DateTimeZone('Europe/London'));
$startdate = $startdate->format('c');
$enddate = new DateTime('2015-01-29 10:00', new DateTimeZone('Europe/London'));
$enddate = $enddate->format('c');
//
// call function to add one event to the calendar (xxxxxxxxxxx#googlemail.com = the calendar owner)
//
calendarize('Test Appointment','Test appt description',$startdate,$enddate,'xxxxxxxxxxx#googlemail.com');
//-----------------------------------------------//
// funtion to add an event to my Google calendar //
//-----------------------------------------------//
function calendarize ($title, $desc, $start_ev_datetime, $end_ev_datetime, $cal_id) {
session_start();
require_once '../google-api-php-client-master/autoload.php';
//Google credentials
$client_id = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com';
$service_account_name = 'xxxxxxxxxxxxxxxxxxxxxxxxxx#developer.gserviceaccount.com';
$key_file_location = '../google-api-php-client-master/API Project-xxxxxxxxxx.p12';
if (!strlen($service_account_name) || !strlen($key_file_location))
echo missingServiceAccountDetailsWarning();
$client = new Google_Client();
$client->setApplicationName("Whatever the name of your app is");
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()) {
try {
$client->getAuth()->refreshTokenWithAssertion($cred);
} catch (Exception $e) {
var_dump($e->getMessage());
}
}
$_SESSION['service_token'] = $client->getAccessToken();
$calendarService = new Google_Service_Calendar($client);
$calendarList = $calendarService->calendarList;
//Set the Event data
$event = new Google_Service_Calendar_Event();
$event->setSummary($title);
$event->setDescription($desc);
$start = new Google_Service_Calendar_EventDateTime();
$start->setDateTime($start_ev_datetime);
$start->setTimeZone('Europe/London');
$event->setStart($start);
$end = new Google_Service_Calendar_EventDateTime();
$end->setDateTime($end_ev_datetime);
$end->setTimeZone('Europe/London');
$event->setEnd($end);
try {
$createdEvent = $calendarService->events->insert($cal_id, $event);
} catch (Exception $e) {
var_dump($e->getMessage());
}
echo 'Event Successfully Added with ID: '.$createdEvent->getId();
}
?>
Using OAuth2 to login and give your server rights to access your calendar account is really simple and well documented (with the google api php client). If you request offline access and store the refresh token, you can log in "as you" server-side at any time.
See Google Accounts Authentication and Authorization: Offline access