To get user's profile information in google script - google-apps-script

I want to get my domain's user's profile information..I am using profile API for this..
Profile API gives only a few fields like (Family Name, Given Name,Email etc)..But i also want to get these fields also:
occupation,department,Phone [Work], Phone [Mobile], Relation [Manager]...
i am not able to get these fields..So please give me suggestion to get these fields.

I got my all fields by Profile API.... Actually if any field is empty then Profile API doesn't give that field as an output.....
So using Profile API, we can get a user's full information....
Code :
var username="user "
var base = 'https://www.google.com/m8/feeds/';
var fetchArgs = googleOAuth_('contacts', base);
fetchArgs.method='GET'
var url=base+'profiles/domain/'+domainName+'/full/'+username+'?v=3&alt=json'
var name=""
var occupation=""
var department=""
var email=""
var contactNumber_1=""
var contactNumber_2=""
var relation=""
var account=""
var office=""
var personal_account=""
var current_account=""
var language=""
var blog=""
var image=""
try{
var urlFetch = UrlFetchApp.fetch(url, fetchArgs)
var json=Utilities.jsonParse(urlFetch.getContentText())
var profileInfo = json.entry
try{
name=profileInfo.gd$name.gd$fullName.$t
}catch(err){}
try{
occupation=profileInfo.gContact$occupation.$t
}catch(err){}
try{
department=profileInfo.gd$organization[0].gd$orgDepartment.$t
}catch(err){}
try{
var emaillist=profileInfo.gd$email
for(var i=0;i<emaillist.length;i++){
if(emaillist[i].rel.split("#")[1]=='work')
email=profileInfo.gd$email[i].address
}
}catch(err){}
try{
var phonelist=profileInfo.gd$phoneNumber
for(var i=0;i<phonelist.length;i++){
if(phonelist[i].rel.split("#")[1]=='work')
contactNumber_1=phonelist[i].$t
else if(phonelist[i].rel.split("#")[1]=='mobile')
contactNumber_2=phonelist[i].$t
}
}catch(err){}
try{
relation=profileInfo.gContact$relation[0].$t+" ["+profileInfo.gContact$relation[0].rel+"]"
}catch(err){}
}catch(err){}
}
/*
Oauth Authentication
*/
function googleOAuth_(name,scope) {
var oAuthConfig = UrlFetchApp.addOAuthService(name);
oAuthConfig.setRequestTokenUrl("https://www.google.com/accounts/OAuthGetRequestToken?scope="+scope);
oAuthConfig.setAuthorizationUrl("https://www.google.com/accounts/OAuthAuthorizeToken");
oAuthConfig.setAccessTokenUrl("https://www.google.com/accounts/OAuthGetAccessToken");
oAuthConfig.setConsumerKey(consumerKey);
oAuthConfig.setConsumerSecret(consumerSecret);
return {oAuthServiceName:name, oAuthUseToken:"always"};
}
If any field is empty then that tag will not be found thats why all the fields are written in try - catch block...

There isn't a built in API for that in Apps Script directly, but if you are using a Google Apps for Business or Education, you can use the Google Apps through UrlFetch and oAuth. That should expose any profile information that is stored in Google Apps.

Related

Update google contact photo with People API using google apps script

I want to update a contact photo of my contacts using People API and google apps script. official document URL is here https://developers.google.com/people/api/rest/v1/people/updateContactPhoto
My Google Apps script code is below
function imageUpdate(){
var id = 'c6379259805458445151'
var url = 'https://admin.singlaapparels.com/Main/fileurl/64F619B8-C2BE-4EDF-BF9B-01FD60C5D957/4/RakeshKumar.jpg'
var blob = UrlFetchApp.fetch(url).getBlob();
var data = Utilities.base64EncodeWebSafe(blob.getBytes());
var resourceName = 'people/'+id;
Logger.log(data)
var reqBody = {
"photoBytes": data,
"personFields": "photos"
}
var res = People.People.updateContactPhoto(resourceName, reqBody)
Logger.log(res)
}
I got this error: API call to people.people.updateContactPhoto failed with error: Empty response
I change the position of parameters and It works for me.
from
var res = People.People.updateContactPhoto(resourceName, reqBody)
to
var res = People.People.updateContactPhoto(reqBody, resourceName)

How to convert a Google Sheets-File to an Excel-File (XLSX)

