Send Only Active Sheet as PDF Attachment through GMail in Google Sheet - javascript

Right now, my code is sending my entire Google Sheet file as a PDF attachment. I am needing it, though, to only send my one tab entitled "PO Template". Let me know if you can help:
function emailGoogleSpreadsheetAsPDF() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var email = ss.getRange("A19").getValue();
var PO = ss.getRange("N3").getValue();
var subject = "PO No. " + PO;
var blob =
DriveApp.getFileById(shs.getId()).getAs("Application/pdf");
var body = "Install the <a href='http://www.labnol.org/email-
sheet'>Email Spreadsheet add-on</a> for one-click conversion.";
blob.setName(ss.getName()+".pdf");
if(MailApp.getRemainingDailyQuota()>0)
GmailApp.sendEmail(email, subject, body, {
htmlBody: body,
attachments:[blob]
});
}

Don't think there's an adhoc method to do this. You'll have to resort to a workaround as suggested by this github tutorial:
// Create a new Spreadsheet and copy the current sheet into it.
var newSpreadsheet = SpreadsheetApp.create("Spreadsheet to export");
var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var projectname = SpreadsheetApp.getActiveSpreadsheet();
sheet = originalSpreadsheet.getActiveSheet();
sheet.copyTo(newSpreadsheet);
// Find and delete the default "Sheet 1", after the copy to avoid triggering an apocalypse
newSpreadsheet.getSheetByName('Sheet1').activate();
newSpreadsheet.deleteActiveSheet();

Related

Google Sheet / Apps script / Trigger when a new row is added [duplicate]

This question already has answers here:
Running onEdit trigger when sheet is updated by Zapier
(2 answers)
Closed 1 year ago.
I am currently working on an Apps Script on a google sheet file. I made a script that sends mail to contacts. In my sheet the contacts are in the form of a line which is automatically added with a zapier. I have installed an onChange trigger but I would like it to act only when a new row is added to my sheet, I have looked everywhere but no solutions work or correspond to my problem. So if anybody have an idea to solve it, it would be helpfull
(I put you a copy of my script below)
thanks in advance
'
function envoie_mail (){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet1=ss.getSheetByName('testmail');
var lr = sheet1.getLastRow();
var eligible = sheet1.getRange(lr,4).getValue();
var emailadresse = sheet1.getRange(lr,1).getValue();
var subject = sheet1.getRange(lr,2).getValue();
if (eligible === "non"){
var htmlTemplate = HtmlService.createTemplateFromFile("body.html");
var modele = htmlTemplate.evaluate().getContent();
var reference = sheet1.getRange(lr,3).getValue();
modele = modele.replace("<ref>",reference).replace("<ref2>",reference);
MailApp.sendEmail({
to: emailadresse,
subject: subject,
htmlBody: modele
});
}
}
I don't know how zapier works, howerver try to put an indicator and test as follows
function createSpreadsheetChangeTrigger() {
var ss = SpreadsheetApp.getActive();
ScriptApp.newTrigger('onChange')
.forSpreadsheet(ss)
.onChange()
.create();
}
function onChange(e) {
var f = SpreadsheetApp.getActiveSheet()
var data = f.getRange(1,f.getLastColumn(),f.getLastRow(),1).getValues().join().split(',')
for (var i=0;i<data.length;i++){
if (data[i]=='') {
Browser.msgBox('envoi mail ligne ' + (i+1))
f.getRange((i+1),f.getLastColumn()).setValue('ok')
}
}
}
https://docs.google.com/spreadsheets/d/1TEWS1e3uOnYybgbuScWb9plA9J7rgVjt16g9Ucg0x3M/copy

Form data submit to external sheet (google script)

