Google2 Plug In & OAuth & Google Analytics

Hi,
I am trying to use Patrick’s Google2 plug-in from ServoyForge, but there is no sample solution or much in the way of documentation.
I am actually trying to use it to allow me to access the Google Analytics API’s which require ‘oauth2’, which it looks like this plugin uses.
I think I have set all of the Google stuff up correctly, so I can do the first bit

	fv_ga_scopes = ['https://www.googleapis.com/auth/analytics'] ;
	
	plugins.Google2.setupApplication('MYAPPNAME', scopes.globals.ga_client_id, scopes.globals.ga_certificate_fingerprint) ;
	
	var _ga_url = plugins.Google2.getAuthorizationUrl(fv_ga_scopes) ;
	
	//sets the relative URL of the HTML_AREA field
	elements.html_area.URL = _ga_url;

where ‘elements.html_area’ is an HTML area I am displaying on a form.
This displays a Google page that seems to want a password entered & has a ‘Sign In’ button.
I enter my Google password and click button, but then nothing happens (& I do not get a token as the Google2 Wiki states)
I have also tried just opening the URL in a web browser using application.showURL, but then get an error page

The redirect URI in the request: urn:ietf:wg:oauth:2.0:oob did not match a registered redirect URI.
Request Details
scope=https://www.googleapis.com/auth/analytics
response_type=code
redirect_uri=urn:ietf:wg:oauth:2.0:oob
client_id=

I am at a loss as to how to proceed, so was wondering, is there a sample solution or some code I can use to get me back the data I need for the token (from Wiki:-)

Once the user logged into his account and granted the requested access, he will be presented with a code (token). That token is then used to authorize your application:

plugins.Google2.authorize(code, userId, scopes)
Please not that the code has a validity, so it will expire rather quickly. The result of the method is the refresh token that you need to store.

so I can use the refresh token to make my GA calls??

Or if anyone else knows how I can get a token to call GA API’s??

Thanks

Rafi

I have never tried this inside a html area. Maybe that simply won’t work. I suggest you try that in a real browser.

The login is necessary of course. The process is: you login into your Google account and then grant access to whatever application.

I’m not sure how the plugin can help you with analytics at this point. Once you have the token, how do you want to proceed?

Hi Patrick,

patrick:
I have never tried this inside a html area. Maybe that simply won’t work. I suggest you try that in a real browser.

I am, but I am still getting the error

  1. That’s an error.

Error: redirect_uri_mismatch

The redirect URI in the request: urn:ietf:wg:oauth:2.0:oob did not match a registered redirect URI.

Request Details
scope=https://www.googleapis.com/auth/analytics
response_type=code
redirect_uri=urn:ietf:wg:oauth:2.0:oob
client_id=

patrick:
The login is necessary of course. The process is: you login into your Google account and then grant access to whatever application.

That is what I am trying to do. Maybe I am using something incorrectly, as the current Google Console for Developers in API section doesn’t seem to match exactly what you put in Wiki for ServoyForge plugin
[attachment=0]GoogleOAuth_web.jpg[/attachment]
I am using the client ID as detailed, but I have tried my certificate fingerprint and the standard secret as my ‘client secret’, but it still doesn’t help :(
What should I be passing?

patrick:
I’m not sure how the plugin can help you with analytics at this point. Once you have the token, how do you want to proceed?

I can request analytics data using a GET URL, but need an Oauth token in it, so wanted to use the token your plugin generates in my call.
I guess I’m just trying to use your plugin as a basic Google OAuth token generator ;-)

Do you have a sample/test Servoy solution file for the Google2 plugin I can work with?

Thanks

Rafi

Hi Patrick/Rafi
Can I Plus 1 on Rafi’s request for clarification as I had much the same experience. Brilliant that there is a plugin for this service but not entirely sure the docs match the experience at the Google end. Having said which Google don’t help matters by changing the goalposts regularly!!

Gordon

I think the documentation on ServoyForge is correct and matches the Google management console.

What you need is a Client ID for an installed application:

[attachment=1]step1.png[/attachment]