The image shows the code who is updated.
The var "xlsFile" is undefined, why? How can I convert the Google Sheets file to an Excel file with (Google Sheets) Script Editor
function googleOAuth_ (name, scope) {
var oAuthConfig = UrlFetchApp.addOAuthService(name);
oAuthConfig.setRequestTokenUrl("https://www.google.com/accounts/OAuthGetRequestToken? scope="+scope);
oAuthConfig.setAuthorizationUrl("https://www.google.com/accounts/OAuthAuthorizeToken");
oAuthConfig.setAccessTokenUrl("https://www.google.com/accounts/OAuthGetAccessToken");
oAuthConfig.setConsumerKey('anonymous');
oAuthConfig.setConsumerSecret('anonymous');
return {oAuthServiceName:name, oAuthUseToken:"always"};
}
function test(){
var id = '#'
exportToXls(id)
}
function exportToXls(id){
var mute = {muteHttpExceptions: true };
var name = DriveApp.getFileById(id).getName()
var url = 'https://docs.google.com/feeds/';
var doc = UrlFetchApp.fetch(url+'download/spreadsheets/Export?key='+id+'&exportFormat=xls', mute).getBlob()
var xlsfile = DocsList.createFile(doc).rename(name+'.xlsx')
}
Using the Drive API, we can get more information about files than is available through the DriveApp methods. Check out the file data, especially exportLinks. Those links contain the magic that will let us get an XLS file. (For fun, put a breakpoint after file is assigned, and check what information you have to play with.)
This script uses the Advanced Drive Service, which must be enabled. A more complete version, with error checking, is available in this gist.
/**
* Downloads spreadsheet with given file id as an Excel file.
* Uses Advanced Drive Service, which must be enabled. * Throws if error encountered.
*
* #param {String} fileId File ID of Sheets file on Drive.
*/
function downloadXLS(fileId) {
var file = Drive.Files.get(fileId);
var url = file.exportLinks[MimeType.MICROSOFT_EXCEL];
var options = {
headers: {
Authorization:"Bearer "+ScriptApp.getOAuthToken()
},
muteHttpExceptions : true /// Get failure results
}
var response = UrlFetchApp.fetch(url, options);
var status = response.getResponseCode();
var result = response.getContentText();
if (status != 200) {
// Get additional error message info, depending on format
if (result.toUpperCase().indexOf("<HTML") !== -1) {
var message = strip_tags(result);
}
else if (result.indexOf('errors') != -1) {
message = JSON.parse(result).error.message;
}
throw new Error('Error (' + status + ") " + message );
}
var doc = response.getBlob();
//DocsList.createFile(doc).rename(file.title + '.xlsx') // Deprecated
DriveApp.createFile(doc).setName(file.title + '.xlsx');
}
The code below uses oAuthConfig which is now deprecated. Use Mogsdad answer instead. The importXLS function uses the drive API and still works.
You'll find many post saying this is not possible and (a few) others saying that you can...and obviously you can !
Mogsdad's answer here (simultaneously) brings an elegant solution using drive service, here is another one so you have a choice ;-)
As a bonus, I added the reverse process, if ever you need it.
Use a function call similar to what I use in the test function to make it work.
function googleOAuth_(name,scope) {
var oAuthConfig = UrlFetchApp.addOAuthService(name);
oAuthConfig.setRequestTokenUrl("https://www.google.com/accounts/OAuthGetRequestToken?scope="+scope);
oAuthConfig.setAuthorizationUrl("https://www.google.com/accounts/OAuthAuthorizeToken");
oAuthConfig.setAccessTokenUrl("https://www.google.com/accounts/OAuthGetAccessToken");
oAuthConfig.setConsumerKey('anonymous');
oAuthConfig.setConsumerSecret('anonymous');
return {oAuthServiceName:name, oAuthUseToken:"always"};
}
function test(){
var id = 'spreadsheet_ID'
exportToXls(id)
}
function exportToXls(id){
var name = DriveApp.getFileById(id).getName()
var url = 'https://docs.google.com/feeds/';
var doc = UrlFetchApp.fetch(url+'download/spreadsheets/Export?key='+id+'&exportFormat=xls',
googleOAuth_('docs',url)).getBlob()
var xlsfile = DocsList.createFile(doc).rename(name+'.xls')
}
function importXLS(){
var files = DriveApp.searchFiles('title contains ".xls"');
while(files.hasNext()){
var xFile = files.next();
var name = xFile.getName();
if (name.indexOf('.xls')>-1){
var ID = xFile.getId();
var xBlob = xFile.getBlob();
var newFile = { title : name+'_converted',
key : ID
}
file = Drive.Files.insert(newFile, xBlob, {
convert: true
});
}
}
}

Edit user signature, but can't use Oauth

