Create google calendar events with php and service account - authenticate issue - php

Is it possible to access google calendar service while using service-account-method?
Google says indirectly, it is not possible, because calendar-service is not on the list of supported services in the documentation of service-account-method, but I personally think, it IS possible.
But how?
I am writing a calendar application in php, and there I want to create calendar events into my google-calendar without user-action (e.g. login).
I learned, that first the application has to authenticate itself against google server, using the service-account-method with a key-file .p12
I am using the following code for authentication:
(downloaded fom here: http://code.google.com/p/google-api-php-client/source/browse/trunk/examples/prediction/serviceAccount.php )
session_start();
require_once 'google-api/src/Google_Client.php';
require_once 'google-api/src/contrib/Google_CalendarService.php';
require_once 'google-api/src/contrib/Google_PredictionService.php';
$client = new Google_Client();
$client->setApplicationName(GOOGLE_APPLICATION_NAME);
$client->setClientId(GOOGLE_CLIENT_ID);
$keyfile = file_get_contents(GOOGLE_KEY_FILE);
$client->setAssertionCredentials(new Google_AssertionCredentials(
GOOGLE_SERVICE_ACCOUNT_NAME,
array('https://www.googleapis.com/auth/prediction'),
$keyfile)
);
But this login seems not to work.
How do I find out, if server is logged in at that moment?
I want to continue with this:
$cal = new Google_CalendarService($client);
if (isset($_SESSION['token'])) {
$client->setAccessToken($_SESSION['token']);
}
if ($client->getAccessToken()) {
$calList = $cal->calendarList->listCalendarList(); // <- this is line 55
print "<h1>Calendar List</h1><pre>" . print_r($calList, true) . "</pre>";
$_SESSION['token'] = $client->getAccessToken();
} else {
$authUrl = $client->createAuthUrl();
print "<a class='login' href='$authUrl'>Connect Me!</a>";
}
But in line 55 there comes this error:
Fatal error: Uncaught exception 'Google_ServiceException' with message
'Error calling GET
https://www.googleapis.com/calendar/v3/users/me/calendarList: (403)
Insufficient Permission' in
/usr/www/users/leuchtk/html/google-api/src/io/Google_REST.php:66
Stack trace: #0
/usr/www/users/leuchtk/html/google-api/src/io/Google_REST.php(36):
Google_REST::decodeHttpResponse(Object(Google_HttpRequest))
#1 /usr/www/users/leuchtk/html/google-api/src/service/Google_ServiceResource.php(186):
Google_REST::execute(Object(Google_HttpRequest))
#2 /usr/www/users/leuchtk/html/google-api/src/contrib/Google_CalendarService.php(205):
Google_ServiceResource->__call('list', Array)
#3 /usr/www/users/leuchtk/html/i_termine_admin.php(55): Google_CalendarListServiceResource->listCalendarList()
#4 /usr/www/users/leuchtk/html/termine_admin.php(113): include('/usr/www/users/...')
#5 {main} thrown in /usr/www/users/leuchtk/html/google-api/src/io/Google_REST.php on line 66
So it looks like, the application is not logged in.
I am completely lost in this code for now.
Thank you for some little light, what is missing there...
Marco

You may want to refer to this question. Your issue could be just to add the
array('https://www.googleapis.com/auth/calendar', 'https://www.googleapis.com/auth/calendar.readonly'),
in where you call the
$client->setAssertionCredentials();
Google PHP Client API: Insufficient Permission
Hope this helps

Related

Google Calendar API InvalidArgumentException : "Invalid Code"

Okay so far I've been following the listed php tutorial that Google has provided, I have gathered my client secret, I have set my Redirect URI to port localhost:8000 and have listed the directory for my credentials/client_secret accordingly. I'm now in the final step which is authorizing my application in order for me to be a productive spawn of society and use this fantastic calendar library.
I'm getting this error once in the stage of authorizing my account, (which is strange because I'm able to get the correct URL to authorize my application (the URL works and redirects to the correct URI) and get the code needed but I'm not able to input it in because it seems as if it takes in nothing willingly without waiting for me to put the code in):
C:\wamp64\www\Main\Career\EricksFuckingWebsite\API's>php quickstart.php
<Open the following link in your browser:
https://accounts.google.com/o/oauth2/auth?response_type=code&access_type=offline&client_id=316595803597-m0irohklrarshii5lj7mugkghi48v84v.apps.googleusercontent.com&redirect_uri=https%3A%2F%2Flocalhost%3A8000&state&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcalendar.readonly&prompt=select_account%20consent
Enter verification code: PHP Fatal error: Uncaught InvalidArgumentException: Invalid code in C:\wamp64\www\Main\Career\EricksFuckingWebsite\API's\vendor\google\apiclient\src\Google\Client.php:176
Stack trace:
#0 C:\wamp64\www\Main\Career\EricksFuckingWebsite\API's\quickstart.php(44): Google_Client->fetchAccessTokenWithAuthCode('')
#1 C:\wamp64\www\Main\Career\EricksFuckingWebsite\API's\quickstart.php(63): getClient()
#2 {main}
thrown in C:\wamp64\www\Main\Career\EricksFuckingWebsite\API's\vendor\google\apiclient\src\Google\Client.php on line 176
Fatal error: Uncaught InvalidArgumentException: Invalid code in C:\wamp64\www\Main\Career\EricksFuckingWebsite\API's\vendor\google\apiclient\src\Google\Client.php:176
Stack trace:
#0 C:\wamp64\www\Main\Career\EricksFuckingWebsite\API's\quickstart.php(44): Google_Client->fetchAccessTokenWithAuthCode('')
#1 C:\wamp64\www\Main\Career\EricksFuckingWebsite\API's\quickstart.php(63): getClient()
#2 {main}
thrown in C:\wamp64\www\Main\Career\EricksFuckingWebsite\API's\vendor\google\apiclient\src\Google\Client.php on line 176
bloody well right
here's where it's throwing the exception (API's\vendor\google\apiclient\src\Google\Client.php on line 176):
public function fetchAccessTokenWithAuthCode($code)
{
if (strlen($code) == 0) {
throw new InvalidArgumentException("Invalid code"); //exception thrown here
}
$auth = $this->getOAuth2Service();
$auth->setCode($code);
$auth->setRedirectUri($this->getRedirectUri());
$httpHandler = HttpHandlerFactory::build($this->getHttpClient());
$creds = $auth->fetchAuthToken($httpHandler);
if ($creds && isset($creds['access_token'])) {
$creds['created'] = time();
$this->setAccessToken($creds);
}
return $creds;
}
is there something wrong with my credentials? I have but a clue what may be going on because I've tried in the past and have never experienced this error, I usually get something along the lines of the redirect URI not being correct. Any and all help is welcome. TYIA.
EDIT (read comment) :
Warning: count(): Parameter must be an array or an object that implements Countable in C:\wamp64\www\Main\Career\EricksFuckingWebsite\API's\vendor\guzzlehttp\guzzle\src\Handler\CurlFactory.php on line 67
PHP Fatal error: Uncaught GuzzleHttp\Exception\RequestException: cURL error 60: SSL certificate problem: unable to get local issuer certificate (see http://curl.haxx.se/libcurl/c/libcurl-errors.html) in C:\wamp64\www\Main\Career\EricksFuckingWebsite\API's\vendor\guzzlehttp\guzzle\src\Handler\CurlFactory.php:187
Stack trace:
#0 C:\wamp64\www\Main\Career\EricksFuckingWebsite\API's\vendor\guzzlehttp\guzzle\src\Handler\CurlFactory.php(150): GuzzleHttp\Handler\CurlFactory::createRejection(Object(GuzzleHttp\Handler\EasyHandle), Array)
#1 C:\wamp64\www\Main\Career\EricksFuckingWebsite\API's\vendor\guzzlehttp\guzzle\src\Handler\CurlFactory.php(103): GuzzleHttp\Handler\CurlFactory::finishError(Object(GuzzleHttp\Handler\CurlHandler), Object(GuzzleHttp\Handler\EasyHandle), Object(GuzzleHttp\Handler\CurlFactory))
#2 C:\wamp64\www\Main\Career\EricksFuckingWebsite\API's\vendor\guzzlehttp\guzzle\src\Handler\CurlHandler.php(43): GuzzleHttp\Handler\CurlFactory::finish(Object(GuzzleHttp\Handler\CurlHandler), Object(GuzzleHttp\Handler\EasyHandl in C:\wamp64\www\Main\Career\EricksFuckingWebsite\API's\vendor\guzzlehttp\guzzle\src\Handler\CurlFactory.php on line 187
Fatal error: Uncaught GuzzleHttp\Exception\RequestException: cURL error 60: SSL certificate problem: unable to get local issuer certificate (see http://curl.haxx.se/libcurl/c/libcurl-errors.html) in C:\wamp64\www\Main\Career\EricksFuckingWebsite\API's\vendor\guzzlehttp\guzzle\src\Handler\CurlFactory.php:187
Stack trace:
#0 C:\wamp64\www\Main\Career\EricksFuckingWebsite\API's\vendor\guzzlehttp\guzzle\src\Handler\CurlFactory.php(150): GuzzleHttp\Handler\CurlFactory::createRejection(Object(GuzzleHttp\Handler\EasyHandle), Array)
#1 C:\wamp64\www\Main\Career\EricksFuckingWebsite\API's\vendor\guzzlehttp\guzzle\src\Handler\CurlFactory.php(103): GuzzleHttp\Handler\CurlFactory::finishError(Object(GuzzleHttp\Handler\CurlHandler), Object(GuzzleHttp\Handler\EasyHandle), Object(GuzzleHttp\Handler\CurlFactory))
#2 C:\wamp64\www\Main\Career\EricksFuckingWebsite\API's\vendor\guzzlehttp\guzzle\src\Handler\CurlHandler.php(43): GuzzleHttp\Handler\CurlFactory::finish(Object(GuzzleHttp\Handler\CurlHandler), Object(GuzzleHttp\Handler\EasyHandl in C:\wamp64\www\Main\Career\EricksFuckingWebsite\API's\vendor\guzzlehttp\guzzle\src\Handler\CurlFactory.php on line 187
I think you are going about it the wrong way remember code is only used once its is an authorization code after that you will need to either store the refresh token or require that the user login again once it has expired.
oauth2callback.php
<?php
// Load the Google API PHP Client Library.
require_once __DIR__ . '/vendor/autoload.php';
// Start a session to persist credentials.
session_start();
// Create the client object and set the authorization configuration
// from the client_secrets.json you downloaded from the Developers Console.
$client = new Google_Client();
$client->setAuthConfig(__DIR__ . '/client_secrets.json');
$client->setRedirectUri('http://' . $_SERVER['HTTP_HOST'] . '/oauth2callback.php');
$client->addScope(Google_Service_Calendar::CALENDAR_READONLY);
// Handle authorization flow from the server.
if (! isset($_GET['code'])) {
$auth_url = $client->createAuthUrl();
header('Location: ' . filter_var($auth_url, FILTER_SANITIZE_URL));
} else {
$client->authenticate($_GET['code']);
$_SESSION['access_token'] = $client->getAccessToken();
$redirect_uri = 'http://' . $_SERVER['HTTP_HOST'] . '/';
header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL));
}
index.php
<?php
// Load the Google API PHP Client Library.
require_once __DIR__ . '/vendor/autoload.php';
session_start();
$client = new Google_Client();
$client->setAuthConfig(__DIR__ . '/client_secrets.json');
$client->addScope(Google_Service_Calendar::CALENDAR_READONLY);
// If the user has already authorized this app then get an access token
// else redirect to ask the user to authorize access to Google Analytics.
if (isset($_SESSION['access_token']) && $_SESSION['access_token']) {
// Set the access token on the client.
$client->setAccessToken($_SESSION['access_token']);
// Create an authorized analytics service object.
$service= new Google_Service_Calendar($client);
// Call The method which will call the Api
$response = getCalendar($service);
// Print the response.
printResults($response);
} else {
$redirect_uri = 'http://' . $_SERVER['HTTP_HOST'] . '/oauth2callback.php';
header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL));
}
I have another example where which shows how to store the refresh token. Calendar api sample

