.getEmail() method for DriveApp and SpreadsheetApp for Google Script - google-apps-script

I am new to Google Scripts for Applications and am trying to get an array of the users that can edit a Google spreadsheet. When I do DriveApp.getFileById('xxxxxx').getEditors()...it returns an array of users. When I run the .getName() method on each item in the array, it returns the names. However, when the run the .getEmail() method on each item, it does not return the email address for each user.
I tried opening the spreadsheet with SpreadsheetApp.openFileById('xxxxxx').getEditors()...and with this array I was able to run the .getEmail() method on each item and get the email addresses.
What is the difference between these .getEmail() methods? Why can I seem to get the emails from the SpreadsheetApp, but not the DriveApp?

DriveApp as well as the drive api protect collaborator's emails. You no longer can get them.
You have to use the older apis which will eventually be deprecated.
In the new api you can only tell the users email if you previously shared something with them and you saved their permissionId. See the drive api docs for more.

Related

How can I set an app script on a Google Sheet via the API?

Is there a way to set an App Script on a new Google Sheet via the Google Sheets API? We use pygsheets as our Python API Client for Google Sheets. Since we are using the onSelectionChange trigger to populate certain cells with a date, we would like to setup the app script after we have populated rows in the spreadsheet.
The Google Sheets API doesn't have a method to do this. You can use the Apps Script API instead, but there are a few caveats which may or may not work with your use case:
You can use projects.create to create a new Apps Script project and attach it to a Sheets file by specifying the parentId field, which is the Sheet's ID. However, there are no methods to attach a preexisting script to a Sheet. You can still use projects.updateContent to add the required script files, though.
You cannot unbind the script once it has been attached.
This API does not work with service accounts, and the user running it needs to explicitly allow it in their settings page. This is for security reasons, since allowing a malicious app to freely write scripts on your account could be catastrophic, but it adds more steps that your users would need to take in order to run your app.

How can I Find All Uses of a Google Script Library?

I have a Google Script library that is used by at least 100 other scripts (some that are bound to spreadsheets/documents, some that are not). How can I find all of these client scripts that reference my library script?
More specifically, I need to be able to add a new feature into the library that requires new permissions that I (the user) must grant. The client scripts won't run if I just add this feature to the library without granting the permissions to each of the client scripts. So ultimately, I need to give this new permission to each of the clients. And if I knew what scripts were actually using this library, I could do that manually for each one. But I need to URL's or ID's or something for each of those scripts.
Answer:
Unfortunately this is not possible to do.
More Information
It is possible to get a list of standalone Scripts from your Drive, though scripts bound to a file can not be searched for using regular searching methods.
It is possible, using the help of this Google Account page to get a list of all the Apps that have access to your account, though only files you have authorised will appear here, and apps which are not just those created by you in Apps Script will appear there (for example, other add-ons or even Android Apps bound to your account appear here).
A Partial Workaround:
Using Google Apps Script, you can list all Apps Script Projects that you own with help of the MimeType enumeration GOOGLE_APPS_SCRIPT
var scripts = DriveApp.getFilesByType(MimeType.GOOGLE_APPS_SCRIPT);
var arr =[ ];
while (scripts.hasNext()) {
var script = scripts.next();
arr.push(script)
}
Logger.log(arr);
Or even just searching for type:script in Drive, however this only returns a list of scripts that are not bound to a file.
You can then use regular Google Drive search terms to find which of these files contain, for example, a unique method name that the library uses. I am aware this isn't a perfect solution and you would still have to look for projects bound to a file using the above webpage.
Feature Request:
It appears that back in 2014 a feature request for this was made on Google's Issue Tracker, though I would suggest creating another feature request for this here as it was marked as a duplicate of another issue. You can make a feature request under the correct Apps Script component here.
References:
Google Apps Script - Enum MimeType
Google Drive Search Query Terms
Apps with access to your account
Google's Issue Tracker
Feature Request: Listing and searching for container bound scripts
Create an Apps Script Feature Request

Getting all viewers of spreadsheet using App Script

