Removing Edit Access from a Sheet using email from a cell - javascript

I am trying to figure out how to remove someone from a spreadsheet using google app scripts.
Essentially, I have a central spreadsheet with information such as emails, names, UID's etc on it. I am trying to pull the email from this spreadsheet and use the removeEditor function to remove that email from another spreadsheet. You can view the code below.
var officerIDrow = officerID + 1;
var Tracker = SpreadsheetApp.getActive().getSheetByName('P_Tracker'); //the button is on the same sheet as this, this is why it is get active.
var PTBooking = SpreadsheetApp.openById("1JPS69ko99dQTEwjplF_l2l2G_T8RyHjxCyMxXd_AV_s"); //Referring to the other sheet where the email will be removed from editors.
var EmailAddressRange = "F" + officerIDrow; //This is the column where the emails are stored. The officer ID row refers to the user inputted value in a dialog. Don't worry about this, I have already checked to see if this is the issue,
var EmailAddress1 = Tracker.getRange(EmailAddressRange);
var EmailAddress2 = EmailAddress1.getValue();
var EmailAddress3 = Utilities.formatString(EmailAddress2); //In my desperation, I was trying to see if setting it as string would help.
PTBooking.removeEditor(EmailAddress3);
This isn't the full version of the code. If you'd like to see it, you can click here. But all that matters is above, everything else works fine.
The code above runs fine until it hits the last line where it tries to remove the email. The error message that appears says: "Invalid email: ". I'm assuming after the "email:" bit, it should display what has been pulled. But it doesn't! I have no idea why it isn't finding and using the email to remove people.
Can anyone spot any issues?
Thanks,
Shaun.

This basic test worked for me. It could read email address from the spreadsheet then remove editors from the external sheet. I tried to copy your example, but I don't know how the officerIDrow works, but I assume it's a number. So just stored a number as a var
function myTest() {
var ss = SpreadsheetApp.openById("ID HERE");
var idRow = 11;
var tracker = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("tracker");
var emailCell = "F"+idRow;
Logger.log(emailCell);
var emailAddress = tracker.getRange(emailCell).getValue();
Logger.log(emailAddress);
ss.removeEditor(emailAddress);
var editors = ss.getEditors();
Logger.log(editors);
}
I've left the Logger bits in as it will help point you at what script is doing at each point.
The email address in the cell must be plain, such as google#google.com

Related

Processing lines and filling fields

I read and search and study, but can't seem to write any JS out of my own head - this should be really simple but it will not work. I keep getting an error about an undefined variable "madlib7.html:411 Uncaught ReferenceError: populatefields is not defined at HTMLButtonElement.onclick"
I start with some urls that I paste into a textarea, then I click a button and first it splits the text into individual lines and stores them in variables. Next, I want to split each line by spaces and populate fields in an HTML form with select words from the resulting array via the use of innerhtml.
I know there is some way of looping through the processes, but I have not figured out how to do that yet so for now I am writing it all out the long way. I have not been able to figure out how to address the error message 'ReferenceError' from above.
Thanks for any and all help
Paul
populatefields(day1, location1, streamid1) {
document.getElementById('PanLinks').value.split('\n');
var streamInfoLine1 = resultArr[0];
var streamInfoLine2 = resultArr[1];
var streamInfoLine3 = resultArr[2];
var streamInfoLine1 = resultArr[3];
var streamInfoLine2 = resultArr[4];
var streamInfoLine3 = resultArr[5];
var streamInfoLine1 = resultArr[6];
var streamInfoLine2 = resultArr[7];
var streamInfoLine3 = resultArr[8];
streamInfoLine1.split(' ');
var day1 = resultArr[0];
var location1 = resultArr[3];
var streamID1 = resultArr[4];
document.getElementById("location1").innerHTML= location1;
document.getElementById("time1").innerHTML= day1;
document.getElementById("streamid1").innerHTML= streamID1;
}
could you use stackoverflow built in code sandbox to include all your code in html, javascript code? it seems like the issue is on your html file madlib7.html, where your onclick listener isn't defined on the button. nor did I see anything from your code that indicates any event listener has been setup to perform that button task. so it's hard to help debug what exactly it is.