Google Calendar API error redirect_uri_mismatch

I am trying to use the google API to manage the user´s calendar, and I am finding a problem. I created and configured a google project on the Google Developers Console. One of the settings was the allowed redirecting uris... and I think it is ok, because after some test where google threw the same error (redirect_uri_mismatch), I got that google ask me for permissions... the problem I think is this line: $this->client->authenticate($_GET['code']);
I am going to show the code and explain what it does
function __construct()
{
parent::__construct();
require __DIR__ . '/vendor/autoload.php';
define('APPLICATION_NAME', 'Google Calendar API PHP Quickstart');
define('CLIENT_SECRET_PATH', __DIR__ . '/credentials/client_secret.json');
define('CREDENTIALS_PATH', __DIR__ .'/credentials/');
define('SCOPES', implode(' ', array(Google_Service_Calendar::CALENDAR_READONLY)));
// If modifying these scopes, delete your previously saved credentials
// at ~/.credentials/calendar-php-quickstart.json
$this->client = new Google_Client();
$this->client->setApplicationName(APPLICATION_NAME);
$this->client->setScopes(SCOPES);
$this->client->setAuthConfigFile(CLIENT_SECRET_PATH);
if (!file_exists(CLIENT_SECRET_PATH.$this->session->userdata("identity").".json") && !$this->input->get("code"))
$this->getCredentials();
}
public function responseCredentials()
{
$authCode = $this->input->get("code");
$this->client->authenticate($_GET['code']);
$accessToken = $this->client->client->getAccessToken();
$credentialsPath = CLIENT_SECRET_PATH.$this->session->userdata("identity").".json";
mkdir(dirname($credentialsPath), 0700, true);
file_put_contents($credentialsPath, $accessToken);
redirect(base_url("dashboard"));
}
private function getCredentials()
{
$this->client->setRedirectUri(base_url('calendar/responseCredentials'));
$authUrl = $this->client->createAuthUrl();
header('Location: ' . filter_var($authUrl, FILTER_SANITIZE_URL));
}
Ok... the first... the constructor it load the google api autoloader, and the constants, creates a new Google_Client object, and inspect if exists a permissions file for the user and there is no "code" index on the get.
If not it invokes the getCredentials function that redirect to google.
After give permissions, the user is redirect to http://domain.com/calendar/responseCredentials (that it is configured on the console.developers.google)
The error thrown is this:
Fatal error: Uncaught exception 'Google_Auth_Exception' with message
'Error fetching OAuth2 access token, message: 'redirect_uri_mismatch'' in
/var/www/html/prototipo/application/controllers/vendor/google/apiclient/src/Google/Auth/OAuth2.php:126
Stack trace:
#0 /var/www/html/prototipo/application/controllers/vendor/google/apiclient/src/Google/Client.php(128): Google_Auth_OAuth2->authenticate('4/rkAKNAmiVgs1Z...', false)
#1 /var/www/html/prototipo/application/controllers/calendar.php(52): Google_Client->authenticate('4/rkAKNAmiVgs1Z...')
#2 [internal function]: Calendar->responseCredentials()
#3 /var/www/html/prototipo/system/core/CodeIgniter.php(360): call_user_func_array(Array, Array)
#4 /var/www/html/prototipo/index.php(202): require_once('/var/www/html/p...')
#5 {main} thrown in/var/www/html/prototipo/application/controllers/vendor/google/apiclient/src/Google/Auth/OAuth2.php on line 126
What am I doing wrong??
Thank you.
EDIT
I just realized that at the end of the code variable on the return uri there always is a pad... something like this:
http://pedro.eatec.es/prototipo/calendar_test_stack/responseCredentials?code=4/PL7nK1s9m5vpBow7HScaPmkpWpoW3J4uzUxlD7NE49g#
The example here: https://developers.google.com/identity/protocols/OAuth2WebServer#handlingresponse doesn´t show this pad... I tried to do this:
$this->client->authenticate($_GET['code']."#");
But... of course, doesn´t work.
PS: I tried to do it because with echo $_GET['code']; didn´t show the pad.
Hello and Thanks #thepieterdc finally you were reason...
I was setting up correctly the project on console.developers... but my mistake was that I need make some trying to get a correct configuration and when I got to make disappear the error 400 (with the broken robot) and it ask me for permission, on the redirecting function when I make $this->g_client->authenticate($_GET['code']); the code try to make other request (on OAuth2.php) to https://accounts.google.com/o/oauth2/token and it use the client_id.json that you need to refresh... and I didn´t. I WAS USING THE FIRST EDITION OF THE CLIENT_ID.JSON I need to re-download (or re-write) if you change something on the console.
Thanks.

