how to pass current user's email address to Google Script - email

I have a script behind a Google spreadsheet that sends an email once certain cells of a row is completed. The script works by sending to multiple hard coded email addresses. How can I add the current user's email address as a 2nd CC? One of the CC is hard coded but the 2nd changes depending on the person updating the spreadsheet. I know how to grab the email address but how do I pass it as a variable so it actually gets CC-ed?
var currentemail = Session.getActiveUser().getEmail();
var options = {cc: 'Session.getActiveUser().getEmail(), someotheremail#domain.com'};
or
var options = {cc: 'currentemail, someotheremail#domain.com'};
GmailApp.sendEmail(email, subject, body, options);
Obviously these do not work :)
Many thanks in advance

this can be done like below :
function sendWithCc(){
var currentemail = Session.getActiveUser().getEmail();
var options = {};// create object
options['cc'] = currentemail+',someotheremail#domain.com';// add key & values (comma separated in a string)
GmailApp.sendEmail('somemail#domain.com', 'subject', 'body', options);
// I stringified 'subject' and 'body' to make that test work without defining values for it
}

Your examples should be modified as follows:
var options = {cc: Session.getActiveUser().getEmail()+', someotheremail#domain.com'};
Or
var options = {cc: currentemail+', someotheremail#domain.com'};
You cannot call a function, or reference a variable, from within a string. Instead, use the + operator to join the value of your variable (or the return value of your function call) with the string.
Note, depending on the context in which this code will be used, the script may not have permission to access the users identity regardless. See the notes under GetActiveUser() here: https://developers.google.com/apps-script/reference/base/session#getActiveUser()

Related

How to send a conditional email based on the value of a cell from a form response?

I have a formula that calculates a number based on the response from a google form. Depending on what this number I want to send an email using details from the from as well as a pre typed email in another cell.
In Col1 is a time stamp, in col14 is an employee start date. My formula in Col33 works out how many days they have been employed at the time of submitting the form.
I want to send an email to the person if the number of days is less than 182.
I have an email pre typed out and can place this anywhere. At the moment I have it in all cells in col36. The email address will be in column32.
I have tried a number of different codes and none of them are sending the email no matter what the trigger I have set up is. I have very basic knowledge on apps script so my current code might be completely wrong, but it should show roughly what I'm getting at.
function sendEmail() {
var values = SpreadsheetApp.getActiveSheet().getDataRange().getValues()
for (i in values.length) {
var data = values[i][33];
var emailAddress = values[i][32];
var message = values[i][36];
if (data < 182); {
MailApp.sendEmail(emailAddress, "Flexible Working Request", message);
}
}
}
The current results have just been deleting the data in col33, Col34 & Col36 on the new form response row only.
Sorry if this question has been answered elsewhere, any other answer I found to similar issues I could not get to work.
I got someone who is much better at google apps script at work to give me a hand
It is to do with google forms pushing down formulas to the side
So we had to move the formula calculating the number of days to another sheet and then used this formula which worked
function sendEmailv2() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Form responses
1');
var scrip = Session.getScriptTimeZone();
var date = sheet.getRange(sheet.getLastRow(),14).getValue();
var sub = sheet.getRange(sheet.getLastRow(),1).getValue();
Logger.log(date);
var fortmat = Utilities.formatDate(new Date(date), scrip, "dd/MM/yyyy");
var Subfortmat = Utilities.formatDate(new Date(sub), scrip, "dd/MM/yyyy");
var emailAddress = sheet.getRange(sheet.getLastRow(),32).getValue();
var sheet2 = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Sheet4');
var message = sheet2.getRange(1,1).getValue();
var days = sheet2.getRange(sheet2.getLastRow(),2).getValue();
if (days<182){
MailApp.sendEmail(emailAddress, "Flexible Working Request", message,{noReply:true});
}
}
Thanks!
You don’t need to go over all the columns to get a single cell value, so there is no need for a for loop. You can do it directly with:
var sheet = SpreadsheetApp.getActiveSheet().getSheets[0];
var cell = ["A33"];
var days_value = sheet.getRange(cell).getValue();
Then you can just make an if condition to send the email:
if (days_value < 182){
MailApp.sendEmail(emailAddress, "Flexible Working Request", message);
}
Hope this helps

