Gadget OAuth2 Authorization - oauth

I am developing a gadget (html, JS) to run inside (Google Calendar page).
I need to show user's tasks there so I need a connection to Google Task Api.
I need to use OAuth2 authorization and such requests as:
GET https://www.googleapis.com/tasks/v1/users/#me/lists
GET https://www.googleapis.com/tasks/v1/lists/tasklist/tasks
Unfortunately I havent found description or samples for gadgets withOAuth2` authorization.
Could you please tell me what will the OAuth2 section look like in this case?
<OAuth2>
<Service name="[service_name]">
<Authorization url="https://.../authorize"/>
<Token url="https://.../oauth2/token"/>
</Service>
</OAuth2>
Could you please approve this code for a request? (JS)
function loadContents(){
var url = "https://www.googleapis.com/tasks/v1/users/#me/lists?alt=json";
var params = {};
params[gadgets.io.RequestParameters.CONTENT_TYPE] = gadgets.io.ContentType.JSON;
params[gadgets.io.RequestParameters.AUTHORIZATION]=gadgets.io.AuthorizationType.OAUTH2;
params[gadgets.io.RequestParameters.METHOD] = gadgets.io.MethodType.GET;
params[gadgets.io.RequestParameters.OAUTH_SERVICE_NAME] ="[service_name]";
var callback = function (response) {
if (response.oauthApprovalUrl) {
...
}
};
gadgets.io.makeRequest(url, callback, params);
}

The Gadgets API framework doesn't support OAuth2. The Tasks API does support OAuth1 however, so you may still be able to get things working.

The answer is - using OAuth instead of OAuth 2.0.
OAuth section should be:
<OAuth>
<Service name="google">
<Access url="https://www.google.com/accounts/OAuthGetAccessToken" method="GET" />
<Request url="https://www.google.com/accounts/OAuthGetRequestToken?scope=https://www.googleapis.com/auth/tasks" method="GET" />
<Authorization url="https://www.google.com/accounts/OAuthAuthorizeToken?oauth_callback=http://oauth.gmodules.com/gadgets/oauthcallback" />
</Service>
</OAuth>
The request is [JS]:
var params = {};
url = "https://www.googleapis.com/tasks/v1/users/#me/lists?key=YOUR_API_KEY";
params[gadgets.io.RequestParameters.CONTENT_TYPE] = gadgets.io.ContentType.JSON;
params[gadgets.io.RequestParameters.AUTHORIZATION] = gadgets.io.AuthorizationType.OAUTH;
params[gadgets.io.RequestParameters.OAUTH_SERVICE_NAME] = "google";
params[gadgets.io.RequestParameters.OAUTH_USE_TOKEN] = "always";
params[gadgets.io.RequestParameters.METHOD] = gadgets.io.MethodType.GET;
To use OAuth1 for Google Tasks API we need an
API key.

Related

OAuth 2.0 Authorization: GAS and Google Maps Engine

I have a Google Maps Engine project where a datasource can be updated via Google Forms/Google Apps Script. I know that there is a way to configure OAuth in GAS (https://developers.google.com/apps-script/reference/url-fetch/o-auth-config) but I can't figure out how to make it work after spending hours reading through the GAS and GME documentation. I have been able to get around it using the OAuth Playground to obtain an access token, but I need to manually refresh each hour. I know the answer is probably simple, but I am new to OAuth and I can't find a simple guide out there to help me.
How can I get my Google Apps Script to play nicely with Google Maps Engine through OAuth?
I have included how I currently access GME below:
/* This function is called when a new provider is added through the "Medical Providers" form
It sends an HTTP request to Google Maps Engine to add the new provider to the map */
function addNewtoTable(row){
var aPIKey = "MY_API_KEY";
var bearer = "ACCESS_TOKEN_FROM_OAUTH_PLAYGROUND";
var projectID = "MY_PROJECT_ID";
var tableID = "MY_TABLE_ID";
//tutorial here https://developers.google.com/maps-engine/documentation/tutorial
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("Providers");
var address = sheet.getRange(row,2).getValue();
var response = Maps.newGeocoder().geocode(address);
for (var j = 0; j < response.results.length; j++) {
var result = response.results[j];
//Logger.log('%s: %s, %s', result.formatted_address, result.geometry.location.lat,
// result.geometry.location.lng);
};
var lat = result.geometry.location.lat;
var long = result.geometry.location.lng;
var name= '"'+sheet.getRange(row,1).getValue()+'"';
var phone= '"'+sheet.getRange(row,4).getValue().toString()+'"';
var email= '"'+sheet.getRange(row,3).getValue()+'"';
var inbounds= '"'+sheet.getRange(row,5).getValue().toString()+'"';
var outbounds = '"'+sheet.getRange(row,6).getValue().toString()+'"';
var lastIn = '" '+sheet.getRange(row,7).getValue().toString()+' "';
var lastOut = '" '+sheet.getRange(row,8).getValue().toString()+' "';
var gxid = '"'+sheet.getRange(row,9).getValue().toString()+'"';
//HTTP request goes here
var payload = '{features:[{type: "Feature",geometry:{type: "Point",coordinates: ['+long+','+lat+']},properties: {gx_id: '+gxid+',name: '+name+',phone:'+phone+',email:'+email+',inbound:'+inbounds+',outbound:'+outbounds+',last_inbound:'+lastIn+',last_outbound:'+lastOut+'}}]}';
Logger.log(payload);
var headers = {"Authorization": "Bearer ACCESS_TOKEN_FROM_OAUTH_PLAYGROUND", "Content-type": "application/json"};
var options ={"method" : "post","headers" : headers, "payload" : payload, "muteHttpExceptions" : true};
var httpresponse = UrlFetchApp.fetch("https://www.googleapis.com/mapsengine/v1/tables/MY_TABLE_ID/features/batchInsert",options);
Logger.log(httpresponse);
if (httpresponse!=""){
MailApp.sendEmail('MY_EMAIL', 'HTTP Request Failed to Send', httpresponse);
};
};
It's certainly possible. The App Script docs have a tutorial explaining how to connect to a remote service using OAuth that uses the Twitter API as an example. This example also shows an OAuth-authorized call being executed.
The main difference in the tutorial for Maps Engine is the first step, where you don't set up with Twitter, you set up in the Developers Console.
You want to create a new OAuth client ID, under APIs & Auth -> Credentials. It's a web application.
Instead of setting the "Callback URL" in Twitter, you'll set the "Authorized Redirect URI" in the console, when creating the client ID. Set the authorized origins to docs.google.com too, just in case.
You'll get your "Consumer Key" and "Consumer Secret" through console.developers.google.com too, they correspond to the Client ID and Client Secret that are referred to in this GME doc.
In addition to the set up, these pointers may help you.
The UrlFetchApp.addOauthService("twitter") calls can use any string as an identifier, there's nothing special about the phrase "twitter", but it needs to match oAuthServiceName
The URLs you need look like they should be these (grabbed from here):
oAuthConfig.setAccessTokenUrl("https://www.google.com/accounts/OAuthGetAccessToken");
oAuthConfig.setRequestTokenUrl("https://www.google.com/accounts/OAuthGetRequestToken?scope="+scope); Scope is explained here.
oAuthConfig.setAuthorizationUrl("https://www.google.com/accounts/OAuthAuthorizeToken");
A little too late for my purposes, but I found that Google themselves made a library for GAS that enables OAuth 2.0. Why this is not included within GAS is beyond me. This also looks to be pretty recent, with some updates as of 5 days ago.

Calling Twitter API from Google Apps Script

I am trying to call Twitter's REST API from Google Apps Script.
The code I am using is copied one to one from here:
https://developers.google.com/apps-script/guides/services/external
and specifically:
function test() {
var consumerKey = 'XXXX'; // Copied from my twitter app setting.
var consumerSecret = 'XXXXX'; // Copied from my twitter app setting.
var oauthConfig = UrlFetchApp.addOAuthService('twitter');
oauthConfig.setAccessTokenUrl('http://api.twitter.com/oauth/access_token');
oauthConfig.setRequestTokenUrl('http://api.twitter.com/oauth/request_token');
oauthConfig.setAuthorizationUrl('http://api.twitter.com/oauth/authorize');
oauthConfig.setConsumerKey(consumerKey);
oauthConfig.setConsumerSecret(consumerSecret);
var options = {
'oAuthServiceName' : 'twitter',
'oAuthUseToken' : 'always'
};
var url = 'https://api.twitter.com/1.1/search/tweets.json?count=5&include_entities=false&result_type=recent&q=hello';
var response = UrlFetchApp.fetch(url, options);
var tweets = JSON.parse(response.getContentText());
Logger.log(tweets)
}
Nevertheless, I get Oauth ERROR every time I run it.
My settings in the twitter app allows for "Read and Write"
Any suggestions
Just go to your twitter application and set the callback url as
https://script.google.com
This is now best handled through the following open source Google Apps Script library:
https://github.com/googlesamples/apps-script-oauth1
The example in the documentation is twitter itself (because it's probably the only remaining user of oauth v1 out there...)
Cheers, M

How to Access twitter from Salesforce

I am struggling to get this done, I need to connect to twitter rest Api 1.1 to get user details, time line etc.
What I came across is:
I have a Twitter App with access token ,secrete etc.
Now how to use all that access token etc to send (GET or POST) request to Twitter from Salesforce. How to set header or how to authenticate request.
A tutorial would be very help full all I could find was tutorials for php etc I need it for "salesforce"
Note: I don't want to use a external lib
You should be able to do this directly from Apex using the HTTP REST library. Here is the first Google result for "salesforce apex twitter integration" with this sample code from Navatar_DbSup:
VF CODE:
<apex:inputTextarea id="tweetInput" onkeyup="return maxLength();" onKeyPress="return maxLength();" value="{!newTweet}" rows="2" cols="73"/>
<apex:commandButton id="tweetBtn" style="height:35px;" value="Tweet" action="{!postTweet}" />
Controller code:
*** post tweets into twitter*/
public String newTweet{get;set;}
public Void postTweet()
{
Http h = new Http();
HttpRequest req = new HttpRequest();
Method = 'POST';
req.setMethod(Method);
req.setEndpoint('https://api.twitter.com/1/statuses/update.xml');
newTweet = newTweet.replace('%','%25').replace('&','%26').replace('#','%40').replace(';','%3B').replace('?','%3F').replace('/','%2F').replace(':','%3A').replace('#','%23').replace('=','%3D').replace('+','%2B').replace('$','%24').replace(',','%2C').replace(' ','%20').replace('<','%3C').replace('>','%3E').replace('{','%7B').replace('}','%7D').replace('[','%5B').replace(']','%5D').replace('`','%60').replace('|','%7C').replace('\\','%5C').replace('^','%5E').replace('"','%22').replace('\'','%27').replace('!','%21').replace('*','%2A').replace('(','%28').replace(')','%29').replace('~','%7F');
req.setBody('status='+newTweet);
req.setHeader('Content-Type','application/x-www-form-urlencoded');
OAuth oa = new OAuth();
if(!oa.setService())
{
message=oa.message;
}
oa.sign(req);
HttpResponse res = h.send(req);
system.debug('&&&&&&&&&&&&&&&&7' + res.getBody());
PostTweetbody = res.getBody() + '___' + message;
newTweet = '';
}

