Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Google Analytics API V3 / OAuth 2

I've desperately tried to figure this out on my own, and did not want to come to SO with this question, but I'm at my wits end (no thanks to the api / oauth docs).

I'm working in PHP and I'm trying to avoid using the Google_Client and AnalyticsService classes, by using REST on the analytics.data.ga.get method.

STEP #1: Create an API Project for a Web Application

I go to the api console and create a project with analytics services and get an OAuth Client ID and Secret.

I'm under the impression that I can create a Client ID for an Installed Application or a Web Application because I'm doing the initial token handshaking manually. Please correct me if I'm wrong.

I create a Client ID for web applications and get my Client ID xxxxxxxxxxxxxx.apps.googleusercontent.com, Client secret yyyyyyyyyyyyyyy, and my Redirect URI is http://localhost:9002

STEP #2: Request initial API access

I enter this link; https://accounts.google.com/o/oauth2/auth?response_type=code&client_id=xxxxxxxxxxxxxx.apps.googleusercontent.com&redirect_uri=http://localhost:9002&scope=https://www.googleapis.com/auth/analytics.readonly&access_type=offline

The access_type=offline is because I'm using REST, and do not expect "the user" (myself) to manually deal with redirects / popups every time I need a refreshed token.

The above request returns http://localhost:9002?code=4/KModH0K_xxxxxxxxxxxxxxxxxxx9Iw.gikOaYRDWywTshQV0ieZDArCOX8XdwI

Code 4/KModH0K_xxxxxxxxxxxxxxxxxxx9Iw.gikOaYRDWywTshQV0ieZDArCOX8XdwI is my permission to request the API Token.

STEP #3: Request First Token

Because of my company’s IT issues, I’m forced to use PHP 5.2.17 and I do not have access to PHP cURL, so I’m using file_get_contents and stream_context_create.

The first token is requested with a PHP file_get_contents();

$opts = array(
    'http' => array(
        'method' => 'POST',
        'header' => 'Content-Type: application/x-www-form-urlencoded',
        'content' => 'code=4/KModH0K_xxxxxxxxxxxxxxxxxxx9Iw.gikOaYRDWywTshQV0ieZDArCOX8XdwI&client_id=xxxxxxxxxxxxxx.apps.googleusercontent.com&client_secret=yyyyyyyyyyyyyyy&redirect_uri=http://localhost:9002&grant_type=authorization_code'
    )
);

$context = stream_context_create($opts);

$result = file_get_contents('https://accounts.google.com/o/oauth2/token', false, $context);
var_dump($result);

The content parameters must be in a single line.

The above code returns my access_token and refresh_token in json format

string(195) "{ "access_token" : "ya29.AHES6wwwwwwwwwwwwwwwVEBXE6XRbC-Q-pP0wZWdoIm9H804ro", "token_type" : "Bearer", "expires_in" : 3600, "refresh_token" : "1/8tXvdUKcSEcaaxVqqqqqqqqqqqqqoYpj2KSS9qwWI" }"

The refresh token I must store in a safe place, like a DB or protected txt file, which is called upon when my access_token has timed out.

STEP #4: Request Analytics Data

Now from what I understand, I’m ready to roll and should be able to use my access_token to make requests to https://www.googleapis.com/analytics/v3/data/ga.

I do this by sending this request;

$request = 'https://www.googleapis.com/analytics/v3/data/ga' .
    '?ids=ga%3Aaaaaaaaa' .
    '&start-date=2012-12-07' .
    '&end-date=2012-12-09' .
    '&metrics=ga%3Avisits';

$opts = array(
    'http' => array(
        'method' => 'GET',
        'header' => 'Content-Type: application/x-www-form-urlencoded\r\n' .
                    'Authorization: Bearer ya29.AHES6wwwwwwwwwwwwwwwVEBXE6XRbC-Q-pP0wZWdoIm9H804ro \r\n'
        )
);

$context = stream_context_create($opts);

$result = file_get_contents($request, FALSE, $context);
var_dump($result);

This request returns a 401 Unauthorized error. I take this as meaning my request is properly formed and making the connection to https://www.googleapis.com/analytics/v3/data/ga.

Also, according to this doc Getting Full Quota, I can make the request with the access_token in the URL like this;

$request = 'https://www.googleapis.com/analytics/v3/data/ga' .
    '?ids=ga%3A48564799' .
    '&access_token=ya29.AHES6wwwwwwwwwwwwwwwVEBXE6XRbC-Q-pP0wZWdoIm9H804ro' .
    '&start-date=2012-12-07' .
    '&end-date=2012-12-09' .
    '&metrics=ga%3Avisits';

$result = file_get_contents($request, FALSE);

$result = json_decode($result);

var_dump($result);

This time I receive 403 error, in which google includes the response User does not have sufficient permissions for this profile.

QUESTION #1

Am I’m missing something in the API console or a process in the token acquisition? I’m assuming I’m not, because I’m ultimately acquiring the access_token=ya29 and refresh token.

QUESTION #2 Maybe I’m completely off basis in assuming I can do this with simple https reqests? Do I have to use the Google_Client and AnalyticsService classes? I don’t think this is the case, but maybe I’m wrong.

QUESTION #3 Do I need to use a ‘key’ in my request? &key=bbbbbbbbbbbbbbbb

QUESTION #4

By using PHP 5.2.17 am I missing something? (besides 5.3 or 5.4 themselves)

For example, in some versions of PHP, in stream_context_create, the header should be in an array and not a string, like this;

$opts = array(
    'http' => array(
        'method' => 'GET',
        'header' => array(
            'Content-Type: application/x-www-form-urlencoded',
            'Authorization: Bearer ya29.AHES6wwwwwwwwwwwwwwwVEBXE6XRbC-Q-pP0wZWdoIm9H804ro '
        )
    )
);

But I don’t think that it’s an issue in my case. I’m just curious if these HTTP request need to be formed a different way (without using curl).

Any insights and thoughts would be greatly appreciated
like image 559
bmorenate Avatar asked Dec 13 '12 15:12

bmorenate


2 Answers

Here’s my dim witted mistake that nearly gave me a heart attack.

I typically do my development work in Chrome. And my Chrome browser was signed into my gmail account [email protected]. However, my analytics account, which is under my [email protected] was open in FireFox (try not to laugh to hard).

I’m not 100% sure this is correct, but I think this is the general flow. When I did STEP #2: Request initial API access, I did this in my Chrome browser. The endpoint https://accounts.google.com/o/oauth2/auth was authorizing my [email protected] account. And my STEP #4 API request https://www.googleapis.com/analytics/v3/data/ga was looking for an analytics profile under my [email protected] account. Which of course doesn’t exist.

I literally wasted 15 hours on this. This is dumber than trying to troubleshoot an update… and forgetting to flush the cache.

Sorry for wasting your time.

EDIT REFRESH TOKENS

I've once again run into issues with this API and found out the hard way that GA will revoke Refresh Tokens if too many different clients use the token, at least I think that was the problem.

Further reading can be found here.

like image 148
bmorenate Avatar answered Oct 22 '22 16:10

bmorenate


I got a 403 today and found the cause: in the get function I was using the account ID instead of the profile ID. Switching to the profile ID fixed it for me.

like image 37
Spinal Avatar answered Oct 22 '22 16:10

Spinal