Name email attachment in Google Apps Script

I have the following G.A.S script to email a google sheet as a pdf attachment.
var spreadsheet = SpreadsheetApp.getActive();
var subject = spreadsheet.getRange("U1:U1").getValues();
var emailTo = spreadsheet.getRange("V1:V1").getValues();
var message = spreadsheet.getRange("W1:W1").getValues();
var pdf = DriveApp.getFileById(spreadsheet.getId()).getAs('application/pdf').getBytes();
var attach = {fileName:subject,content:pdf, mimeType:'application/pdf'};
MailApp.sendEmail(emailTo, subject, message, {attachments:[attach]});
The above code works well except that the file attached to the email message has a bizarre name like "[Ljava.lang.Object_#4e63998c" with no ".pdf" extension!
I am looking for a way to set a name for the pdf file before being attached to the email. The file name should equal the "subject" variable.
Thanks in advance.
Omid
Values retrieved by getValues() is 2 dimensional array. I think that the filename becomes such string because the array is used as the filename. Please retrieve the element from the array and try again. So could you please modify as follows?
From :
var attach = {fileName:subject,content:pdf, mimeType:'application/pdf'};
To :
var attach = {fileName:subject[0][0],content:pdf, mimeType:'application/pdf'};
You can also use the following modification. In this case, getValue() can retrieve the value as a string from the cell "U1".
From :
var subject = spreadsheet.getRange("U1:U1").getValues();
To :
var subject = spreadsheet.getRange("U1:U1").getValue();
Reference :
getValue()
getValues()
If this was not what you want, please tell me. I would like to think of other solutions.
I'm a bit late, but another way to solve this problem might be:
var spreadsheet = SpreadsheetApp.getActive();
var subject = spreadsheet.getRange("U1:U1").getValues();
var emailTo = spreadsheet.getRange("V1:V1").getValues();
var message = spreadsheet.getRange("W1:W1").getValues();
var pdf = DriveApp.getFileById(spreadsheet.getId())
.getAs('application/pdf')
.getBlob()
.setName(subject);
MailApp.sendEmail(emailTo, subject, message, {attachments:[pdf]});
The Blob class has a setName method https://developers.google.com/apps-script/reference/base/blob#setName(String), that can be chained into a Blob object (which is the result of getBlob())
After that you just need to add the Blob object inside attachments array of function MailApp.sendEmail

Generate and send pdf through Google Forms to my email address - doesn't send, debugging to no assitance

