whar is the oauth service name for the google apps reseller api - oauth

I tried to use the google apps reseller api with google apps script. To use oauth I need the AuthServiceName. what is the right name? "apps" does not work.

AuthServiceName is defined in your application, its not dependent on the API that you are connecting to, i would suspect that you may not have completed all the steps necessary or that your oauth call is not properly structured.
Here is an example of a call that retrieves the details of domains.
function getCustomer() {
//set up oauth for Google Reseller API
var oAuthConfig1 = UrlFetchApp.addOAuthService("doesNotMatter");
oAuthConfig1.setRequestTokenUrl("https://www.google.com/accounts/OAuthGetRequestToken?scope=https://www.googleapis.com/auth/apps.order.readonly");
oAuthConfig1.setAccessTokenUrl("https://www.google.com/accounts/OAuthGetAccessToken");
oAuthConfig1.setAuthorizationUrl("https://www.google.com/accounts/OAuthAuthorizeToken?oauth_callback=https://script.google.com/a/macros");
oAuthConfig1.setConsumerKey(CONSUMER_KEY);
oAuthConfig1.setConsumerSecret(CONSUMER_SECRET);
var options1 = {oAuthServiceName:"doesNotMatter", oAuthUseToken:"always",
method:"GET", headers:{"GData-Version":"3.0"}, contentType:"application/x-www-form-urlencoded"};
//set up user profiles url
var theUrl = "https://www.googleapis.com/apps/reseller/v1/customers/somedomain.com";
//urlFetch for customer list
var customerInfo = "";
try {
var response = UrlFetchApp.fetch(theUrl,options1);
customerInfo = response.getContentText();
} catch(problem) {
Logger.log(problem.message);
}
Logger.log(customerInfo);
}
This will work if
You have a reseller account (I guess i.e. I did not test on my non reseller account)
You have create a project in the API console, and enabled the Reseller API
You know your SECRET and KEY lifted form the console
I have use a read.only scope which is safe, if not you need to set up your tests in the sand box
Let me know if you need any more clarifications

Related

Error 400: invalid_scope "https://www.googleapis.com/auth/chat.bot"

The documentation for the new google hangouts chat says that you need to authorize the scope https://www.googleapis.com/auth/chat.bot to do pretty much anything.
Here's the error:
While generating an authentication URL using their OAuth2 client I get the message that the scope is invalid. I don't have that problem if I use https://www.googleapis.com/auth/chat or some other scope like the one for google plus.
When I try to google things on in the API Explorer no combination of the URL or parts of the URL work either.
Here is my code to fetch the URL, seems to work just fine for everything else:
var {google} = require('googleapis');
var OAuth2 = google.auth.OAuth2;
var oauth2Client = new OAuth2(
"clientid-idididid.apps.googleusercontent.com",
"_secretsuff",
"http://localhost:3000/auth/google/callback"
);
var scopes = [
"https://www.googleapis.com/auth/chat", //Works
"https://www.googleapis.com/auth/chat.bot" // Does not work
];
var url = oauth2Client.generateAuthUrl({
access_type: 'offline',
scope: scopes,
});
console.log(url);
In case others are running across this problem I think I've figured this out. Google doesn't seem need this auth scope enabled by a domain user because it's already authorised on the domain when your testing your bot. The "authorisation" of these scopes are dictated by users in a domain adding/removing bots from spaces.
I'll go into a bit of detail if you're confused.
When you create a bot in the console for an organisation https://console.cloud.google.com/apis/api/chat.googleapis.com/ your bot is added to the domain and can be added to spaces by users. If then go over to to the credentials and create a service account you can use that json file credentials to access the API as your bot. The code below gets a list of the people in a space.
var { google } = require('googleapis');
var chat = google.chat("v1");
var key = require('./google_service-account-credentials.json');
var jwtClient = new google.auth.JWT(
key.client_email,
null,
key.private_key,
['https://www.googleapis.com/auth/chat.bot'], // an array of auth scopes
null
);
jwtClient.authorize(function (err, tokens) {
chat.spaces.members.list({
auth: jwtClient,
parent: "spaces/AAAAD4xtKcE"
}, function (err, resp) {
console.log(resp.data);
});
});
If you try to get a list of members on other spaces (and other domains) the bot will fail with the exact same error message:
"Bot is not a member of the space."
I assume if you list your bot on the marketplace and it gets added to different domains and spaces google's API makes sure that your bot can do what it's trying to do on a space by space basis. It would be annoying have to setup some authentication flow after a bot has already been added for it to do its job. This is also probably why the current REST api doesn't let you list spaces under domains, it's not the paradigm this API works under.
It may have to do with one of the following:
The scope is created for service accounts. Make sure you are accessing the REST API with a service account.
Make sure that the bot is added to the room or space and has access to what you want it do.
Make sure the Service account is part of the bot project that you are using for the bot.

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.