authentication Google Content Api service account - error 'user cannot access account'

I am bashing my head against the wall trying to get my code to work.
I already have succesfully connected to the google Api by using the authentication route with the redirect url.
However, I need to get this working as a standalone service which will be running in a crontab.
So now I am trying to authenticate with a 'service account'.
This is my code and below that you will find the error it is giving me.
$client = new Google_Client();
$client->setApplicationName('GoogleShoppingService');
if (isset($_SESSION['service_token'])) {
$client->setAccessToken($_SESSION['service_token']);
}
$service = new Google_Service_Content($client);
$client_id = 'xxxxxxx.apps.googleusercontent.com';
$client->setClientId($client_id);
$service_account_name = 'xxxxxxx#developer.gserviceaccount.com';
$key_file_location = 'privatekey.p12';
$key = file_get_contents($key_file_location);
$scope = 'https://www.googleapis.com/auth/content';
$cred = new Google_Auth_AssertionCredentials(
$service_account_name,
array($scope),
$key
);
$result = $client->setAssertionCredentials($cred);
print_r($result);
if($client->getAuth()->isAccessTokenExpired()) {
$client->getAuth()->refreshTokenWithAssertion($cred);
}
$_SESSION['service_token'] = $client->getAccessToken();
echo $client->getAccessToken();
$merchantId = 1234567;//this a dummy value, I replace it with the actual merchantId
$accountId = 1234567;//this a dummy value, I replace it with the actual accountId
$accountstatuses = $service->accountstatuses->get($merchantId,$accountId);
So this is the message I get when running the code. (note that the token is created, but that I am not able to access the content of the Google Shopping feed.)
{"access_token":"ya29.NQD7MQz0cas9PhoAAADRPMlTVecqYXYh4fNoZfRMymQtSF4hwqJn31uobohLbw","expires_in":3600,"created":1404200605}
Fatal error:
Uncaught exception 'Google_Service_Exception' with message 'Error calling GET https://www.googleapis.com/content/v2/1234567/accountstatuses/1234567: (401) User cannot access account 1234567' in /home/sites/site1/web/googleShopping2/src/Google/Http/REST.php:79
Stack trace:
#0 /home/sites/site1/web/googleShopping2/src/Google/Http/REST.php(44): Google_Http_REST::decodeHttpResponse(Object(Google_Http_Request))
#1 /home/sites/site1/web/googleShopping2/src/Google/Client.php(499): Google_Http_REST::execute(Object(Google_Client), Object(Google_Http_Request))
#2 /home/sites/site1/web/googleShopping2/src/Google/Service/Resource.php(195): Google_Client->execute(Object(Google_Http_Request))
#3 /home/sites/site1/web/googleShopping2/src/Google/Service/Content.php(685): Google_Service_Resource->call('get', Array, 'Google_Service_...')
#4 /home/sites/site1/web/googleShopping2/examples/test.php(58): Google_Service_Content_Accountstatuses_Resource->get(1234567, 1234567)
#5 {main} thrown in /home/sites/site1/web/googleShopping2/src/Google/Http/REST.php on line 79
I've already tried to find a solution for 2 days now, but any hint that I've found doesn't help me. I've also creted a new project with new Api auth keys, but nothing works and I always get the above message.
Who can help me please?
Regards,
Martin
You need to add the email address of the service account you created to the Google merchant account under Settings > User.
On https://merchants.google.com/
At the top right, click on the gear icon i.e settings.
click on account access
click +add user
add the email-adress you got from the service account .json file. (it's in there)
make sure the added user is set to admin.

Unable to get Google OAuth Token

I'm trying to add calendar events to my Google calendar from a php script. Note that I can do this successfully directly from a Google test page so I think that my calendar is set up correctly. However, when I attempt do this from a php script, I'm not able to get the OAuth2 token.
The following script, mostly taken from a Google example, runs without error, but it always winds up with a "Connect Me!" link. When I click on this link, it takes me to a validation screen that warns me that this app would like to manage my calendars. I click 'Accept' and a then see my calendar. A little inconvenient, but if this gets the OAuth token, fine.
I then go back and run the script again, hoping that the access token will now be available, but I get exactly the same result. No matter how many times I run this script, I never get the token, which I need in order to expand the script to add events to the calendar.
I've been at this for days, and I'm just not getting anywhere. Can anyone help? Thanks.
<?php
require_once '../../src/Google_Client.php';
require_once '../../src/contrib/Google_CalendarService.php';
require_once '../../src/auth/Google_OAuth2.php';
session_start();
$client = new Google_Client();
$client->setApplicationName("Add Google Calendar Entries");
// Visit https://code.google.com/apis/console?api=calendar to generate your
// client id, client secret, and to register your redirect uri.
$client->setClientId('843319906820-1s1d737e77o71a3vaskf434k3ape1fk5.apps.googleusercontent.com');
$client->setClientSecret('AP5imn3e0TEWNyLTCNm8YJj6');
$client->setRedirectUri('https://www.google.com/calendar/');
$client->setDeveloperKey('AIzaSyDIw3ks7AmrIrRxjO9y2gWBhQDYHFWd-uc');
$client->setUseObjects(true);
$cal = new Google_CalendarService($client);
if (isset($_GET['logout'])) {
unset($_SESSION['token']);
}
if (isset($_GET['code'])) {
$client->authenticate($_GET['code']);
$_SESSION['token'] = $client->getAccessToken();
header('Location: http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF']);
}
if (isset($_SESSION['token'])) {
$client->setAccessToken($_SESSION['token']);
}
if ($client->getAccessToken()) {
$calList = $cal->calendarList->listCalendarList();
print "<h1>Calendar List</h1><pre>" . print_r($calList, true) . "</pre>";
$_SESSION['token'] = $client->getAccessToken();
} else {
$authUrl = $client->createAuthUrl();
print "<a class='login' href='$authUrl'>Connect Me!</a>";
}
?>
EDIT: Attempting to implement the suggestion from Vinicius Pinto. I've changed my redirect to point directly back to this script. Now I get this error:
Fatal error: Uncaught exception 'Google_ServiceException' with message
'Error calling GET
https://www.googleapis.com/calendar/v3/users/me/calendarList?key=AIzaSyDIw3ks7AmrIrRxjO9y2gWBhQDYHFWd-uc:
(403) Access Not Configured. Please use Google Developers Console to
activate the API for your project.' in
D:\Hosting\11347607\html\scripts\google-api-php-client\src\io\Google_REST.php:66
Stack trace: #0
D:\Hosting\11347607\html\scripts\google-api-php-client\src\io\Google_REST.php(36):
Google_REST::decodeHttpResponse(Object(Google_HttpRequest)) #1
D:\Hosting\11347607\html\scripts\google-api-php-client\src\service\Google_ServiceResource.php(186):
Google_REST::execute(Object(Google_HttpRequest)) #2
D:\Hosting\11347607\html\scripts\google-api-php-client\src\contrib\Google_CalendarService.php(205):
Google_ServiceResource->__call('list', Array) #3
D:\Hosting\11347607\html\scripts\google-api-php-client\examples\calendar\simple.php(43):
Google_CalendarListServiceResource->listCalen in
D:\Hosting\11347607\html\scripts\google-api-php-client\src\io\Google_REST.php
on line 66
It would appear that I don't have the correct APIs activated in the developer console. I have the Calendar API and the Google Cloud Storage JSON API activated and nothing else. I don't see any other APIs that would be relevant, and I don't think that this message is telling me which APIs it wants.
EDIT 2: Looks like I was using the wrong developer key. I've changed it to the key for server applications. Now my error is this:
Fatal error: Uncaught exception 'Google_AuthException' with message
'Error refreshing the OAuth2 token, message: '{ "error" :
"invalid_client" }'' in
D:\Hosting\11347607\html\scripts\google-api-php-client\src\auth\Google_OAuth2.php:288
Stack trace: #0
D:\Hosting\11347607\html\scripts\google-api-php-client\src\auth\Google_OAuth2.php(248):
Google_OAuth2->refreshTokenRequest(Array) #1
D:\Hosting\11347607\html\scripts\google-api-php-client\src\auth\Google_OAuth2.php(225):
Google_OAuth2->refreshToken('1/6ZdJyZALqcbwW...') #2
D:\Hosting\11347607\html\scripts\google-api-php-client\src\service\Google_ServiceResource.php(167):
Google_OAuth2->sign(Object(Google_HttpRequest)) #3
D:\Hosting\11347607\html\scripts\google-api-php-client\src\contrib\Google_CalendarService.php(205):
Google_ServiceResource->__call('list', Array) #4
D:\Hosting\11347607\html\scripts\google-api-php-client\examples\calendar\simple.php(47):
Google_CalendarListServiceResource->listCalendarList() in
D:\Hosting\11347607\html\scripts\google-api-php-client\src\auth\Google_OAuth2.php
on line 288
The $client->setRedirectUri() should receive a URL pointing to your application, because this is the URL that you'll be redirected to after you authorize the application in the Google page. That's why you are being redirect to the calendar, because you are using the calendar URL.
It seems like your script is already expecting a $_GET['code'], so try setting the redirect URL to the url of this script. You'll also need to set the same URL in the Developers Console, under API -> Credentials.
You only get a token when you call $client->authenticate($_GET['code']); with a value code.
Take a look at this lib I just commited to Github, it's an early version, but it's working fine (I'm using to access YouTube). It's using the new official library.
Update: as said in the comments, the developer key isn't actually required for this to work, even though all Google sample code sets it.

Google Analytics API 401 Invalid Credentials

I'm wracking my brain trying to figure out how to use the Google API PHP Client to access Google Analytics. Specifically, I want to upload cost data from other campaigns. My code does work to get information from GA, I can view traffic data for profiles, but I cannot figure out how to upload.
Here's the code that I'm using for auth:
require_once 'google-api-php-client/src/Google_Client.php';
require_once 'google-api-php-client/src/contrib/Google_AnalyticsService.php';
session_start();
$client = new Google_Client();
$client->setApplicationName("GA-Tester");
$client->setClientId('xxx.apps.googleusercontent.com');
$client->setClientSecret('xxx');
$client->setRedirectUri('http://www.site.com/indext.php');
$client->setDeveloperKey('xxx');
$analyticsService = new Google_AnalyticsService($client);
$dailyUploads = $analyticsService->management_dailyUploads;
if (isset($_GET['logout'])) {
unset($_SESSION['token']);
}
if (isset($_GET['code'])) {
$client->authenticate();
$_SESSION['token'] = $client->getAccessToken();
$redirect = 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'];
header('Location: ' . filter_var($redirect, FILTER_SANITIZE_URL));
}
if (isset($_SESSION['token'])) {
$client->setAccessToken($_SESSION['token']);
}
if (!$client->getAccessToken()) {
header ('Location:http://www.site.com/indext.php');
} else {...
This code does work for requesting data. I can get a list of accounts, profiles, download traffic data for a specific profile, etc. No errors or issues.
When I try to upload my CSV file containing cost data I get a '401 Invalid Credentials' error. Here's the code that sends the file:
$send = $dailyUploads->upload(
$accountId,
$webPropertyId,
$customDataSourceId,
$start_date,
1,
'cost',
array(
"reset" => true,
"data" => $cont,
"mimeType" => "application/octet-stream",
"uploadType" => "media"));
I've double checked all of my variables that I'm passing, they're sending the correct information.
So here's my question. If all of my GET requests work without issue, why would my POST request throw an error? I can't tell if this is an error with my code, or with settings in the API console. Can anyone steer me in the right direction?
EDIT:
Here's the error code generated (minus identifiable bits).
Fatal error: Uncaught exception 'Google_ServiceException' with message
'Error calling POST https://www.googleapis.com/upload/analytics/v3/man
agement/accounts/1234567/webproperties/UA-1234567-1/customDataSources/
xXxXxX/dailyUploads/2013-01-17/uploads?appendNumber=1&type=cost&reset=
true&uploadType=media&key=xXxXxX: (401) Invalid Credentials' in /../pub
lic_html/proj/google-api-php-client/src/io/Google_REST.php:66 Stack tra
ce: #0 /../public_html/proj/google-api-php-client/src/io/Google_REST.ph
p(36): Google_REST::decodeHttpResponse(Object(Google_HttpRequest)) #1 /
../public_html/proj/google-api-php-client/src/service/Google_ServiceRes
ource.php(186): Google_REST::execute(Object(Google_HttpRequest)) #2 /..
/public_html/proj/google-api-php-client/src/contrib/Google_AnalyticsSer
vice.php(82): Google_ServiceResource->__call('upload', Array) #3 /../pu
blic_html/proj/dailyUpload_send.php(60): Google_ManagementDailyUploadsS
erviceResource->upload('1234567', 'UA-1234567-1', 'xXxXxXxXxXxXxXx...',
' in /../public_html/proj/google-api-php-client/src/io/Google_REST.php
on line 66
I just successfully uploaded cost data for the first time. In trading comments with Nicholas Pickering I came across the documentation for Management API Authorization which states that:
You will get a 401 status code if your access_token has expired or if you are using the wrong scope for the API.
The default for scope is read only, which is why all of my GET requests were working without difficulty, but I couldn't complete any POST requests through the API. I can't remember how I found it, but the way to accomplish this within the PHP client library is to append the following line to the client declaration:
$client->setScopes('https://www.googleapis.com/auth/analytics');
As soon as I added that line to my project, I was able to successfully upload cost data. I'm really glad to have cleared this hurdle. I still have a long way to go to complete my project, but at least I know that it's going to work.
I kept geting this error until I went to Google Console -> APIs & auth ->
APIs and turned on this API usage.

Categories