This will give you something like this:

[attachment=0]step1a.png[/attachment]

Thanks Patrick, its was the selection of the ‘installed app’ and ‘other’ that I had got wrong.

Appreciate the time you took to create the plugin and help here many thanks

Gordon

Then you need to enable the analytics or whatever app you want for your application:

[attachment=2]step2.png[/attachment]

Once done, you can start using the plugins methods. For example:

function setupAnalytics() {
	plugins.Google2.setupApplication("Google plugin for Servoy", clientID, clientSecret);
	var scopesToGetAccessFor = [plugins.Google2.AUTHENTICATION_SCOPE.DRIVE, "https://www.googleapis.com/auth/analytics.readonly"];
	var url = plugins.Google2.getAuthorizationUrl(scopesToGetAccessFor);
	application.output(url);
}

Note that the plugin does not yet support analytics, so it doesn’t offer the scope (you have to figure it out). In the example above, you request access to google Drive and Analytics in read only mode.

The URL created can the be opened in a browser and it will look like this:

[attachment=1]step4.png[/attachment]

If you as a user allow this, you will see this:

[attachment=0]step5.png[/attachment]

This is the request token your user has to copy. With that you have to call:

function authorizeAnalytics() {
	var token = plugins.Google2.authorize("4/PnM4Df_weblqwm4WYS1Hph8i9wjEPeeXmbxj6epjOQg.sv33e8FB5AIfyjz_MlCJoi2Yk_YUmgI",userId,[plugins.Google2.AUTHENTICATION_SCOPE.DRIVE, "https://www.googleapis.com/auth/analytics.readonly"])
	application.output(token);
}

which will output the refresh token that you need to store.

Now you have a token that gives you access to analytics. But what do you do now?

What is it that you want from Google analytics? The plugin can, of course, easily be enhanced…

Hi Patrick,
firstly, thanks for all the other posts, I will try them out tomorrow and let you know how they went.

patrick:
What is it that you want from Google analytics? The plugin can, of course, easily be enhanced…

I want to be able to pick up various values, like how many times a landing page has been hit so that I can then trigger something else, like sending an email…

When I’ve got my token working, I will maybe post an example of a call I make.

Again, thanks :D

Rafi

Hi Patrick,
I have had a chance to have another go now and thanks to your earlier clarification of how to get client ID, I have now got a Google auth page to display that then gives me an access code.

I can then get a refresh token, but now when I try to send a simple GET URL request, it’s not working because I need the ‘access_token’ that goes along with the refresh token…

patrick:
The plugin can, of course, easily be enhanced…

From my perspective, if you could also return for me the ‘access_token’, then I can put that in the header of my request like this

var _url = 'https://www.googleapis.com/analytics/v3/data/ga' ;
	_url += '?ids=ga_my_id' ;
	_url += '&start-date=2015-01-01' ;
	_url += '&end-date=2015-04-30' ;
	_url += '&metrics=ga%3Apageviews' ;
	_url += '&dimensions=ga:browser' ;
	_url += '&prettyprint=true' ;

        scopes.globals.ga_header_bearer = 'Bearer ' + scopes.globals.ga_access_token ; // this is the other token returned by your plugin with refresh token
	var client = plugins.http.createNewHttpClient();
	var request = client.createGetRequest(_url);
	request.addHeader('Authorization', scopes.globals.ga_header_bearer) ;
	var response = request.executeRequest(my_gmail_email,my_gmail_pwd);
	var httpCode = response.getStatusCode(); // httpCode 200 is ok"
	fv_pageData = response.getResponseBody();

The above code is just an example of GA data, in this case number of page views by browser, which returns