I have created a data entry form in google sheets, now I am having trouble saving said entry to an external sheet so far this is what I have, I do not know if I am using the right method to reference sheet.
please look at comments, thank you
Everytime I am trying to submit the form it is giving lastRow Null
function submitData() {
//variable declaration for referenceing the active google sheet
var myGoogleSheet = SpreadsheetApp.getActiveSpreadsheet();
var shUserForm = myGoogleSheet.getSheetByName('MasterSheet');
//open external sheet
var extSS = SpreadsheetApp.openById("1U9SmfPCH9v8maqh6XL0dmRL85TJZfckUV7SAEGM3pQo");
var datasheet= extSS.getSheetByName("Mastersheet");
var srcData = shUserForm.getDataRange().getValues();
//to create the instance of the ui environment to use the alert features
var ui = SpreadsheetApp.getUi();
var response = ui.alert("Submit", "Do you want to submit the data?", ui.ButtonSet.YES_NO);
//checking the user response
if ( response == ui.NO) {
return; // to ext from this function
}
if ( validateEntry()== true) {
var blankRow =datasheet.getLastRow() + 1; //identify the next blank row
//'code to update the database sheet ( write data entry to DB sheet)
datasheet.getRange(blankRow,1).setValue(srcData.getRange("C7").getValue()); //input number
datasheet.getRange(blankRow,2).setValue(srcData.getRange("C9").getValue()); //Department
datasheet.getRange(blankRow,3).setValue(srcData.getRange("C11").getValue()); //Agent Name
datasheet.getRange(blankRow,4).setValue(srcData.getRange("C13").getValue()); //Hub location
datasheet.getRange(blankRow,9).setValue(srcData.getRange("C15").getValue()); //order ID
datasheet.getRange(blankRow,10).setValue(srcData.getRange("C20").getValue()); //type of entry
datasheet.getRange(blankRow,5).setValue(Session.getActiveUser().getEmail()); //Submitted By, this will automatically get user email
datasheet.getRange(blankRow,7).setValue(new Date()).setNumberFormat('yyyy-mm-dd h:mm:');
datasheet.getRange(blankRow,8).setValue(new Date()).setNumberFormat('yyyy-mm-dd h:mm:');
datasheet.getRange(blankRow,6).setValue(srcData.getRange("C17").getValue()); //comments
ui.alert(' "New Data Saved - Input #' + shUserForm.getRange("C7").getValue() + '"');
shUserForm.getRange("C7").clear();
shUserForm.getRange("C9").clear();
shUserForm.getRange("C11").clear();
shUserForm.getRange("C13").clear();
shUserForm.getRange("C15").clear();
shUserForm.getRange("C17").clear();
}
}
To save data to another Spreadsheet, You need to open it first by using either openById("insert sheet id here") or openByUrl("insert sheet URL here"). This will return a Spreadsheet class which has getSheetByName("sheet name") method you can use to access the Sheet.
ID of the spreadsheet can be found in the url. This can be found after /d/ or before /edit
Example ID:
https://docs.google.com/spreadsheets/d/12345/edit#gid=0
12345 is the Spreadsheet ID
Example:
Code:
function saveData() {
//open current sheet
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sh = ss.getSheetByName("Sheet1");
//open external sheet
var extSS = SpreadsheetApp.openById("Insert External Spreadsheet ID here");
var extSH = extSS.getSheetByName("Sheet1 External");
//get data from current Sheet.
var srcData = sh.getDataRange().getValues();
//write to external sheet
extSH.getRange(extSH.getLastRow()+1, 1, srcData.length, srcData[0].length).setValues(srcData);
}
This script will paste the values from Sheet1 to Sheet2
Before:
Sheet1 Data:
Sheet2 Data:
After:
Sheet1 Data:
Sheet2 Data:
SpreadsheetApp.openByID()
SpreadsheetApp.openByURL()
Spreadsheet.getSheetByName()
Class Sheet
Class Range

I'm trying to send an email from google spreadsheet, however the message is not copying the hyperlink

I have "to" in column A & "message/body" in column "B". I have a code which sends an email. However in my message I have a word hyperlinked to another sheet, while sending the email, the hyperlink is not considered. Please find the screenshot below.
However when the email is sent, the hyperlink is not visible. Please the image below
function sendEmails() {
var sheet = SpreadsheetApp.getActiveSheet();
var startRow = 2;
var numRows = 1;
var dataRange = sheet.getRange(startRow, 1, numRows, 2);
var data = dataRange.getValues();
for (var i in data) {
var row = data[i];
var emailAddress = row[0]; // First column
var message = row[1]; // Second column
var subject = 'Sending emails from a Spreadsheet';
MailApp.sendEmail(emailAddress, subject, message);
}
}
Use Templated HTML
var htmlBody = HtmlService.createTemplate('Email with <a href=<?=link?>> Some link </a>');
htmlBody.link = row[1];
MailApp.sendEmail({
to: row[0],
subject: 'Sending emails from a Spreadsheet',
htmlBody: htmlBody.evaluate().getContent()
});
If you have embedded cell links, you can extract them using Advanced Sheets services, as describe here, for example
var values = Sheets.Spreadsheets.get(SpreadsheetApp.getActive().getId(), {ranges: "Sheet1!B1:B10", fields: "sheets/data/rowData/values/hyperlink"})
var links = values.sheets[0].data[0].rowData.map(v => v.values[0].hyperlink);
them use them in templated HTML example I provided.

apps script, To view the message, please use an HTML compatible email viewer

