I have a google spreadsheet which will be used for collaboration and I was able to create a UI interface which will fetch and update data from a table to make it easier for users.
For the work I need to restrict users to only be able to update rows if they are assigned to them and I am able to do it. But along with that, I also need to allow administrator to assign or update rows which are not assigned to them.
I have a table with all employee's email address and an admin flag for those who are admin.
Name____________Email________________Is Admin
Employee 1_______emp1#domain.com_____Admin
Employee 2_______emp2#domain.com_____
Employee 3_______emp3#domain.com_____
Employee 4_______emp4#domain.com_____Admin
Employee 5_______emp5#domain.com_____
Employee 6_______emp6#domain.com_____
How can I write a something in my script that will allow me to if the user who is triggering a function has admin right or not.
I user Session.getActiveUser().getEmail() to pull out the users email address. I am creating the tool to be used within google apps domain.
Code that checks if the user is the owner of the row, this part works fine but what I want to do is if a user is admin they basically will skip this check.
if (s.getRange("E4").getValue() != usr()){
msg("Once a Task is assigned to an employee, only assigned employee can make any changes to the Task. Thank you");
return;
}
s = sheet
usr() = function calling to check active user email
If I can do something like countifs where I can check count based on the email address and Admin criteria and if its >= 1 proceed if its 0 show error that you can not make changes.
Please let me know.
Really appreciate the help.
Thank you.
Zooooon
Are you looking for something like this?
function myFunction() {
var s = SpreadsheetApp.getActiveSheet();
var usr = Session.getActiveUser().getEmail();
var emails = s.getRange("E2:F").getValues();
for (var i=0;i<emails.length;i++) {
if (emails[i][0] === usr){
if (emails[i][1] === "Admin") {
//Do something when Admin
return;
} else {
//Do something when not admin
return;
}
} else {
//Do something when email not in the list
}
}
}
I am assuming your data is in the range "D:F"
Related
So I've got a spreadsheet that lists work to be done via an imported range from another file. Users have a dropdown of validated data that when they select the status of this work it searches the other sheet for the work they've selected and updates the status of this work. It's super simple, and works for everyone I've given editing privileges to.
I'd like alter it to also log the email of the user who edited the work status and therefore ran the script (we are all part of the same workspace domain). I've gotten it to pull my email and place it where required with repetition, but I cannot get it to access anyone else's. I tried deploying it, although I'm not entirely sure I understand how that works. I've looked into authorizing it, but the only place I can find to alter authorization is via the appscript.json in the editor, but that isn't showing the permissions that the documentation says to edit/add so I'm a little lost as to how to authorize this.
Not sure if it matters, but this script is attached to the sheet it picks up the edit from. I don't know if that means the sheet permissions need to change or what.
Here is the entirety of the code, minus identifying URL's/ID's:
function onEdit(e) {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet(); //shortens calling to the current sheet
var dataSheet = SpreadsheetApp.openById("datafileID").getSheetByName("Data"); //shortens calling to the data file
const status = e.value; //validated user input
var erange = e.range; //range of edited cell
var ecolumn = erange.getColumn(); //range column of edited cell
var erow = erange.getRow(); //range row of edited cell
var snRow = erow; //identifies what row to look for the store number
var snColumn = ecolumn-2; //identifies what column to look for the store number
var sn = sheet.getRange(snRow, snColumn).getValue(); //declares the store number as variable
var user = e.user; //declares user as variable
if (!e.range.isBlank()) { //searches data sheet for store and updates status and user
var column = dataSheet.getRange("G:G").getValues();
var uRow;
for (var i = 0; i < column.length; i++){
if (column[i][0] === sn) {
uRow = i+1;
break;
}
}
dataSheet.getRange(uRow,6).setValue(status)
dataSheet.getRange(uRow,5).setValue(user)
}
sheet.getActiveCell().clearContent();
}
onEdit is a reserved name for simple triggers, you should not use call this function from an edit / change installable trigger because there will be two executions running in parallel.
When using an simple or installable trigger with Google Workspace accounts from the same domain, e.user should return the User object representing de active user.
As the script is working for your account there is no need of additional permissions.
As the script is not working, try the following:
Delete the installable trigger
Change the name of the function (i.e. respondToEdit)
Create the installable trigger again pointing to the new function name.
Double check that the spreadsheet sharing permissions are set to editors from your Google Workspace domain only.
References
https://developers.google.com/apps-script/guides/triggers/events#edit
New user here and not versed in code much. Im working on a COVID-19 form for our company and looking for some help with google script/trigger where when an employee fills out the google form and selects yes/no on the google form the google sheet that collects the data will send off an email based on the value in the cell.
IE: employee A enters "no" to agreeing to comply to policy it will email the manager informing them that someone entered "no".
I have a test formula that is working but when I set up a min by min trigger for it to kick off it just continues to kick off. Im assuming this is obviously due to it not having a code to only send new entries??
Any help would be greatly appreciated.
To reiterate im trying add a script that sends an email only ONCE per user when someone fills out the google form and they choose the wrong answer.
Code I have now:
function onEdit() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet1");
var currentValue = sheet.getRange("F2:F1000").getValue();
if (currentValue = ("Yes")) {
MailApp.sendEmail("test#example.com", "ALERT: Please see person in question!", "The message body that you want to send.");
}
}
Try this:
You haven't identified the person in question.
function onMyEdit(e) {
const sheet=e.range.getSheet();
if(sheet.getName()=='Sheet1') && e.range.columnStart==6 && e.range.rowStart>1 && e.value=='No') {
//MailApp.sendEmail("test#example.com", "ALERT: Please see person in question!", "The message body that you want to send.");
Logger.log("ALERT: Please see person in question!");
}
}
Since this is sending an email which requires authorization you will have to create an installable trigger using the Edit/Current Project Triggers menu.
I wrote a google apps script which fetches the G Suite (google apps) users from the AdminDirectory API
As on output, i get the domain name in front of every user (used replace to extract domain name from each user email id).
what i want to do-:
1. Count the number of users on each domain in one column, so end result should look like this-:
Column - I (exaxple)
domainA.com = 120 users
domainB.com = 28 users
etc....
Any help is appreciated.
I think there is probably a way to shorten this code, but something like this will work. You will have to figure out how to read the correct columns in and output to the correct columns, but hopefully, this will help out:
var emails = [
'someone#testA.com',
'someone#testB.com',
'someone#testA.com',
'someoneelse#testA.com'
];
function countDomains() {
var domainCounts = {};
var domains = emails.map(function(domain) {return domain.split('#')[1];});
domains.forEach(function(each) {
if(domainCounts.hasOwnProperty(each)) {
domainCounts[each]++;
} else {
domainCounts[each] = 1;
}
});
Logger.log(domainCounts);
}
I seek an approach by which I can provide user a bespoke Google Sheet dashboard on the basis of some ID that is entered or transferred via URL.
To explain: as of now, raw data sits in a master Google Sheet and is processed and summarised in another Google Sheet dashboard that requires to enter an ID which acts as filter to the raw data so that the summary only presents insights associated with that particular ID and user - that works.
However, Each user should enter only their ID and see their summary. Right now all users have access to the same public Sheet and the possibility of parallel access is problematic.
How may I generate individual Sheets (one per user) that is based on a template?
Is this possible with default functionality, or Apps Script? Any advice is highly appreciated, thank you!
This is one option you can try, you can get the email ID of the user who opens the google spreadsheet like so:
function onOpen(e) {
var email = Session.getEffectiveUser().getEmail()
var ui = SpreadsheetApp.getUi()
ui.alert(email)
//doSomethingSpecificBasedOnEmail(email) call function that fliters data based on email ID
}
Note: There are few nuances to using Session.getEffectiveUser(). Based on permission and security setting, it can give you a blank user/email.
https://developers.google.com/apps-script/reference/base/session#getActiveUser()
Second Option:
If email ID is not an option and since you are ok with users entering an ID to access the data. This code will ask for an ID and create a copy of sheet called template and also set the value of A1 as the ID. The sheet can then use the ID to get ID specific data and make plots.
function onOpen(){
var ui = SpreadsheetApp.getUi();
var response = ui.prompt('Get ID:');
// Process the user's response.
if (response.getSelectedButton() == ui.Button.OK) {
var id = response.getResponseText();
var ss = SpreadsheetApp.getActive()
var lookupSheet = ss.getSheetByName(id)
if(lookupSheet == null){
var template = ss.getSheetByName("Template")
var newSheet = template.copyTo(ss)
newSheet.setName(id)
newSheet.getRange(1,1).setValue(id)
newSheet.activate()
} else
{
lookupSheet.activate
}
} else {
Logger.log('The user clicked the close button in the dialog\'s title bar.');
}
}
An example of this can be found here: https://docs.google.com/spreadsheets/d/1RPHUGKi7u9jJVc-3xCaYlrZ8kaHWvpl6gPZxUL1g32Y/edit?usp=sharing
Note: People can see each others sheet though, which I assume based on your post is not an issue. However, if that is not the case the best option is to use google Web App script.
Good Evening! I'm Aaron Ayres, an 8th grade mathematics teacher at Noblesville West Middle School in Noblesville, Indiana. Recently for a school-wide incentive my school is using Google Drive to share a "pass" that grants nominated students access to rewards and other treats during the month they are nominated. We typically have about 80 students who are nominated on a monthly basis for their hard work - each educator in the building nominates one student each month based on multiple criteria.
Instead of having to manually go through my folder and un-share the individual passes at the end of the month, I have been researching for a more efficient method of allowing the passes to expire. I came across Amit Argawal's Auto-expire script (http://www.labnol.org/internet/auto-expire-google-drive-links/27509/) and I think it could potentially work but it only expires one file at a time. Is there a way I can modify the script (or create a new script) to reference multiple, sharable links in the script editor so the sharing access to each individual students' pass expires at the end of the month? In other words, is there a way for the script to expire all 80+ passes at the same date and time? I'm a novice to Google Scripts so I'm wondering if I am not formatting my list or URL references correctly so the script recognizes multiple files, or perhaps I could revise the script to recognize an array of links instead of a single variable url link.
Thanks in advance for the assistance!
I hope you have the full script at your hand.Please give the URLs in a list, separated with commas. Are the passwords different for each student? Otherwise you could have just added the URL of the folder without changing the original script at all.
However, Please try changing these portions of the script:
// Enter the full list of URLs(separated with comma) of the public Google Drive file or folder
var URL_LS = ["https://drive.google.com/open?id=0B_NmiOlCM-VTcFp6U1hydTM2MzVCY3AzMUpuTEtVWUhXRXNz", "https://drive.google.com/file/d/0B_NmiOlCM-VTNXFqOU1jTG5JdHJVQ3ZGUGNqZklJNWludllr/view?usp=sharing"] ;
var URL_LN = URL_LS.length;
// Enter the expiry date in YYYY-MM-DD HH:MM format
var EXPIRY_TIME = "2016-02-18 09:46";
And again,replace the autoExpire() as follows:
function autoExpire() {
var id, asset, i, email, users;
try {
for (var j = 0; j < URL_LN; j++) {
var URL = URL_LS[j];
var id = URL.match(/[-\w]{25,}/g);
if (id) {
id = id[id.length-1];
asset = DriveApp.getFileById(id) ? DriveApp.getFileById(id) : DriveApp.getFolderById(id);
if (asset) {
asset.setSharing(DriveApp.Access.ANYONE, DriveApp.Permission.NONE);
asset.setSharing(DriveApp.Access.ANYONE_WITH_LINK, DriveApp.Permission.NONE);
users = asset.getEditors();
for (i in users) {
email = users[i].getEmail();
if (email !== "") {
asset.removeEditor(email);
}
}
users = asset.getViewers();
for (i in users) {
email = users[i].getEmail();
if (email !== "") {
asset.removeViewer(email);
}
}
}
}
}
} catch (e) {
Logger.log(e.toString());
}
}