I'm tryng to edit the users signature via GAS.
I have found lots of examples and tutorials, and one of the Waqar Ahmad's answers looks very good - Email Settings APIs Authentication.
However, it doesn't work for me.
I don't really understand OAuth autorization, but couldn't find a tutorial for it.
With what should I replace anonymous?
oAuthConfig.setConsumerKey("anonymous");
oAuthConfig.setConsumerSecret("anonymous");
I go to https://console.developers.google.com/ create a project and use clientID for key and client secret for secret, is it right?
Adding more information:
This is the Waqar's code I'm using:
/*-----------------------------------------------------------------------------
This function will update the HTML signature of a user.
Input will be jason data
To disable signature, pass an empty string as signature value
sample parameter
ob = {user='hps', signature='<b>Regards</b><br>Waqar'}
To disable signature
ob = {user='hps', signature=''}
-----------------------------------------------------------------*/
function updateSignature(ob) {
//ob = {};
//ob.user = "hps";
//ob.signature = "<b>Regards</b><br>Waqar";
ob = {};
ob.user = "test#xxxx.it";
ob.signature = "<b>Regards</b><br>Waqar";
var base = 'https://apps-apis.google.com/a/feeds/emailsettings/2.0/';
var xmlRaw = '<?xml version="1.0" encoding="utf-8"?>'+
'<atom:entry xmlns:atom="http://www.w3.org/2005/Atom" xmlns:apps="http://schemas.google.com/apps/2006">'+
'<apps:property name="signature" value="'+htmlEncode(ob.signature)+'" />'+
'</atom:entry>';
var fetchArgs = googleOAuth_('emailSetting',base);
fetchArgs.method = 'PUT';
fetchArgs.payload = xmlRaw;
fetchArgs.contentType = 'application/atom+xml';
var domain = UserManager.getDomain();
var url = base+domain+'/'+ob.user+'/signature';
var urlFetch = UrlFetchApp.fetch(url, fetchArgs);
var status = urlFetch.getResponseCode();
return status;
}
//--------------------------------------------------------------------------
//This function will retreive Signature settings as json.
/*Sample returned object
{user=hps, signature=<b>Regards</b><br>Waqar}
*/
//-----------------------------------------------------------------
function retrieveSignature(user) {
var user = 'hps';
var base = 'https://apps-apis.google.com/a/feeds/emailsettings/2.0/';
var fetchArgs = googleOAuth_('emailSetting',base);
fetchArgs.method = 'GET';
var domain = UserManager.getDomain();
var url = base+domain+'/'+user+'/signature?alt=json';
var urlFetch = UrlFetchApp.fetch(url, fetchArgs);
var jsonString = urlFetch.getContentText();
var jsonArray = Utilities.jsonParse(jsonString).entry.apps$property;
var ob = {};
ob.user = user;
for(var i in jsonArray){
ob[jsonArray[i].name] = jsonArray[i].value;
}
return ob;
}
//Google oAuthConfig..
function googleOAuth_(name,scope) {
var oAuthConfig = UrlFetchApp.addOAuthService(name);
oAuthConfig.getAccessTokenUrl()
oAuthConfig.setRequestTokenUrl("https://www.google.com/accounts/OAuthGetRequestToken?scope="+scope);
oAuthConfig.setAuthorizationUrl("https://www.google.com/accounts/OAuthAuthorizeToken");
oAuthConfig.setAccessTokenUrl("https://www.google.com/accounts/OAuthGetAccessToken");
oAuthConfig.setConsumerKey("xxxxxxxxxxxx.apps.googleusercontent.com");
oAuthConfig.setConsumerSecret("xxxxxxxx-xxxxxx-xxxxx");
return {oAuthServiceName:name, oAuthUseToken:"always"};
}
//This function will escape '<' and '>' characters from a HTML string
function htmlEncode(str){
str = str.replace(/</g,'<');
return str.replace(/>/g,'>')
}
to get the oAuthConfig.setConsumerKey and oAuthConfig.setConsumerSecret I have created a new project in the google developer console, modified to on the Admin SDK API status, created a "Client ID for native application" and used the CLIENT ID in setConsuperKey, and CLIENT SECRET in setConsumerSecret.
Executing the script updateSignature the test#xxxx.it's signature should be changed,
I can see the box "autorization required" clik ok, and appear the request access box,
i click on "grant access" but nothing happes, and no error are shown.
Executing the same function in debug mode, i have the same boxes and a red box with "Errore OAuth" at the end.
I'm doing something wrong... please help me to find the mistake!!
Thanks again.
Marco
Finally i found the clue!!
Thank's to mike's quastions and answers
who let me discover This example
I Finally understand!!
in consumerkey you have to set your domain (p.e. "mydomain.it",
in consumerSecret you have to set the "Secret data of the customer to OAuth:" from admin google console->secority->advanced settings->Manage data OAuth key and secret for this domain.
I was confusing by the secret key in the google developer console, may be this answer can help

Creating a group with Admin SDK Directory API in Google Apps Script doesn't work "On form submit"

I've read through all of the relevant pages in the Admin ADK Directory API documentation and several questions on stackoverflow, and I'm still stuck.
I am the super admin of my Google Apps domain, and I want users in my domain to be able to create their own Google Groups. I made a Google Form where the user specifies the name and email of the group. Then the Google Form Responses sheet has an "On form submit" trigger that invokes my code to create the group.
This code works when I run createGroupTest() from the Script Editor. It creates the group in my Google apps domain immediately.
This code does not work when the "On form submit" trigger runs the onFormSubmit(e) function. I get the email from the catch(e) saying Exception: Failed to authenticate for service: Groups.
Does anyone know what is causing the oauth authentication to work from within the Script Editor but not when invoked by the onFormSubmit function?
function onFormSubmitTest() {
var t = new Date();
t = t.getTime();
onFormSubmit([t, "AAA Test Group " + t], ["aaa.testgroup." + t + "#mydomain.com"], ["me#mydomain.com"]);
}
var consumerKey = "mydomain.com";
var consumerSecret = "xxxxxxxxxxxxxxxxxxxxxxxx";
var domainName = "mydomain.com";
function onFormSubmit(e) {
var timestamp = e.values[0];
var groupName = e.values[1];
var groupEmail = e.values[2];
var owner = e.values[3];
owner = owner.split("#")[0];
var description = 'test';
var requestBody = {email: groupEmail, name: groupName, description: description};
var scope = "https://www.googleapis.com/auth/admin.directory.group";
var fetchArgs = googleOAuth_("Groups", scope);
fetchArgs.method = "POST";
fetchArgs.contentType = "application/json";
fetchArgs.payload = JSON.stringify(requestBody);
fetchArgs.muteHttpExceptions = true;
var url = 'https://www.googleapis.com/admin/directory/v1/groups?key=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
UrlFetchApp.fetch(url, fetchArgs);
}
function googleOAuth_(name,scope) {
var oAuthConfig = UrlFetchApp.addOAuthService(name)
oAuthConfig.setRequestTokenUrl("https://www.google.com/accounts/OAuthGetRequestToken?scope="+scope);
oAuthConfig.setAuthorizationUrl("https://www.google.com/accounts/OAuthAuthorizeToken");
oAuthConfig.setAccessTokenUrl("https://www.google.com/accounts/OAuthGetAccessToken");
oAuthConfig.setConsumerKey(consumerKey);
oAuthConfig.setConsumerSecret(consumerSecret);
return {oAuthServiceName:name, oAuthUseToken:'always'};
}
I figured it out: I had failed to include the domain extension in the groupEmail string (because my Google Form only asks the user to fill in the group email name without the domain extension).

Retrieve photo from Google Apps Profile API

I am trying to retrieve Google Apps Profile API photo using Google Apps Profile API but It keeps on prompting to authorize the request even after authorizing it.
Here is the code which I have tried so far.
function getPhoto(userName){
userName = 'user#myDomain.com'; //will be replaced by actual username
var scope = 'https://www.google.com/m8/feeds/profiles';
var fetchArgs = googleOAuth_('Profile', scope);
fetchArgs.method = 'GET';
var domain = UserManager.getDomain();
var url = 'https://www.google.com/m8/feeds/photos/profile/'+domain+'/'+userName+'?v=3';
var rawData = UrlFetchApp.fetch(url, fetchArgs).getContentText();
Logger.log(rawData);
}
//google oAuth
function googleOAuth_(name,scope) {
var oAuthConfig = UrlFetchApp.addOAuthService(name);
oAuthConfig.setRequestTokenUrl("https://www.google.com/accounts/OAuthGetRequestToken?scope="+scope);
oAuthConfig.setAuthorizationUrl("https://www.google.com/accounts/OAuthAuthorizeToken");
oAuthConfig.setAccessTokenUrl("https://www.google.com/accounts/OAuthGetAccessToken");
oAuthConfig.setConsumerKey("anonymous");
oAuthConfig.setConsumerSecret("anonymous");
return {oAuthServiceName:name, oAuthUseToken:"always"};
}
Refernces :
https://developers.google.com/google-apps/profiles/#photo_management
https://developers.google.com/google-apps/profiles/auth
Note : I have super administrator access to the domain I am trying
You could try with
var scope = 'https://www.google.com/m8/feeds/';
to authorize.
You can take a look at this Library. It lets you get the profile picture as a blob without any issue:
https://sites.google.com/site/scriptsexamples/new-connectors-to-google-services/profiles-services