I am trying to write a code that transfers data from gmail to spreadsheet. Here is the code:
function mailToStudio() {
var label = GmailApp.getUserLabelByName('GmailToStudio');
var threads = label.getThreads();
for (var i = threads.length - 1; i>=0; i--){
var msg = threads[i].getMessages()[0];
extractDetails(msg);
GmailApp.markMessageRead(msg);
}
}
function extractDetails(msg) {
var dateTime = msg.getDate();
var subjectText = msg.getSubject();
var senderDetails = msg.getFrom();
var body = msg.getPlainBody();
Logger.log(body);
var activeSheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
activeSheet.appendRow([dateTime, subjectText, senderDetails, body]);
}
My issue is with gmail body part. I want the data starting "Client Time" text and ending "Total" to be copied to spreadsheet in rows and columns same as given in gmail body.
Here is what I get:
1- When there are only few data lines in gmail body then the code works in such a way that it puts whole body content in a single cell instead of copying it to different rows and columns according to data structure.
2- When there are more data lines like 50+ lines in gmail body then the code does not work and all I get from body is an error "To view the message, please use an HTML compatible email viewer!".
Can anybody help how I can move gmail data to spreadsheet in proper rows and columns?
Thank you

Trouble with Google MailApp html option

I am having trouble setting up a script to iterate through a Google spreadsheet and email to the employees the lines that contain the reports about them.
In my tests The email address and subject lines are being emailed but depending on what I try the email is either blank or says "[object Object]".
I am viewing emails from the Gmail site in Chrome.
The HTML code does not have any variables yet. I am still working on getting it to email correctly and then I will try working in scriplets to build a table for the report.
Code.gs
function changeName() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var shA = ss.getSheets()[0]; // Report download
var shB = ss.getSheets()[1]; // Names & email address
var alRow = shA.getLastRow();
var blRow = shB.getLastRow();
var data = shA.getRange(1, 1, alRow, 14).getValues(); // Array of all employees reports
var employees = shB.getRange(1, 1, 2, 2).getValues(); // List of employees [i][0] and email address [i][1] in Scorecard data
for(i=0;i<employees.length;i++){
var html = HtmlService.createTemplateFromFile('Index').evaluate();
MailApp.sendEmail(employees[i][1], employees[i][0] + ' Scorecards Test', {htmlbody: html.getContent()});
Logger.log(html.getContent());
}
}
Index.html
<body>
<p1>Test 5062</p1>
<table>
<tr>
<td>Test Cell 1</td>
<td>Test Cell 2</td>
<td>Test Cell 3</td>
</tr>
</table>
</body>
When I view the log, it shows the HTML file.
What I am doing wrong?
How about a following modification?
From :
function changeName() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var shA = ss.getSheets()[0]; // Report download
var shB = ss.getSheets()[1]; // Names & email address
var alRow = shA.getLastRow();
var blRow = shB.getLastRow();
var data = shA.getRange(1, 1, alRow, 14).getValues(); // Array of all employees reports
var employees = shB.getRange(1, 1, 2, 2).getValues(); // List of employees [i][0] and email address [i][1] in Scorecard data
for(i=0;i<employees.length;i++){
var html = HtmlService.createTemplateFromFile('Index').evaluate();
MailApp.sendEmail(employees[i][1], employees[i][0] + ' Scorecards Test', {htmlbody: html.getContent()});
Logger.log(html.getContent());
}
}
To :
function changeName() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var shA = ss.getSheets()[0]; // Report download
var shB = ss.getSheets()[1]; // Names & email address
var alRow = shA.getLastRow();
var blRow = shB.getLastRow();
var data = shA.getRange(1, 1, alRow, 14).getValues(); // Array of all employees reports
var employees = shB.getRange(1, 1, 2, 2).getValues(); // List of employees [i][0] and email address [i][1] in Scorecard data
for(i=0;i<employees.length;i++){
var html = HtmlService.createTemplateFromFile('Index').evaluate();
MailApp.sendEmail({
to: employees[i][1],
subject: employees[i][0] + ' Scorecards Test',
htmlBody: html.getContent()
});
Logger.log(html.getContent());
}
}
If this didn't work, I'm sorry.
I find it a lot easier to build the html right in the file like this:
var s='<table>';
s+='Utilities.formatString('<tr><td>%s</td><td>%s</td><td>%s</td></tr>',data[i][0],data[i][1],data[i][2]);
s+='</table>'`;
MailApp.sendMail({to:emailAddress, subject: subj, htmlBody: s});
And keep in mind your html doesn't have to be complete.
Often I actually build the email this way and disable the sendEmail while I'm building it and just do this to view my results.
var ui=HtmlService.createHtmlOutput(s);
SpreadsheetApp.getUi().showModeLessDialog(ui,title);
And that way I can see what I'm doing while I built it without having to send emails. Some people use the logger but I like doing it this way.
And often people end up wanting to put some conditions on sending the email.
Email Address is not empty
Body is not empty
The email hasn't already been sent
You haven't exceeded your remaining daily quota
But hey everyone is different and you can choose to do it whatever way that makes you happy.

Categories