Multiple Twitter accounts using Google App Script

I'm experimenting with Google Apps Script and Twitter, and I'd like to be able to access multiple Twitter accounts through one spreadsheet. At the moment I've attempted the approach below (a unique OAuthService name for each Twitter account), and this kind-of works but it clunky because I have to randomly authorize one account (and not more than one) each time the script is run, and the popup dialog doesn't tell me which account (i.e. id) I'm authenticating for.
Ideally, I'd like to force each user to give Twitter permission on first use, then store that token for later use - is this possible withe Google App Script?
Thanks.
function oAuth(id) {
var oauthConfig = UrlFetchApp.addOAuthService(NS_TWITTER + id);
oauthConfig.setAccessTokenUrl("https://api.twitter.com/oauth/access_token");
oauthConfig.setRequestTokenUrl("https://api.twitter.com/oauth/request_token");
oauthConfig.setAuthorizationUrl("https://api.twitter.com/oauth/authorize");
oauthConfig.setConsumerKey(CONSUMER_KEY);
oauthConfig.setConsumerSecret(CONSUMER_SECRET);
};
and then
var options =
{
"method": "GET",
"oAuthServiceName":NS_TWITTER + id,
"oAuthUseToken":"always",
};
try {
var result = UrlFetchApp.fetch(feed, options);
}
Yes, is possible.
To store the token values use userProperties (Docs here) or CacheService wich remains for 20 minutes in cache (Docs here).
Example storing token using UserProperties
UserProperties.setProperty('token', 'value');
var token = UserProperties.getProperty('token');
Example storing token using CachService
// Gets a cache that is private to the current user
var cache = CacheService.getPrivateCache();
cache.put('token', 'value');
var token = cache.get('token');
After building you cache solution you need to check if the token is valid with twitter API. If it's invalid you should require the auth again.

How to import Google contacts in ASP.NET MVC (no third party please)

I have Used a API for importing the contacts of GMail. The code is something like this:
public static DataTable GetGmailContacts(string App_Name, string Uname, string UPassword)
{
Log.LogDebug(string.Format("SettingsController.cs-Importing Contacts for email={0}, password={1} from gmail server", Uname, UPassword));
DataTable dt = new DataTable();
DataColumn C2 = new DataColumn();
C2.DataType = Type.GetType("System.String");
C2.ColumnName = "EmailID";
try
{
dt.Columns.Add(C2);
RequestSettings rs = new RequestSettings(App_Name, Uname, UPassword);
rs.AutoPaging = true;
ContactsRequest cr = new ContactsRequest(rs);
Feed<Contact> f = cr.GetContacts();
foreach (Contact t in f.Entries)
{
foreach (EMail email in t.Emails)
{
DataRow dr1 = dt.NewRow();
dr1["EmailID"] = email.Address.ToString();
dt.Rows.Add(dr1);
}
}
Log.LogDebug(string.Format("SettingsController.cs-Imported Contacts for email={0}, password={1} from gmail server", Uname, UPassword));
return dt;
}
catch (Exception e)
{
dt = null;
Log.LogDebug(string.Format("SettingsController.cs-Imported Contacts for email={0}, password={1} from gmail server", Uname, UPassword));
return dt;
}
}
This code importing the GMail contacts but it is third party DLL. So some time Google warned me to not use it. So I want to use Direct API.
Versions 1 and 2 of the Google Contacts API have been officially deprecated as of April 20, 2012. They will continue to work as per our deprecation policy, but we encourage you to move to version 3
From: https://developers.google.com/google-apps/contacts/v2/developers_guide?hl=en
Authorizing requests with OAuth 2.0
Requests to the Google Contacts API for non-public user data must be authorized by an authenticated user.
The details of the authorization process, or "flow," for OAuth 2.0 vary somewhat depending on what kind of application you're writing. The following general process applies to all application types:
When you create your application, you register it with Google.
Google then provides information you'll need later, such as a client
ID and a client secret.
Activate the Google Contacts API in the Services pane of the Google
APIs Console. (If it isn't listed in the Console, then skip this
step.)
When your application needs access to user data, it asks Google for
a particular scope of access.
Google displays an OAuth dialog to the user, asking them to
authorize your application to request some of their data.
If the user approves, then Google gives your application a
short-lived access token.
Your application requests user data, attaching the access token to
the request.
If Google determines that your request and the token are valid, it
returns the requested data.
From: https://developers.google.com/google-apps/contacts/v3/#authorizing_requests_with_oauth_20
Check Google Contacts API v2 Developer's Guide - .Net and Google Contacts API version 3.0 to write your own code :)

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