Getting "invalid credentials" When Performing Fusion Tables INSERT From A Google Gadget

We have a Google Gadget that connects to Fusion Tables through the Fusion Table API with the user’s Google Account. It performs SELECT and INSERT.
We built the gadget using OAuth1 (shindig library for opensocial). It worked fine for the deprecated version of the Fusion Table API. When we migrated it to the new PAPI, the select qworks fine because authentication with OAuth2 is not necessary. For the INSERT however, it is necessary. The documentation for opensocial has not been completely updated:http://docs.opensocial.org/display/OSREF/OpenSocial+Specification+Considerations
I cannot figure out how to successfully use OAuth2 to perform an Insert. We have the API privileges to read/write at the domain level and the user has owner privileges to the Fusion table.
The error I am getting is saying “Invalid Credentials” Pretty vague and I cannot tell why.
Here is our gadget header:
<OAuth>
<Service name="google">
<Access url="https://www.google.com/accounts/OAuthGetAccessToken" method="GET" />
<Request url="https://www.google.com/accounts/OAuthGetRequestToken?scope=https://www.googleapis.com/auth/fusiontables%20https://docs.google.com/feeds/default/private"
method="GET" />
<Authorization url="https://www.google.com/accounts/OAuthAuthorizeToken?oauth_callback=http://oauth.gmodules.com/gadgets/oauthcallback" />
</Service>
</OAuth>
I am not sure exactly how to update, so I added another header:
<OAuth2>
<Service name="google">
<Authorization url="https://www.google.com/accounts/OAuthAuthorizeToken?oauth_callback=http://oauth.gmodules.com/gadgets/oauth2callback" />
</Service>
</OAuth2>
When we make the call, we do the following:
options = {};
options[gadgets.io.RequestParameters.CONTENT_TYPE] = gadgets.io.ContentType.TEXT;
options[gadgets.io.RequestParameters.METHOD] = gadgets.io.MethodType.POST;
options[gadgets.io.RequestParameters.POST_DATA] = postData;
options[gadgets.io.RequestParameters.AUTHORIZATION] = gadgets.io.AuthorizationType.OAUTH2;
options[gadgets.io.RequestParameters.HEADERS] = {'Authorization':'{encrypted fusiontable key}'}; //not sure if this helps but its extra
options[gadgets.io.RequestParameters.OAUTH_SERVICE_NAME] = "google";
options[gadgets.io.RequestParameters.OAUTH_USE_TOKEN] = "always";
URL = https://www.googleapis.com/fusiontables/v1/query?key={encrypted fusiontable key} &client_id={id number}”;
postData=”sql=INSERT…”;
gadgets.io.makeRequest(URL, handlerWrapper, options);
Thanks!
If you're doing a write request, you will need to supply the oauth token that encodes the user's permission to access the table. It looks like this might be in gadgets.io.RequestParameters.OAUTH_REQUEST_TOKEN. The key is used for read access from public tables. Also, you may need to set the OAUTH_SERVICE_NAME to "fusiontables".