--clipped--
"columnHeaders": [
  {
   "name": "ga:browser",
   "columnType": "DIMENSION",
   "dataType": "STRING"
  },
  {
   "name": "ga:pageviews",
   "columnType": "METRIC",
   "dataType": "INTEGER"
  }
 ],
 "totalsForAllResults": {
  "ga:pageviews": "697"
 },
 "rows": [
  [
   "(not set)",
   "10"
  ],
  [
   "Chrome",
   "539"
  ],
  [
   "Firefox",
   "25"
  ],
  [
   "Internet Explorer",
   "9"
  ],
  [
   "Java",
   "8"
  ],
  [
   "Maxthon",
   "1"
  ],
  [
   "Mozilla",
   "1"
  ],
  [
   "Mozilla Compatible Agent",
   "51"
  ],
  [
   "Opera",
   "4"
  ],
  [
   "Safari",
   "48"
  ],
  [
   "YaBrowser",
   "1"
  ]
 ]
}

patrick:
What is it that you want from Google analytics?

… but for this client, I want the number of conversions/goal for a landing page
If you could make another function in your plugin like

var myJSONReturnObject = plugins.Google2.getGoogleDataViaURL(_url,refreshToken)

where ‘_url’ is created by me (like sample above) with whatever I need, from wherever I have asked for a scopes for and your function wraps it up properly with the correct tokens and returns the JSON from Google??
And then we could parse the JSON object for the data needed?? :D :D :D

If you can do something like that, your plugin usefulness suddenly explodes :lol:

Thanks

Rafi

Makes sense. I have added a method getAccessToken(refreshToken) that returns the access token you need to access any authorized API. With that you can send your request. (see https://www.servoyforge.net/news/490)

Hi Patrick,

patrick:
Makes sense. I have added a method getAccessToken(refreshToken) that returns the access token you need to access any authorized API. With that you can send your request. (see https://www.servoyforge.net/news/490)

WOW!!
You are amazing!
That works great, thank you! :D

What is the time frame validity for the access token? Is it the default 1 hour?

Whatever that time frame is, do I then just need to call ‘getAccessToken(refreshToken)’ again after that time to get a new access token?
Is the refresh token valid until I revoke it, so that my client can do a one off launch of system that goes to browser for access code and once that’s been put in to the solution & I get a refresh token, I can just store that for however long and re-use as with getAccessToken(refreshToken) ??

Thanks

Rafi

You simply store the refresh token and get your access token per session. Not sure how long that is valid, but you can get a new one any time. The refresh token should be valid until revoked.

patrick:
You simply store the refresh token and get your access token per session. Not sure how long that is valid, but you can get a new one any time. The refresh token should be valid until revoked.

Fantastic!
Thanks

Hi Patrick,

patrick:
You simply store the refresh token and get your access token per session. Not sure how long that is valid, but you can get a new one any time. The refresh token should be valid until revoked.

this all seems to be working in Smart Client (although I’m not 100% sure if I am ‘refreshing’ my token correctly as sometimes I have to get a new access code…
However, if I try and do everything in Web Client, when I try

			ga_access_token = plugins.Google2.getAccessToken(ga_refresh_token);

I am getting a

Wrapped java.lang.NullPointerException

error :(
I was hoping that I might be able get this all running in web client (WC) and actually, at some point, the call to GA [& the call to get access token] will be happening in headless client (HC).
Will it run in HC??
I can probably cope while testing with it not working in WC, but maybe it is pointing to some other issue…??

Thanks
Rafi

Can you send me the full log file via email, please?

Sent from my iPhone using Tapatalk

Hi

patrick:
Can you send me the full log file via email, please?

Will do
Thanks
Rafi

Just a little question to be sure …

Our CRM application has a sync with Google Agenda, it means that we can send appointments from our app to the Google account of the connected user. With the old version of the plugin (old Google API), we were be able to send appointment to other user’s calendars. But with the new API it seems impossible because Google need the autorization of the owner of the account to use the app.

Please, can you confirm that ? Thank you for your help !

Not sure I understand the problem. With the old version, you needed to store the user’s Google account name and password. With the new version, you need to store a token that the user can retrieve from Google. That approach is actually nicer, because you don’t need to ever store the full account credentials.

I have written an overview of how that works: https://www.servoyforge.net/projects/google2/wiki

Sorry, it had 2-3 things that I didn’t understood about the new Google API but now it’s OK.

It works like a charm thanks to your plugins, many thanks Patrick !