is it possible? onChange from one spreadsheet triggers onChange from another spreadsheet

I have a sheet that when the onchange triggers it makes a mirror of the information to use as a reference later when it determine which rows changed. I had this connected to a Query function. Whenever the query got updated, the onChange function would run. But sometimes the query would act weird and information would appear blank on the sheet it copies to even though i can see it on the query. And if two computers were looking at the query at the same time, it was evident that it didn't update on all screens. So i decided, why not, instead of a query, we have the information get updated the same way the mirror is updated. So it copies all the information down and puts it onto the sheet, no query needed. I figured this would at least make sure everyone is seeing the same information. So i made a query sheet, and added an onChange() trigger to it that grabbed all the info and pasted it onto the main sheet, whenever the query updated. (even if it messes up, at least it's much more obvious and no one is seeing anything different). But when the information was posted onto the main spreadsheet. THAT spreadsheet's onChange function didn't trigger. I thought it would trigger whenever there was a change. No matter what. So I then decided to create a new function in the Query Sheet where it inserts and deletes the last row, even say hi, thinking if I make the sheet change more prominently, the onChange() function would trigger. Still didn't. I'm at a loss.
function onChangeMirror() {
var sos = SpreadsheetApp.openById("the sheet with the query");
var sas = SpreadsheetApp.setActiveSpreadsheet(sos);
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s1 = ss.getActiveSheet();
var lastRow = s1.getLastRow();
var lastRow1 = s1.getLastRow()+1;
var lastRow10 = s1.getLastRow() +10;
var SRange = s1.getRange(2,1,lastRow,2);
var A1Range = SRange.getA1Notation();
var SData = SRange.getValues();
var sos2 = SpreadsheetApp.openById("the sheet it's updating");
var sas2 = SpreadsheetApp.setActiveSpreadsheet(sos2);
var ss2 = SpreadsheetApp.getActiveSpreadsheet();
var s2 = ss2.getActiveSheet();
var MaxRow = s2.getMaxRows();
s2.getRange(A1Range).setValues(SData);
Logger.log(lastRow1)
Logger.log(lastRow10)
s2.getRange('A'+ lastRow1+':'+'B'+lastRow10).setValue(null);
Logger.log(A1Range)
if(MaxRow > '300') {
s2.deleteRow(MaxRow)
}
else if(MaxRow < '301'){
s2.insertRowAfter(MaxRow)
s2.getRange('A'+(MaxRow+1)).setValue('HI')
}
}
here is the script i was using

Send email after new document is created from template that includes URL from new document