i wrote code for getting all viewers of spreadsheet in app script .
i have used getViewers() method to get viewers names who actually viewed it. but that method is returning me the names of people to whom i actually shared the spreadsheet....
is there any other way that i can get all viewers of spreadsheet.?
is there any web automation tools that can solve my problem?
Answer:
It is not possible to get a list of people that have opened your a Google Drive file using Google Apps Script - a method that returns this list does not exist. The getViewers() method returns the list of people with view and comment permissions for a file, while getEditors() retrieves the list of people that have edit permissions.
The Issue:
is there any other way that i can get all viewers of spreadsheet.? is there any web automation tools that can solve my problem?
There is no way of getting viewers of a Google Sheet as this is a huge security issue. This information is not stored and is therefore not retrievable.
Workaround:
You can make a custom function which stores the username of a person when they open the file - though be aware that triggers have restrictions and will only run if the person opening the file has edit access. I have included a list of Apps Script Trigger Restrictions below for you to look through and decide what is the best approach for you.
Code:
function onOpen(e) {
var user = e.user.getEmail();
// do some code to store or save this parameter
// for example save it to a hidden sheet or email it to yourself
// though an email would require an installable trigger to be made
}
Simple Trigger Restrictions:
These are not all of the restrictions (full restrictions are available here), but these are the ones that I believe to be most relevant for you.
As per the Google Apps Script Simple Triggers documentation:
They do not run if a file is opened in read-only (view or comment) mode.
They cannot access services that require authorization. For example, a simple trigger cannot send an email because the Gmail service requires authorization, but a simple trigger can translate a phrase with the Language service, which is anonymous.
They can modify the file they are bound to, but cannot access other files because that would require authorization.
They may or may not be able to determine the identity of the current user, depending on a complex set of security restrictions.
This last point is important - getting information about the current user is possible depending on the security policies of the the G Suite domain. A detailed explanation of this can be found in the getActiveUser() method documentation:
If security policies do not allow access to the user's identity, User.getEmail() returns a blank string. The circumstances in which the email address is available vary: for example, the user's email address is not available in any context that allows a script to run without that user's authorization, like a simple onOpen(e) or onEdit(e) trigger, a custom function in Google Sheets, or a web app deployed to "execute as me" (that is, authorized by the developer instead of the user). However, these restrictions generally do not apply if the developer runs the script themselves or belongs to the same G Suite domain as the user.
There are big security issues with getting a list of people that have viewed a file, for good reason, and so what you are looking to do it highly restricted by Google.
References:
Class File of Google Apps Script
getViewers() method of Class File
getEditors() method of Class File
Simple Triggers
onOpen(e) Trigger
Simple Trigger Restrictions
Installable Triggers
Event objects
Class User of Apps Script
User.getEmail() method
Class Session
getActiveUser() method of Session Class

How to get the user property for the "active user" in google apps script custom function

I've published a Google Apps Script standalone spreadsheet add-on, while I met some problem using PropertiesService.getUserProperties() in a custom function.
If User A has installed the add-on and saved some data in the user property.
Then User A shared the spreadsheet to User B. When user B run the custom function, he can get the saved data in user property for user A. This is not what I suppose user Property works. Both User A and B should get their own saved data.
So what is the active user for a shared spreadsheet? I don't want all the spreadsheet viewers to get the saved data for the spreadsheet creator. Is there anything I'm doing wrong in code or "Cloud Platform project" option?
In other words, how can I get different data saved in user properties for different viewers in a shared spreadsheet?
I tried to get the active user email in a custom function, but it does not work.
Please note, I can't use Session.getActiveUser in the custom function, because Google Apps Script Custom function does not support Session service. It will get an invalid permission exception.
https://developers.google.com/apps-script/guides/sheets/functions#Advanced
Thanks,
After writing tons of code to test different scenarios, I believe it has no way to solve the above problem.
So I will use a workaround to achieve the goal. In case someone also run into the trouble. I will put down my test results here.
If Google account A shared spreadsheet to Google account B.
In custom function, they all get A's user property.
From a webpage, call into server function via script.run, both A and B can
get their own user property.
Custom functions can't access PropertiesServices.userProperties() (maybe the exception is the spreadsheet owner).
According to https://developers.google.com/apps-script/guides/sheets/functions
Unlike most other types of Apps Scripts, custom functions never ask users to authorize access to personal data. Consequently, they can only call services that do not have access to personal data, specifically the following:
While Properties is included on the list and there isn't any note for this service, since the custom function doesn't ask users to authorize to access personal data it should not return PropertiesServices.userProperties() as it potentially store user personal data.

POST request from Google Sheets to Norbert API

I have create automations with Zapier that get prospect informations and write it in new rows in a spreadsheet.
This new sheet is composed by :
column A : name
Column B: domain
I want to call an API that gets email : "VoilĂ  Norbert" , and returns the email (or the error) into the Column C.
The Norbert API works as follow:
Make a POST request to https://www.voilanorbert.com/api/v1/
With three parameters : name, domain and token
It return JSON format with the email or an error
I have installed the importJSON code gist.github.com/chrislkeller/5719258 .
I have tried to use the Zapier WebHook, it works, but I can't write the result in my spreadsheet.
I have tried to use this script https://gist.github.com/mhawksey/1276293 in the google script, but it does not work because I don't know where to put the API URL that is need to be called.
Do you know how to call a POST API with parameters in google spreadsheet that search the parameters into the spreadsheet, and that put the JSON result into the spreadsheet
I'm not a developper (sadly). I think it could be useful for everybody that need to enrich their data into google spreadsheet using API call with parameters.
You have an Apps Script code bound to your spreadsheet. gs code runs on Google's Servers. In order to communicate with the Norbert API (Or any API), you must use the UrlFetchApp class.
https://developers.google.com/apps-script/reference/url-fetch/url-fetch-app
And in particular, the fetch() method:
https://developers.google.com/apps-script/reference/url-fetch/url-fetch-app#fetch(String,Object)