Copying cells from one sheet to another with Google Apps Script - email

I am trying to copy specific cells from one sheet to another using a button as a trigger. The same script should also send an email notification to notify someone that the document has been updated.
This is the code I am using but it does not work and it seems incomplete:
function myFunction() { MailApp.sendEmail({ to: "xx#xx.com.au", subject: "xx", htmlBody: " xxx", }
function Copy() {
var sss = SpreadsheetApp.openById('xxxxxxxxx');
var ss = sss.getSheetByName('xxx');
var range = ss.getRange('xx');
var data = range.getValues();
var tss = SpreadsheetApp.openById('xxxx'); //replace with destination ID
var ts = tss.getSheetByName('xxx'); //replace with destination Sheet tab name
}
I need the script to copy the cells and add them to an existing sheet and not overwrite any rows too.

Related

onFormSubmit(e) I need to sum 4 columns and output to a PDF

This seems like a simple problem, add 4 Form Event columns(Cost 1, Cost 2, Cost 3, Cost 4) and output calculated 'Total' to a PDF via email utilizing a template. I have no problem getting the Event(e) data to the template and sent via email but cannot get the total. I've tried many different Google App Scripts from this site to no avail. Currently, I have a separate sheet called 'Total' and created an array that captures the Event data columns and displays exactly what I want but I cannot get it to the template, problem code may be on line 20. I've included links to the template as well as the Spreadsheet and the Google App Script
// Get template from Google Docs and name it
var docTemplate = "1Ti1n71wpA-U5X9yLqSIfLC9VXqcxOGGsZQhYq0ZwJX4"; // *** replace with your template ID ***
var docName = "Calculate the total";
// When Form Gets submitted
function onFormSubmit(e) {
var name = "Rick"
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('Total'); //Get 'Total' sheet
var row = sheet.getLastRow(); //Get 'Total' last row
//Get information from form and set as variables
var todaysDate = Utilities.formatDate(new Date(), "CST", "MM/dd/yyyy, hh:mm");
var email_address = "MyEmail address";
var cost1 = e.values[1];
var cost2 = e.values[2];
var cost3 = e.values[3];
var cost4 = e.values[4];
var total = sheet.getRange(row, [1]).getValue(); //Is this the problem?
// Logger.log(e.namedValues);
// Get document template, copy it as a new temp doc, and save the Documents ID
var copyId = DriveApp.getFileById (docTemplate)
.makeCopy(docName + ' for '+ name)
.getId();
// Open the temporary document
var copyDoc = DocumentApp.openById(copyId);
// Get the documents body section
var copyBody = copyDoc.getActiveSection();
// Replace place holder keys,in our google doc template
copyBody.replaceText('<<name>>', name);
copyBody.replaceText('<<cost1>>', cost1);
copyBody.replaceText('<<cost2>>', cost2);
copyBody.replaceText('<<cost3>>', cost3);
copyBody.replaceText('<<cost4>>', cost4);
copyBody.replaceText('<<total>>', total);
copyBody.replaceText('<<timeStamp>>', todaysDate);
// Save and close the temporary document
copyDoc.saveAndClose();
// Convert temporary document to PDF by using the getAs blob conversion
var pdf = DriveApp.getFileById(copyId).getAs("application/pdf");
// Attach PDF and send the email
var subject = "Your Total Cost Project Script";
var body = name + ", here is the total cost for your project ";
MailApp.sendEmail(email_address, subject, body, {htmlBody: body, attachments: pdf});
// Delete temp file
DriveApp.getFileById(copyId).setTrashed(true);
}
Spreadsheet - https://docs.google.com/spreadsheets/d/144t33X98eZIAH2k5hCA--fFeUzmJCGefKI7lC1EE4Xc/edit?usp=sharing
Template - https://docs.google.com/document/d/1Ti1n71wpA-U5X9yLqSIfLC9VXqcxOGGsZQhYq0ZwJX4/edit?usp=sharing

Script for Google sheets (auto email function)

Google Sheets Script
I need to generate an auto email reply when Column "A" is marked "Completed". The email address to send this to is in Column "I" and subject of the email needs to be data in Column "H" while the body of the email will be generic for all emails sent. This is all specific to each Row.
I have multiple scripts running, for hiding rows etc, but nothing this complex.
All data is sent in to spreadsheet from Google Forms, and will need to encompass all rows
Any help would be much appreciated.
I created a script for something similar to this, except it runs off of check boxes. You could easily edit this code to have the email recipient variable to point to a value in a column by adding a .getdisplayvalue
How I used it is basically just as a script trigger, so I wouldn't have it replace the "progress" column you have, but to add a column for them to check when they're done editing the row.
Side Note: This script purposefully sets the check box back to default after clicking "yes I want to send the email" on the alert, otherwise the script would continuously run.
Without seeing your Google Sheet or current code/this code inserted, I wouldn't be able to help you implement at all. Let me know if this helps.
/*
A function to:
* After clicking a checkbox, auto prompt a yes/no box
* Upon "yes", copies that row from the source sheet to a destination sheet
* send an e-mail based on that new row's data
I reccomend protecting the response sheet and hiding it, as well as protecting the check box column to give edit access to only those you want to be able to send e-mails.
NOTES:
*It is important that the headers on your source sheet match your destination sheet.
* You have to run the script from the editor first to accept permissions for the emailapp and driveapp
* you need to set up a project trigger (edit/current project triggers) for the source sheet, on spreadsheet, on edit.
*The email will come from the owner of the google sheet and owner of the script project. (the person who reviews and accepts permissions)
MAKE SURE you are the owner of the sheet, that you are putting the code into the editor, and that you're okay with the e-mail coming from and replying to your email address.
*/
function EmailNotification(e) {
var ui = SpreadsheetApp.getUi();
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('Assets'); //source sheet
var columnb = sheet.getRange('B:B'); //Column with check boxes
var columnbvalue = columnb.getValues();
var notifysheet = ss.getSheetByName('Responses'); //destination sheet
var data = [];
var rownum =[];
//Condition check in B:B (or check box column); If true copy the same row to data array
for (i=0; i<columnbvalue.length;i++) {
if (columnbvalue[i] == 'true') {
var columnb2 = sheet.getRange('B2:B');
columnb2.setValue('false');
// What you want to say in the pop up alert
var response = ui.alert('Hold Up!\n Are you sure you want to send an email to finance for this asset change?', ui.ButtonSet.YES_NO);
if (response == ui.Button.YES) {
data.push.apply(data,sheet.getRange(i+1,1,1,20).getValues());
//Copy matched ROW numbers to rownum
rownum.push(i);
//Copy data array to destination sheet
notifysheet.getRange(notifysheet.getLastRow()+1,1,data.length,data[0].length).setValues(data);
var activeRow = notifysheet.getLastRow();
var assetname = notifysheet.getRange(activeRow, 1).getDisplayValue(); // The number is the column number in the destination "responses" sheet that you want to include in the email
var owner = notifysheet.getRange(activeRow, 3).getDisplayValue();
var serial = notifysheet.getRange(activeRow, 9).getDisplayValue();
var podate = notifysheet.getRange(activeRow, 6).getDisplayValue();
var email = 'theiremail#gmail.com' //The email address in which you want to send the email notification to
var subject = 'Asset has changed department ownership!'
//Body of the email message, using HTML and the variables from above
var message =
'<br><br><div style="margin-left:40px;">Heads Up!</div>'
+'<br><br><div style="margin-left:40px;">An asset has changed department ownership.</div>'
+'<br><br><div style="margin-left:40px;"><h3 style="text-decoration: underline;">Asset Name:'+ assetname +'</h3></div>'
+'<div style="margin-left:40px;">New Departmet Owner: '+ owner +'</div><br>'
+'<div style="margin-left:40px;">Serial: '+ serial +'</div>'
+'<div style="margin-left:40px;">Purchase Date: '+ podate +'</div>'
+ '<br><br><div style="margin-left:40px;">ヽ(⌐■_■)ノ♪♬</div>';
MailApp.sendEmail(
email,
subject,
"",
{
htmlBody: message,
name: 'Sadie Stevens', //The name you want to email coming from. This will be in bold, while your e-mail address will be small in italics
});
}
}
}
}
Try it this:
function EmailNotification(e) {
var ui=SpreadsheetApp.getUi();
var ss=SpreadsheetApp.getActiveSpreadsheet();
var sheet=ss.getSheetByName('Assets');
var columnb=sheet.getRange(1,2,sheet.getLastRow());
var columnbvalue=columnb.getValues();
var notifysheet=ss.getSheetByName('Responses');
var data=[];
var rownum=[];
for (var i=0;i<columnbvalue.length;i++) {
if (columnbvalue[i] == 'true') {
var columnb2=sheet.getRange(2,2,sheet.getLastRow()-1);
columnb2.setValue('false');
var response=ui.alert('Hold Up!\n Are you sure you want to send an email to finance for this asset change?', ui.ButtonSet.YES_NO);
if (response==ui.Button.YES) {
data.push(sheet.getRange(i+1,1,1,20).getValues());
rownum.push(i);
notifysheet.getRange(notifysheet.getLastRow()+1,1,data.length,data[0].length).setValues(data);
var activeRow=notifysheet.getLastRow();
var assetname=notifysheet.getRange(activeRow, 1).getDisplayValue(); // The number is the column number in the destination "responses" sheet that you want to include in the email
var owner=notifysheet.getRange(activeRow, 3).getDisplayValue();
var serial=notifysheet.getRange(activeRow, 9).getDisplayValue();
var podate=notifysheet.getRange(activeRow, 6).getDisplayValue();
var email='theiremail#gmail.com' //The email address in which you want to send the email notification to
var subject='Asset has changed department ownership!'
var message =
'<br><br><div style="margin-left:40px;">Heads Up!</div>'
+'<br><br><div style="margin-left:40px;">An asset has changed department ownership.</div>'
+'<br><br><div style="margin-left:40px;"><h3 style="text-decoration: underline;">Asset Name:'+ assetname +'</h3></div>'
+'<div style="margin-left:40px;">New Departmet Owner: '+ owner +'</div><br>'
+'<div style="margin-left:40px;">Serial: '+ serial +'</div>'
+'<div style="margin-left:40px;">Purchase Date: '+ podate +'</div>'
+ '<br><br><div style="margin-left:40px;">ヽ(⌐■_■)ノ♪♬</div>';
MailApp.sendEmail(email,subject,"",{htmlBody: message,name: 'Sadie Stevens'});
}
}
}
}

How to run script if a google sheets cell contains email?

I'm looking for help to send an email whenever a new row is added by a google form entry if said entry contains an email in the Email column. I'm new to Javascript, but I've pieced together some code which I plan to run off an onEdit trigger in GSheets.
My problem is that if there is no email address, the code will fail. I need to know how to wrap this in an "if/else" or maybe just a simple error handling bit would be fine, not sure.
If I go with an "if/else", I'll need to check if the email column contains a value. I don't need to check if it is a valid email; the google form already does this on submission.
Here is the code I have right now:
function MessageNotification() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
ss.setActiveSheet(ss.getSheetByName("Message Board"));
//
//extracts the values in last row and stores them into a two-dimensional
array called data
var sheet = SpreadsheetApp.getActiveSheet();
var lastRow = sheet.getLastRow();
var dataRange = sheet.getRange(lastRow,3,1,8);
var data = dataRange.getValues();
//
//pull column elements into a one-dimensional array called rowData
for (i in data) {
var rowData = data[i];
var emailAddress = rowData[2];
var poster = rowData[7];
var subject = rowData[3];
var recipName = rowData[6];
var comment = rowData[4];
var replyLink = rowData[5];
//
//
var message = 'Dear ' + recipName + ',\n\n'+poster+' has posted the
following comment directed to you: '+'\n'+comment+'\n\n'+'To reply to this
comment click: '+replyLink;
var subject = subject;
MailApp.sendEmail(emailAddress, subject, message);
}
}
thanks in advance for any help you can give me.
Thank you tehhowch for the help. I'm new at this so I'll have to continue researching the link you referred to regarding iteration best practice. However I was able to get this working with a simple 'if' wrapper, which turned out to be simpler than I thought.
I did find out that form submission does not recognize an active sheet, so manually testing my code worked, while form submission did not trigger it.
After some looking, I replaced:
var ss = SpreadsheetApp.getActiveSpreadsheet();
with this:
var ssID = '//insert spreadsheet id here';
var ss = SpreadsheetApp.openById(ssID);
This still did not work, so I had to kickstart it by deleting the trigger and putting it back in (found this info: On form submit trigger not working)
This may not be the most efficient code, but here is what I have now, and it does work:
function MessageNotification() {
var ssID = '//insert spreadsheet id here';
var ss = SpreadsheetApp.openById(ssID);
ss.setActiveSheet(ss.getSheetByName("Message Board"));
//extracts the values in last row and stores them into a two-dimensional
array called data
var sheet = SpreadsheetApp.getActiveSheet();
var lastRow = sheet.getLastRow();
var dataRange = sheet.getRange(lastRow,3,1,8);
var data = dataRange.getValues();
//
//pull column elements into a one-dimensional array called rowData
for (i in data) {
var rowData = data[i];
var emailAddress = rowData[2];
var poster = rowData[7];
var subject = rowData[3];
var recipName = rowData[6];
var comment = rowData[4];
var replyLink = rowData[5];
//
//
var message = 'Dear ' + recipName + ',\n\n'+poster+' has posted the
following comment directed to you: '+'\n'+comment+'\n\n'+'To reply to this
comment click: '+replyLink;
var subject = subject;
if(emailAddress)
{
MailApp.sendEmail(emailAddress, subject, message);}
}
}
As mentioned in the question comments, you want to use the event object available to the on form submit trigger. This can be accessed from a container-bound script on either the form or its responses spreadsheet, simply by adding a parameter to the function that receives the trigger.
This object is of the form:
e: {
authMode: <enum>,
namedValues: {
'q1title': [ <q1string> ],
'q2title': [ <q2string> ],
...
},
range: <Range>,
triggerUid: <string>,
values: [<q1string>, <q2string>, ...]
}
Using this object means that accessing of the Spreadsheet, for the purposes of emailing someone based on contents of the form, is unnecessary.
function MessageNotification(e) {
if(!e) return; // No form event object was provided.
var responses = e.namedValues;
var emailQTitle = /* the title of the question that asks for the email */;
// Check that 1) this question exists in the response object, and also
// 2) it has an answer with a value that 3) is "truthy".
// https://developer.mozilla.org/en-US/docs/Glossary/Truthy
if(responses[emailQTitle] // 1
&& responses[emailQTitle].length // 2
&& responses[emailQTitle][0]) // 3
{
var emailAddress = responses[emailQTitle][0];
/* access the responses variable in a similar manner
for the other variables needed to construct the email */
MailApp.sendEmail(emailAddress, ... );
} else {
/* There was no response to the email question. */
// You can use View->Stackdriver Logging to inspect the form response, for
// example, to make sure that it had the format or values you expected.
console.log({form_object: e, responses: responses, emailTitle: emailQTitle});
}
}

Programming google app script to trigger at a specific time by displaying spreadsheet in email body

I'm sending a spreadsheet in the body of an email everyday. I completed the email portion, but now im trying to program the trigger to set off at 1:15pm everyday. I'm not sure how to implement the code to trigger with the email?
'function nearMinute(minute) {
var sendRead = ScriptApp.newTrigger("sendRead1pm")
.timeBased()
.atHour(13)
.everyDays(1) // Frequency is required if you are using atHour() or atMinute()
.create();
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("Totals");
var subjecttable = UrlFetchApp.fetch("https://docs.google.com/spreadsheet/pub?
key=XXXXXXXXXXXXXXXXXXXXXXXXXXX=true&gid=1&output=html");
var htmltable = subjecttable.getContentText();
var fromName = "DoNotReply - email";
var rowData = ss.getRange("B16").getValues()[0];
var emailAddress = "emailaddress#gmail.com"; // First column
var message = {htmlBody: htmltable, name: fromName}; // Second column
var subject = "TEST $" + rowData;
MailApp.sendEmail(emailAddress, subject, "", message);
}`
You don't have to code your trigger. Make your function to do the email part and set up the trigger manually. In your script, go to Resources --> Current Project's Triggers and then add a trigger. This is the easiest.

Send email from google spreadsheet

I found the following script to insert form submission values into a google spreadsheet.
function doPost(e) { // change to doPost(e) if you are recieving POST data
var ss = SpreadsheetApp.openById(ScriptProperties.getProperty('active'));
var sheet = ss.getSheetByName("DATA");
var headers = sheet.getRange(1, 1, 1, sheet.getLastColumn()).getValues()[0]; //read headers
var headers2 = sheet.getRange(2, 1, 1, sheet.getLastColumn()).getValues()[0]; //read headers
var nextRow = sheet.getLastRow(); // get next row
var cell = sheet.getRange('a1');
var col = 0;
for (i in headers2){ // loop through the headers and if a parameter name matches the header name insert the value
if (headers2[i] == "Timestamp"){
val = new Date();
} else {
val = e.parameter[headers2[i]];
}
cell.offset(nextRow, col).setValue(val);
col++;
}
//http://www.google.com/support/forum/p/apps-script/thread?tid=04d9d3d4922b8bfb&hl=en
var app = UiApp.createApplication(); // included this part for debugging so you can see what data is coming in
var panel = app.createVerticalPanel();
for( p in e.parameters){
panel.add(app.createLabel(p +" "+e.parameters[p]));
}
app.add(panel);
return app;
}
//http://www.google.sc/support/forum/p/apps-script/thread?tid=345591f349a25cb4&hl=en
function setUp() {
ScriptProperties.setProperty('active', SpreadsheetApp.getActiveSpreadsheet().getId());
}
Now I want to send a formatted email to two of my coworkers every time a row gets inserted. I tried to use:
var emailAddress = "email#gmail.com"; // First column
var message = "message"; // Second column
var subject = "Sending emails from a Spreadsheet";
MailApp.sendEmail(emailAddress, subject, message);
but it's not sending anything.. can anyone advise please?
I had the same trouble.
With the most recent version of Google Apps I had to save the script, create a new revision, and re-publish the script making sure to select the new revision. After this the new code was in effect. I wasted several hours in the belief that the script would be updated if I just saved it.
Somehow the new method saves the script elsewhere. It's almost impossible to tell what code is actually running unless you go through the process of saving a revision, and re-publishing.