I have some script in Sheets that sends an email after a button is pressed letting me know the sheet is newly created. However, the way I have written the script sends me a link to the template, and not the newly created sheet. I want to have the email created include the URL from the new sheet and not the template. I have the script used below (with some information changed for anonymity):
function sendemail() {
MailApp.sendEmail("name#gmail.com", "New Sheet Created",
"The link for the new sheet is
https://docs.google.com/spreadsheets/");
}
Thank you for the help, I plan to check back frequently to answer any questions. If I need to clarify anything, please let me know. Thank you!
I think this answer might be what you are looking for:
https://webapps.stackexchange.com/questions/93305/how-to-find-url-of-the-current-sheet
function getSheetUrl() {
var SS = SpreadsheetApp.getActiveSpreadsheet();
var ss = SS.getActiveSheet();
var url = '';
url += SS.getUrl();
url += '#gid=';
url += ss.getSheetId();
return url;
}

Google Apps Script to Open copy of Google Sheet in new window

I am trying to boost my Google knowledge by getting into scripting, and I have researched high and low for a solution to my situation to no avail.
I have a Google Sheet that is serving as a template. When the original file is opened, I want to launch a dialog to enter a student ID#. This number will pass into a specified cell in the template, which results in some auto-populated cells in the sheet (using spreadsheet functions). Once the cells have been populated, I want to make a copy of the file with a specific naming structure and store it in a specified folder in Google Drive. Lastly, I want that new file to open in a new window for further editing.
So far, I can get the dialog box to pop up for the ID#, I can pass that number to the sheet, and I can make a copy of the template and rename it accordingly.
What I CANNOT do is get the new file to open automatically in a new tab. I also need the new file to not run the "onOpen" script.
Here is what I have so far for each of these endeavors.
The code below creates a dialog box to enter a Student ID and passes it to the sheet to a specified cell:
function BuildUI() {
var app = UiApp.createApplication();
app.setTitle('Make a Copy - Please enter the Student ID# below:');
var panel = app.createVerticalPanel();
var textBox = app.createTextBox();
textBox.setName('stuId').setId('StudentID');
var button = app.createButton('Submit');
panel.add(textBox);
panel.add(button);
var clickHandler = app.createServerClickHandler('responses');
button.addClickHandler(clickHandler);
clickHandler.addCallbackElement(panel);
app.add(panel);
var doc = SpreadsheetApp.getActive();
doc.show(app);
}
function responses(e){
var app = UiApp.getActiveApplication();
var textBoxValue = e.parameter.stuId;
var sheet = SpreadsheetApp.getActiveSheet();
var studentID = sheet.getRange('Y4').setValue(textBoxValue);
var dateToday = sheet.getRange('C5').setValue(new Date());
return app.close();
}
The above code works for what I need it to do. I only include it for reference (and suggestions for cleaning it up ;)
This next code block makes a copy of the file with the new values, renames it, and saves it to a designated folder in Google Drive. Again..this works for me, but I include it for reference and suggestions:
function makeCopy(){
var sheet = SpreadsheetApp.getActiveSpreadsheet();
var firstName = sheet.getRange('O4').getDisplayValue();
var lastName = sheet.getRange('E4').getDisplayValue();
var date = sheet.getRange('C5').getDisplayValue();
var stuId = sheet.getRange('Y4');
var grade = sheet.getRange('AH4').getDisplayValue();
var fileName = (lastName+ ", " +firstName+ " - " +stuId+ " - Grade " +grade+ " - " +date);
var destFolder = DriveApp.getFolderById('folderID');
destFolder.setSharing(DriveApp.Access.DOMAIN_WITH_LINK, DriveApp.Permission.VIEW);
DriveApp.getFileById(sheet.getId()).makeCopy(fileName, destFolder);
}
Lastly, my onOpen function strings this all together (plus one other function) to run as soon as the template is opened:
function onOpen(){
clearCells(); //Clear all content left behind by last editor
BuildUI();
makeCopy();
}
Any help in getting this workflow dialed in is greatly appreciated (most of this I have accomplished already, I just include it for you understanding of my overall needs):
User Interface Dialog Box to capture Student ID (done, but could use suggestions for cleaning up)
Pass ID to cell Y4 and current date to cell C5 (done...just included for understanding of overall need)
Make a copy of the original file and rename it to "Last Name, First Name - StuID - Grade - Date and store in specified Folder in Google Drive (done...just included for understanding of overall need)
NEED -- Open newly created file in a new tab in the browser without running the attached scripts (ideally, the scripts will not be included in the copy if possible)
Bonus points for any help in recreating the UI using the HtmlService in Google scripts since the UI Service is deprecated and functionality may go away the moment I figure all this out.
Thanks in advance for any help on this tall order.
You could capture the google file object in the makeCopy() with
gFile = DriveApp.getFileById(sheet.getId()).makeCopy(fileName, destFolder);
return gFile;
then add this function to open a new sheet:
function openNewSheet(gFile) {
var spreadsheetId = gFile.getId();
var url = "https://docs.google.com/spreadsheets/d/"+spreadsheetId;
//SpreadsheetApp.getUi().alert('url is ' + url);
var html = "<script>window.open('" + url + "');google.script.host.close();</script>";
var userInterface = HtmlService.createHtmlOutput(html);
SpreadsheetApp.getUi().showModalDialog(userInterface, "Open Sheet");
}
Finally you can add openNewSheet() to the end of onOpen()
Some credit goes to this video: https://www.youtube.com/watch?v=2y7Y5hwmPc4

Google Apps Scripts - Extract data from gmail into a spreadsheet

this is the first script i try to write from scratch. It's been no good up to now so i'm going to ask for some help.
Case: I recieve e-commerce confirmation emails from e-commerce sites no reply email address. In the email's body they send email address from buyers. I want to send an automated mail to the body's email address.
How i plan to do this (any suggetions to eliminate steps will be thanked).
Use a rule to tag incoming emails with a unique tag.
Use that tag to identify emails in gmail with a script, go one by one and extract the info i need. Use regex with the emails body content to extract the email address i need to send the automated emails. Plan is to get: subject, date, email from body.
Write all that info to a spreadsheet.
Get rid of unique tag info to prevent duplicate runs.
Then use form mule addon to send emails from the spreadsheet.
So far, i've dealt with steps 1 (easy), and been stuggling with steps 2 and 3 (im not a coder, i can read, undestrand and hack. writing from scratch is a completely different thing). Ive dealt with 4 before i think this is the best way to deal with it.
With the script i extract info to the spreadsheet, with the addon i use the info from the spreadsheet to send emails.
This is the code ive written so far. I've left the regex part for later cause i cant even write anything into the spreadsheet yet. once i get that working, ill start working in the regex and "remove the label" aspects of the script.
function myFunction() {
function getemails() {
var label = GmailApp.getUserLabelByName("Main tag/subtag");
var threads = label.getThreads();
for (var i = 0; i < threads.length; i++) {
var messages=threads[i].getMessages();
for (var j = 0; j < messages.length; j++) {
var message=messages[j];
var subject=message.getSubject();
tosp(message);
}
}
}
function tosp(message){
var body=message.getBody()
var date=message.getDate();
var subject=message.getSubject();
var id= "my spreasheet id";
var ss = SpreadsheetApp.openById(id);
var sheet = ss.getActiveSheet();
sheet.appendRow(subject,date,body);
}
}
Any help would be appreciated.
Thanks
Sebastian
Following is the code I wrote and tested that performs the steps 2, 3 and 4 mentioned by you perfectly well.
function myFunction() {
var ss = SpreadsheetApp.getActiveSheet();
var label = GmailApp.getUserLabelByName("MyLabel");
var threads = label.getThreads();
for (var i=0; i<threads.length; i++)
{
var messages = threads[i].getMessages();
for (var j=0; j<messages.length; j++)
{
var msg = messages[j].getBody();
var sub = messages[j].getSubject();
var dat = messages[j].getDate();
ss.appendRow([msg, sub, dat])
}
threads[i].removeLabel(label);
}
}
One of the faults in your code was that the appendRow function accepts an array of elements specified within [ ] brackets.
Depending on where you're attaching this script, your line of code:
var ss = SpreadsheetApp.openById(id);
is not necessary if the script is being written in the script editor of the Spreadsheet where you want these emails to be logged. However, if there are multiple sheets in that spreadsheet, you can replace my line
var ss = SpreadsheetApp.getActiveSheet();
by
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("Sheet1");
Another suggestion is that the current code will give you messages in HTML format. Hence, if you want to get the message in plain text as you see it, use:
var msg = messages[i].getPlainBody();
Now you can write another function for regex and pass the message msg to that. Hope this helps!
I made a ready-to-use script, explaining how to use it (from the start) as well, for those who need more assistance.
It's on gmail-to-google-sheets-script repository. Just read the content and follow the instructions.
How to use
Create a new Google Sheet
Access menu Tools > Script Editor
Copy the content from gmailt-to-sheets.gs to editor, replacing the sample code there
Replace the value on SEARCH_QUERY to your real query (Do your search on gmail first, copy and paste the search terms there)
Select saveEmails on menu (near "run" and "debug" buttons)
Click on "Run" button
It will ask for authorization at first run, proceed accepting it (it's your Gmail account authorizing your Google Script account)
After run, the results will be applied to you sheet
Changing fields
If you want to save different message attributes, take a look at gmail-message class and change your script file the code below comments with a ✏️ (pencil).

Categories

Resources