I'm trying to send myself a form-based report as a pdf. The problem is, I don't receive any emails. Debugging doesn't help much, since that only tells me which values are "undefined" (they are being defined the instant one fills out the form and triggers the email by clicking send; in theory). My coding experience stems from the days of TurboPascal and .bat-files, and I have lately realised I need to shape up. Trying to figure out Android, and this is a little experiment at work. But I had forgotten the lost feeling of "what now?"...
Here's the code:
// Samfunnsutvikling kursrapport
var docTemplate = "TemplateIDinGoogleDoks";
var docName = "Kursrapport";
// When Form Gets submitted
function onFormSubmit(e) {
//Get information from form and set as variables
var email = "worker#work.no";
var namn = e.namedvalues.namn;
var arrangement = e.namedvalues.arrangement;
var dato = e.namedvalues.dato;
var referat = e.namedvalues.referat;
// Get document template, copy it as a new temp doc, and save the Doc’s id
var copyId = DocsList.getFileById(docTemplate)
.makeCopy(docName+' for '+namn)
.getId();
// Open the temporary document
var copyDoc = DocumentApp.openById(copyId);
// Get the document’s body section
var copyBody = copyDoc.getActiveSection();
// Replace place holder keys,in our google doc template
copyBody.replaceText('keynamn', namn);
copyBody.replaceText('keyarrangement', arrangement);
copyBody.replaceText('keydato', dato);
copyBody.replaceText('keyreferat', referat);
// Save and close the temporary document
copyDoc.saveAndClose();
// Convert temporary document to PDF
var pdf = DocsList.getFileById(copyId).getAs("application/pdf");
// Attach PDF and send the email
var subject = "Kursrapport";
var body = "Kursrapporten frå " + namn + "";
GmailApp.sendEmail(email, subject, body, {htmlBody: body, attachments: pdf});
// Delete temp file
DocsList.getFileById(copyId).setTrashed(true);
}
The script/document is authorized to send emails, but, oddly, I had to authorize it twice. It is saved.
In general, you can add Logger.log() to print variable values or just messages to see how far does it reach.
It looks as attachments parameter expects Blob[] type, however you are passing just Blob. So, it should be:
GmailApp.sendEmail(email, subject, body, {htmlBody: body, attachments: [pdf]});
You may also want to replace DocsList with DriveApp class as-is since the first one is depricated.
Update
It turned out also that getActiveSection() was renamed to getBody().

Manipulate google form associated with a google sheet from app script in that sheet

I have a google spreadsheet which contains multiple sheets (or tabs) within it. Each sheet is populated from its own unique form. None of the forms are embedded in the spreadsheet.
Periodically, I need to delete all the data in the sheets, and also delete all the old responses which are saved in each of the forms. I can do this using a .gs script which resides in the spreadsheet. It accesses the form by its ID (the long string which appears in its URI). This requires the ID string to be hardcoded in my .gs script.
Ideally, I would like to access each form from the sheet object (i.e. the destination for each forms entries). Mock up code would look like this...
var ss = SpreadSheedApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var form = sheet.getMyAssociatedSourceForm(); // my dream method :-)
form.deleteAllResponses() // this method already exists
Does anyone know if this is possible? Or will I have to continue to use the ID (which is currently working)?
rgds...
I think you can do this without literally typing in ID's into your script. But, you would need to get every Form in your drive, loop through them all and get the destinationId() of every Form.
Google Documentation
Then compare the destinationId with the current spreadsheets ID, which you can get without needing to "hard code" it:
function deleteAllResponses() {
var thisSS_ID = SpreadsheetApp.getActiveSpreadsheet().getId();
var allForms = DriveApp.getFilesByType(MimeType.GOOGLE_FORMS);
var thisFormFile, thisFormFileID = "", thisForm, theDestID = "";
while (allForms.hasNext()) {
thisFormFile = allForms.next();
thisFormFileID = thisFormFile.getId();
thisForm = FormApp.openById(thisFormFileID);
try {
theDestID = thisForm.getDestinationId();
} catch(err) {
continue;
};
if (theDestID === "" || theDestID === undefined) {
continue;
};
if (theDestID === thisFormFileID) {
thisForm.deleteAllResponses();
};
};
};
I have not tested this, so don't know if it works. If it does, let me know in the comments section.

Getting a Google Form Script generated email to pipe data into Reponse Sheet