Yelp API Google App Script OAuth

I am trying to use Google Apps Script to query the Yelp Search Api and put the results into a spreadsheet. I having issues making the call to yelp using this example as a model:
var consumerKey = "... register your app with Twitter ...";
var consumerSecret = "... register your app with Twitter ...");
var oauthConfig = UrlFetchApp.addOAuthService("twitter");
oauthConfig.setAccessTokenUrl("http://api.twitter.com/oauth/access_token");
oauthConfig.setRequestTokenUrl("http://api.twitter.com/oauth/request_token");
oauthConfig.setAuthorizationUrl("http://api.twitter.com/oauth/authorize");
oauthConfig.setConsumerKey(consumerKey);
oauthConfig.setConsumerSecret(consumerSecret);
// "twitter" value must match the argument to "addOAuthService" above.
var options = {
"oAuthServiceName" : "twitter",
"oAuthUseToken" : "always"
};
var url = "http://api.twitter.com/1/statuses/user_timeline.json";
var response = UrlFetchApp.fetch(url, options);
var tweets = JSON.parse(response.getContentText());
// Handle tweets
https://developers.google.com/apps-script/class_oauthconfig
This class only has methods for setting the access token URLs which Yelp doesn't appear to provide. They just provide the Token and Token Secret directly. I assumed that these would be set like the Consumer Key and Secret but I haven't found a way.
The Yelp API uses oAuth1.0a to authorize and identifiy the API caller not the end user that might be using the application. This is not like a Twitter scenario where you have to let your users login. Therefore, you dont need any access token URLs or other details. You are able to create all the necessary tokens to get started. Here is how your API console should look like once everything is setup (I've obfuscated my keys for obvious reasons) -
Now, you'll need to make the API calls from the server side using UrlFetchApp and not use the jQuery AJAX APIs as that Yelp API doesn't seem to allow CORS and JSONP is not allowed with HtmlService. Otherwise you'll get errors like this below in the console -
Lastly, here is some sample code to get you started. I based these off their JavaScript sample -
var auth = {
consumerKey: "YOURKEY",
consumerSecret: "YOURSECRET",
accessToken: "YOURTOKEN",
accessTokenSecret: "YOURTOKENSECRET",
};
var terms = 'food';
var near = 'San+Francisco';
var accessor = {
consumerSecret: auth.consumerSecret,
tokenSecret: auth.accessTokenSecret
};
var parameters = [];
parameters.push(['term', terms]);
parameters.push(['location', near]);
parameters.push(['oauth_consumer_key', auth.consumerKey]);
parameters.push(['oauth_consumer_secret', auth.consumerSecret]);
parameters.push(['oauth_token', auth.accessToken]);
var message = {
'action': 'http://api.yelp.com/v2/search',
'method': 'GET',
'parameters': parameters
};
OAuth.setTimestampAndNonce(message);
OAuth.SignatureMethod.sign(message, accessor);
var parameterMap = OAuth.getParameterMap(message.parameters);
parameterMap.oauth_signature = OAuth.percentEncode(parameterMap.oauth_signature)
var url = OAuth.addToURL(message.action,parameterMap);
var response = UrlFetchApp.fetch(url).getContentText();
var responseObject = Utilities.jsonParse(response);
//have my JSON object, do whatever we want here, like add to spreadsheets
I also added a couple of GS script files with the contents of the oAuth JS code and SHA1 JS code from the links provided (just copy paste into new files in the script editor). However, if you feel adventurous, you could also use the Utilities APIs to manually sign and encode the necessary oAuth params.
Hope this helps. I was able to get Yelp responses with all the provided samples.

Resources