I am using Google Sheets to store the list of file names in Google Drive, their respective File ID. I am using another sheet in the same workbook to record email addresses and file names that I want to send those email addresses.
I have a Sheet named Data with the following columns
File Name - Files stored on Google Drive
File ID - File ID of the file derived from the share link
I have another Sheet named Request with the following columns
File Name
Email Address
I want to fetch the File mentioned as the File Name mentioned in the Request sheet by looking up the corresponding File ID from the Data sheet for that file name. Once the file is fetched, I want to send that file as an attachment to the email address mentioned in the Request sheet. I want to do this for each row in the Request sheet.
I have created an HTML file named DocTemplate to constitute the body of the email.
I have written the below code in the script editor of Google Sheets. On running it, a mail is triggered but it does not contain the attachment nor does it include the content of the HTML file. The body of the mail just reads [object Object]
What am I doing wrong?
function sendfile(){
var request = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Request");
var data = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Data");
var Avals = request.getRange("A1:A").getValues();
var requestlastrow = Avals.filter(String).length;
var Avalsu = data.getRange("A1:A").getValues();
var datalastrow = Avalsu.filter(String).length;
for (var i=2;i<= requestlastrow;i++) {
var control = request.getRange(i,6).getValue();
if(control != 1){
var FilenameRequest = request.getRange(i,1).getValue();
for (var j=2;j<= datalastrow;j++) {
var FilenameData = upload.getRange(j,1).getValue();
if(FilenameRequest == FilenameData) {
/// to get the File ID
var FileID = data.getRange(j,2).getValue();
var file = DriveApp.getFileById(FileID);
/// to form the email
var values = request.getRange(i,1,1,2).getValues();
var rec = values[0];
var client =
{
email: rec[1],
name: rec[0]
};
client.subject = 'Request Filename:' + client.name;
var template = HtmlService
.createTemplateFromFile("DocTemplate.html");
template.client = client;
var message = template.evaluate().getContent();
MailApp.sendEmail(client.email,client.subject,{
htmlBody: message,
attachments: [file.getAs(MimeType.PDF)]
});
request.getRange(i,6).setValue("1");
}
}
}
}
}
Since this is not a reproducible example I can only assume that the rest of the code works except for this :
MailApp.sendEmail(client.email,client.subject,{
htmlBody: message,
attachments: [file.getAs(MimeType.PDF)]
});
It should also contain the message argument :
MailApp.sendEmail(client.email,client.subject,message,{
htmlBody: message,
attachments: [file.getAs(MimeType.PDF)]
});
Related
I am trying to create a Google Form linked to a Google Sheet utilizing some Google App script that will take some answers from a survey, attach an uploaded file, and send an email to a specific person. I have been able to figure out the part where I collect the data in a Google Sheet and send an email, but the part where I take the uploaded file and have it as an attachment in the email is stumping me.
Currently, my code to send the email looks like this:
GmailApp.sendEmail(Recipient,subject,'',{htmlBody: htmlText},);
But looking at the documentation on sendEmail, it looks like I want to add more to that Options part, right? The so if I am defining a variable for this, I need to use getFileById, but the file ID will be different with each upload. Furthermore, I might need to attach multiple files.
I have created a test Google Form here and I have attached it to a Google Sheet here. You can see the Google App Script here. You can check the email being sent/received successfully by looking at formtesting4#mailinator.com as specified in the code.
Is that possible with what I am trying to do?
You can refer to this sample script:
function emailMe() {
const ss = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
const info = ss.getDataRange().getValues();
info.forEach((entry,a) => {
// Identify whether notification has been sent
if (entry[4] === '') {
// Collect entries
var Recipient = "your#email.com"
var subject = 'Roster Scheduler Update';
Timestamp = entry[0];
Name = entry[1];
Roster = entry[2];
attachment = "TEST";
var attachmentBlobs = [];
//Get the blob of all attachments available
if(entry[3]){
var attachments = entry[3].split(', ');
attachments.forEach(url => {
var fileId = url.replace('https://drive.google.com/open?id=','');
Logger.log(fileId);
var file = DriveApp.getFileById(fileId);
attachmentBlobs.push(file.getBlob());
});
}
let body = '';
// Generate email
var html = HtmlService.createTemplateFromFile("email.html");
var htmlText = html.evaluate().getContent();
// Send email
GmailApp.sendEmail(Recipient, subject, body, {htmlBody: htmlText, attachments: attachmentBlobs});
// Email confidence
const check = 'Sent';
ss.getRange(a + 1,5).setValue(check);
}
});
}
Changes done:
Get the blob file of all the uploaded attachments using File.getBlob(). You can get the file id from the attachment's url link and use DriveApp.getFileById(id)
Include body in the GmailApp.sendEmail() to fix email content issue
Include attachments as an option in the GmailApp.sendEmail(recipient, subject, body, options)
Output:
Sample1: 3 attachments
Sample2: 1 attachment
I have created a Google Form containing two fields (First Name, Last Name)
I have PDF files in Google Drive/specific folder, PDF files named as "First Name"+"Last Name"
I want to get PDF file from my Google Drive based on form submission and get the URL to be sent by email.
I need the way to get PDF file based on form user submission.
I have written the below code which shall send the PDF as email attachment in place of the URL of PDF. I hope this code can help you. This code is a very basic code which can be further advanced as per your needs. Please let me know if you need any further help.
function pdfextractor() {
var ss = SpreadsheetApp.getActiveSpreadsheet(); // Get active spreadsheet.
var lastrow = ss.getLastRow();
var sheetName = ss.getRange("B" + lastrow).getValue() + " " + ss.getRange("C" + lastrow).getValue(); //considering format 'FirstName LastName' stored in column B & C of spreasheet generated by submission of google forms.
var pdfName = sheetName + ".pdf";
ss.getRange("D" + lastrow).setValue(pdfName);
var files = DriveApp.getFilesByName(pdfName);
var body = "This is a test email";
var subject = "PDF File "
var email = "admin#gmail.com"
while (files.hasNext()) {
var file = files.next();
}
GmailApp.sendEmail(email, subject, body, {
attachments: [file]
});
}
You can also change the email of each mail you want to send if stored with the sheet.
One way to do it is to create trigger that fires when the form is submitted. Based on this event, you can get the responses from the form submission, use them to search the file in Drive and send it attached to an email.
Here's an example that you can adapt to build what you need:
function onSubmit(e) {
// Get submitted responses
let itemResponses = e.response.getItemResponses();
// Get form answers (assume the form has three question in this order: First Name, Last Name, Email)
let firstName = itemResponses[0].getResponse();
let lastName = itemResponses[1].getResponse();
let email = itemResponses[2].getResponse();
// Get file (first file found with specified name)
let searchResult = DriveApp.searchFiles(`title contains \'${firstName+lastName}\'`);
let respondentFile = searchResult.next();
if (!respondentFile) throw 'File not found';
// Send email with respondent's file
MailApp.sendEmail(email, 'Your PDF File', 'Your PDF file is attached.', {
name: 'Automatic Emailer Script',
attachments: [respondentFile.getAs(MimeType.PDF)]
});
}
Needing help with adding 'n' number of attachments.
Code below:
for(var i = 2; i<=lr; i++)
{
var Contact_Person = ss.getRange(i,4).getValue();
var PDFs = ss.getRange(i,6).getValue();
//The above i am grabbing the PDF name from a column in My sheet.
//This name is used for generating my Mail Merge File.
var contents = DriveApp.getFolderById('1ouiQE2cERaRMC_rnSftJCqQCpr2B4x3D').getFiles();
PDFs = DriveApp.getFilesByName(Contractor_Name);
if(PDFs.hasNext())
{
var attach = [];
while(contents.hasNext())
{
var file = contents.next();
if (file.getMimeType() == "application/pdf")
{
attach.push(file);
}
}
GmailApp.sendEmail(currentEmail, Subject, messageBody,
{
attachments: [PDFs.next().getAs(MimeType.PDF), attach[0],attach[1],attach[2], attach[3],],
name: 'Test'
});
}
//This section is for me to grab 1 attachment according to the name specified for that row matching
//the Merged file in the google drive folder.
//I am also trying to attach from a separate folder N number of files to this email.
Pdfs is a variable holding getting values from Column 6 in my Spreadsheet.
This column per row has a set of names.
When the program runs it performs a mail merge and then sends an email to the user of a specific row.
Example:
Email Subject Reference No. Contact Person Contractor Name PDFs
***#gmail.com Test XXXXX Mr. Dan XYZ Company XYZ Company
Answer:
You can just push them all to the same array.
More Information:
From the documentation on GmailApp.sendEmail(recipient, subject, body, options):
Advanced parameters
attachments BlobSource[] an array of files to send with the email
So you can attach them all in one array.
Code Snippet:
if (PDFs.hasNext()) {
var attach = [];
attach.push(PDFs.next().getAs(MimeType.PDF));
while (contents.hasNext()) {
var file = contents.next();
if (file.getMimeType() == "application/pdf") {
attach.push(file);
}
}
GmailApp.sendEmail(currentEmail, Subject, messageBody, {
attachments: attach,
name: "Test"
});
}
References:
Class GmailApp - sendEmail(recipient, subject, body, options) | Apps Script | Google Developers
I'm new here and try to seek some expertise to help to create a google apps script.
I have a spreadsheet and want to export the header and the new added row value to csv file and save it into my local c drive and send an alert email with column B value as a subject.
eg. spreadsheets has 14 columns and I would like to export start from column 2 to csv with values like: "column2 value; column3 value; column4 value; column5 value; column6 value; .....column14 value "
Below is my description workflow :
So everytime when people filled up the value in the google forms and press submit, i will received a new row value in a google sheet. Then i will export the header and the latest row value to csv file into my local c drive and send an alert email with column B value as a subject.
Much appreciated if some expertise can help me on this. Thank you so much. :)
Excel sample.xlsx
See if this helps you:
We'll assume you have the spreadsheet configured as follows:
You've a sheet for submission called Responses
You've a helper sheet needed for the script called Temp which has
the same headers in the first row than the Responses sheet
In the illustrated example below, you want to save as CSV file the headers (Orange) along with the last row submitted (Green)
When you access the script you'll change the following:
The Spreadsheet ID of the whole document
The ID of the tab Temp (numbers found after edit#gid=)
The email address of the recipient
Code:
// Example: https://docs.google.com/spreadsheets/d/1kXaTto1ktqX0XNKQ035897FGX5tV75o7wuYHiNCOqEFfI/edit#gid=1269457815
// In this link the ID of the Spreadsheet is everything after /d/
// which is: 1kXaTto1ktqX0XNKQ035897FGX5tV75o7wuYHiNCOqEFfI
// THE ID of the sheet Temp would be something like: 1269457815
// ---------- Menu ----------
function onOpen() {
var ui = SpreadsheetApp.getUi();
ui.createMenu('CSV File')
.addItem('Step 1: Email CSV', 'EmailRange')
.addItem('Step 2: Save CSV file', 'showurl')
.addToUi();
}
// Choose how do want to export the: csv,pdf,xlsx
EXPORT_TYPE="csv";
function EmailRange() {
// Enter Sheet ID in between ""
var sheetId = "ID GOES HERE";
var ss = SpreadsheetApp.openById(sheetId);
var sheet=ss.getSheetByName("Responses");
// You can set up the headers beforehand
var temp = ss.getSheetByName("Temp");
//Copy range onto Temp sheet
var rangeToCopy = sheet.getRange("A"+(ss.getLastRow())+":N"+(ss.getLastRow()));
// It will erase any previous data
rangeToCopy.copyTo(temp.getRange(2, 1));
// Temporarily hide the sheet
ss.getSheetByName('Responses').hideSheet()
//Authentification
var params = {method:"GET",headers:{"authorization":"Bearer "+ ScriptApp.getOAuthToken()}};
var url="https://docs.google.com/spreadsheets/d/"+ss.getId()+"/export?format="+EXPORT_TYPE;
//Fetch URL of active spreadsheet
var fetch=UrlFetchApp.fetch(url,params);
//Get content as blob
var blob=fetch.getBlob();
var mimetype;
if(EXPORT_TYPE=="pdf"){
mimetype="application/pdf";
}else if(EXPORT_TYPE=="csv"){
mimetype="text/csv";
}else if(EXPORT_TYPE=="xlsx"){
mimetype="application/xlsx";
}else{
return;
}
// OP: send an alert email with column B value as a subject
var subject = sheet.getRange("B"+(ss.getLastRow()));
var timestamp = sheet.getRange("A"+(ss.getLastRow()));
var Title = subject.getValues();
var signature = timestamp.getValues();
//Change Email Recipient underneath
GmailApp.sendEmail('s.nabil#arrowad.sch.sa',
'Job ID: '+Title,
'Hi there,' + '\n\n' + 'A new entry has been submitted, please find the details in the attached CSV file.' + '\n\n' + 'Submitted on: '+signature,
{
attachments: [{
fileName: Title + "."+EXPORT_TYPE,
content: blob.getBytes(),
mimeType: mimetype
}]
});
//Reshow Response sheet
ss.getSheetByName('Responses').showSheet()
}
function showurl() {
// Enter Spreadsheet ID after d/ and the TAB ID of Temp after gid=
var htmlOutput = HtmlService
.createHtmlOutput('Click here My File to download')
.setWidth(250) //optional
.setHeight(50); //optional
SpreadsheetApp.getUi().showModalDialog(htmlOutput, 'Download CSV File');
}
STEP 1: Sending an email to the defined recipient in the script with the subject being the value of the last row in column B, and the signature the submission date & time, like this:
The CSV file will be attached to the email:
STEP 2: From the CSV File Menu which is created when opening the spreadsheet:
Save file to your Local desktop:
When running my script I get the error Converting from application/pdf to application/vnd.google-apps.spreadsheet is not supported. (line 6, file "Code")
The original file is no PDF but an excel worksheet. I tried different file with different types and every file returned as PDF.
Here is my code:
function sendTimelist() {
var emailAddress = 'some#mail.com';
var mailReplyTo = 'somemore#mail.com';
var subject = 'Timelist';
var message = 'Here is my timelist!';
var timelist = SpreadsheetApp.openById("1v7EShuCrjrEa8BxW2JGCRDUwuIsUk03fnvvYEVntlvM").getAs(MimeType.GOOGLE_SHEETS);
var optAdvancedArgs = {replyTo: mailReplyTo, name: attachmentName, attachments: [timelist] };
var attachmentName = 'Timelist.xlsx';
GmailApp.sendEmail(emailAddress, subject, message, optAdvancedArgs);
}
What am I missing?
I focused on the length of your file ID. Your file ID is 1v7EShuCrjrEa8BxW2JGCRDUwuIsUk03fnvvYEVntlvM. The length is 44. In the case of Excel file in Google Drive, the length of ID is 28. And the case of Google Docs (Spreadsheet, Document, Slide), the length of ID is 44.
When Google Docs files are downloaded without the assignment of export format, the format automatically becomes PDF.
I thought that you might try to send Spreadsheet of Google Docs. In order to confirm this, can you try to run a following script?
var id = "1v7EShuCrjrEa8BxW2JGCRDUwuIsUk03fnvvYEVntlvM";
Logger.log(DriveApp.getFileById(id).getMimeType());
If the log shows application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, the file is Excel file. If the log shows application/vnd.google-apps.spreadsheet, the file is Spreadsheet file.
In the case of Excel file, when the file is sent as an attachment file of gmail, it is not converted. Excel file can be sent. In the case of Spreadsheet file, it is converted to PDF and sent as an attachment file.
If your file was a Spreadsheet file, in order to send it as Excel file, you can use the following sample script.
Sample script :
function sendTimelist() {
var emailAddress = 'some#mail.com';
var mailReplyTo = 'somemore#mail.com';
var subject = 'Timelist';
var message = 'Here is my timelist!';
var attachmentName = 'Timelist.xlsx';
var fileId = "1v7EShuCrjrEa8BxW2JGCRDUwuIsUk03fnvvYEVntlvM";
var timelist = UrlFetchApp.fetch(
"https://docs.google.com/feeds/download/spreadsheets/Export?key=" + fileId + "&exportFormat=xlsx",
{
"headers": {Authorization: "Bearer " + ScriptApp.getOAuthToken()},
"muteHttpExceptions": true
}
).getBlob().setName(attachmentName);
var optAdvancedArgs = {replyTo: mailReplyTo, name: attachmentName, attachments: [timelist] };
GmailApp.sendEmail(emailAddress, subject, message, optAdvancedArgs);
}
If I misunderstand your situation, I'm sorry.
I think the source of the problem is using SpreadsheetApp to open the file. To preserve original data type, open it as DriveApp.getFileById(...) which returns a File object. You shouldn't need getAs either.