I am currently trying to setup an approval workflow. I'm fairly junior when it comes to some of this stuff. But so far have it working at respectable level to fit our needs with the assistance of an example.
I was using the template/example from Email Approval using Google Script and a Form.
The issue I am running into, with a lack of functionality is that at the time of Accept or Deny via the Email that is generated for approval I would like it to then record that data back into the Google Form row in the last column that the email was generated from.
I may end up adding 2nd timestamp, reply email etc later.
So then that row would show the initial form filled out and then either blank/accepted/deny as the status.
Thank you for any time or assistance.
The approval workflow that James Ferreira originally wrote was intentionally very basic. Enhancing it to provide correlation between approvals and the original requests is simple in concept, yet complicates the code because of details and limitations.
Things that need to considered:
Form responses include a timestamp, which we can use as a sort of "serial number" for responses, since it has a very high probability of being unique in an application like this.
We can pass this identifier along with the rest of the URL embedded in the approval email, which will give it back as a parameter to the webapp, in turn.
Passing an object like a timestamp between applications can be troublesome. To ensure that the URL embedded in the approval email works, we need to encode the string representation of the timestamp using encodeURIComponent(), then decode it when the webapp consumes it.
Searching for matches is simplified by use of ArrayLib.indexOf() from Romain Vaillard's 2D Array library. This function converts all array data to strings for comparisons, so it fits nicely with our timestamp.
Alternatively, we could put effort into creating some other identifier that would be "guaranteed" to be unique.
The approval-response web app (doGet()) does not understand what "activeSpreadsheet" means, even though it is a script contained within a spreadsheet. This means that we need a way to open the spreadsheet and record the approval result. To keep this example simple, I've assumed that we'll use a constant, and update the code for every deployment. (Ick!).
So here's the Better Expense Approval Workflow script.
// Utilizes 2D Array Library, https://sites.google.com/site/scriptsexamples/custom-methods/2d-arrays-library
// MOHgh9lncF2UxY-NXF58v3eVJ5jnXUK_T
function sendEmail(e) {
// Response columns: Timestamp Requester Email Item Cost
var email = e.namedValues["Requester Email"];
var item = e.namedValues["Item"];
var cost = e.namedValues["Cost"];
var timestamp = e.namedValues["Timestamp"];
var url = ScriptApp.getService().getUrl();
// Enhancement: include timestamp to coordinate response
var options = '?approval=%APPROVE%&timestamp=%TIMESTAMP%&reply=%EMAIL%'
.replace("%TIMESTAMP%",encodeURIComponent(e.namedValues["Timestamp"]))
.replace("%EMAIL%",e.namedValues["Requester Email"])
var approve = url+options.replace("%APPROVE%","Approved");
var reject = url+options.replace("%APPROVE%","Rejected");
var html = "<body>"+
"<h2>Please review</h2><br />"+
"Request from: " + email + "<br />"+
"For: "+item +", at a cost of: $" + cost + "<br /><br />"+
"Approve<br />"+
"Reject<br />"+
"</body>";
MailApp.sendEmail(Session.getEffectiveUser().getEmail(),
"Approval Request",
"Requires html",
{htmlBody: html});
}
function doGet(e){
var answer = (e.parameter.approval === 'Approved') ? 'Buy it!' : 'Not this time, Keep saving';
var timestamp = e.parameter.timestamp;
MailApp.sendEmail(e.parameter.reply, "Purchase Request",
"Your manager said: "+ answer);
// Enhancement: store approval with request
var sheet = SpreadsheetApp.openById(###Sheet-Id###).getSheetByName("Form Responses");
var data = sheet.getDataRange().getValues();
var headers = data[0];
var approvalCol = headers.indexOf("Approval") + 1;
if (0 === approvalCol) throw new Error ("Must add Approval column.");
// Record approval or rejection in spreadsheet
var row = ArrayLib.indexOf(data, 0, timestamp);
if (row < 0) throw new Error ("Request not available."); // Throw error if request was not found
sheet.getRange(row+1, approvalCol).setValue(e.parameter.approval);
// Display response to approver
var app = UiApp.createApplication();
app.add(app.createHTML('<h2>An email was sent to '+ e.parameter.reply + ' saying: '+ answer + '</h2>'))
return app
}
So, I tried this, but there an issue with the formatting for date when it's in the data array. In order to get this to work, you have to reformat the time stamp in the doGet using formatDate.
I used the following to get it to match the formatting that appears in the array.
var newDate = Utilities.formatDate(new Date(timestamp) , "PST", "EEE MMM d yyyy HH:mm:ss 'GMT'Z '(PST)'");
Lastly, of course update the indexof parameter that is passed to newDate.