Send multiple attachments using DriveApp.getFileById in Google Apps Script - email

I am trying to get a script running that takes multiple file IDs from a Google Sheet and attaches them to an email. I cannot get multiple files to be attached using DriveApp.getFileById.
The script runs and fires off an email, but with no attachments.
function createAndSendDocument(values) {
// Get the email address of the active user
var email = Session.getActiveUser().getEmail();
// Get the name of the document to use as an email subject line.
var subject = 'New Paperwork';
//Let's add the attachments variables
var attachmentstring = values["Which documents do you want to attach?"];
var array = attachmentstring.toString().split(",");
var blobs = [];
var x = 0;
for (var i = 0; i < array.length; i++) {
//check if even
if (i % 2 === 0) {
blobs[x] = array[i];
x++;
}
}
// Append a new string to the "url" variable to use as an email body.
var body = 'your doc: ' + blobs[0] + blobs[1] + array[0] + array[1] + "length:" + array.length;
// Send yourself an email with a link to the document.
GmailApp.sendEmail(email, subject, body, {attachments: blobs});
}
I edited the original post to include the snippet of code. Here is the output of the blobs and array.
undefinedundefinedW-4 2019.pdf1YjQqFNze8VX0L6wZ9O3Y9AJNznR8jfxqlength:4

This code worked:
function createAndSendDocument(values) {
// Get the email address of the active user
var email = Session.getActiveUser().getEmail();
// email subject line.
var subject = 'New Paperwork';
// add the attachments variables
var attachmentstring = values["Which documents do you want to attach?"];
var array = attachmentstring.toString().split(",");
var blobs = [];
var x = 0;
for (var i = 0; i < array.length; i++) {
//check if even
if (i % 2 === 0) {
}
else
{
blobs[x] = DriveApp.getFileById(array[i]).getBlob();
x++;
}
}
// an email body.
var body = 'Hello';
// Send an email with attachments
GmailApp.sendEmail(email, subject, body, {attachments: blobs});
}

Related

Send email when any value is input into first column Google Script

I'm looking to send an email to the recipient (clientEmail) when data is added to the first column of that specific row. The data in the first column would be a mix of numbers and letters. I've tried different methods using the following code but can never get it to send only when the value in the first column contains a value.
var EMAIL_DRAFTED = "EMAIL DRAFTED";
function draftMyEmails() {
var sheet = SpreadsheetApp.getActiveSheet(); // Use data from the active
sheet
var startRow = 2; // First row of data to process
var numRows = sheet.getLastRow() - 1; // Number of rows to process
var lastColumn = sheet.getLastColumn(); // Last column
var dataRange = sheet.getRange(startRow, 1, numRows, lastColumn) // Fetch the data range of the active sheet
var data = dataRange.getValues(); // Fetch values for each row in the range
// Work through each row in the spreadsheet
for (var i = 0; i < data.length; ++i) {
var row = data[i];
// Assign each row a variable
var clientName = row[1]; // Col B: Client name
var clientEmail = row[2]; // Col C: Client email
var message1 = row[3]; // Col D: First part of message
var message2 = row[4]; // Col E: Second part of message
var emailStatus = row[lastColumn - 1]; // Col F: Email Status
// Prevent from drafing duplicates and from drafting emails without a recipient
if (emailStatus !== EMAIL_DRAFTED && clientEmail) {
// Build the email message
var emailBody = '<p>Hi ' + clientName + ',<p>';
emailBody += '<p>' + message1 + ', your requested data, ' + message2 + ', is ready.<p>';
//Send the emaiil
MailApp.sendEmail(
clientEmail, // Recipient
'Here is your data', // Subject
'', // Body (plain text)
{
htmlBody: emailBody // Options: Body (HTML)
}
);
sheet.getRange(startRow + i, lastColumn).setValue(EMAIL_DRAFTED); // Update the last column with "EMAIL_DRAFTED"
SpreadsheetApp.flush(); // Make sure the last cell is updated right away
}
}
}
Start off by changing your for loop, know the difference between ++i and i++, in this case you'd want to use the latter. See: difference between ++i and i++.
for (var i = 0; i < data.length; i++) {
All you need to do after that is add a check in your if statement for the column in question. Note: you could define this separately like you've done for the other variables. I'll provide 2 examples and you can pick which you'd prefer to use, both will function the same.
//option 1
if (emailStatus !== EMAIL_DRAFTED && clientEmail && row[0]) {
//option 2
var checkData = row[0];
if (emailStatus !== EMAIL_DRAFTED && clientEmail && checkData) {
In the end your code should look something like this:
var EMAIL_DRAFTED = "EMAIL DRAFTED";
function draftMyEmails() {
var sheet = SpreadsheetApp.getActiveSheet(); // Use data from the active sheet
var startRow = 2; // First row of data to process
var numRows = sheet.getLastRow() - 1; // Number of rows to process
var lastColumn = sheet.getLastColumn(); // Last column
var dataRange = sheet.getRange(startRow, 1, numRows, lastColumn); // Fetch the data range of the active sheet
var data = dataRange.getValues(); // Fetch values for each row in the range
// Work through each row in the spreadsheet
for (var i = 0; i < data.length; i++) {
var row = data[i];
// Assign each row a variable
var clientName = row[1]; // Col B: Client name
var clientEmail = row[2]; // Col C: Client email
var message1 = row[3]; // Col D: First part of message
var message2 = row[4]; // Col E: Second part of message
var emailStatus = row[lastColumn - 1]; // Col F: Email Status
// Prevent from drafing duplicates and from drafting emails without a recipient
if (emailStatus !== EMAIL_DRAFTED && clientEmail && row[0]) {
// Build the email message
var emailBody = '<p>Hi ' + clientName + ',<p>';
emailBody += '<p>' + message1 + ', your requested data, ' + message2 + ', is ready.<p>';
//Send the emaiil
MailApp.sendEmail(
clientEmail, // Recipient
'Here is your data', // Subject
'', // Body (plain text)
{
htmlBody: emailBody // Options: Body (HTML)
}
);
sheet.getRange(startRow + i, lastColumn).setValue(EMAIL_DRAFTED); // Update the last column with "EMAIL_DRAFTED"
SpreadsheetApp.flush(); // Make sure the last cell is updated right away
}
}
}

Extract last email with gscript

I have the following code with which I have to extract the last email arrived with the label 'AlertGol', then I have to process it by cutting the parts that I do not need and send it back to me by email. Something I'm doing wrong because I get more than 3 emails including one undefinied.
function getEmails() {
var label = GmailApp.getUserLabelByName("AlertGol");
var thread = label.getThreads();
for (var i = 0; i < thread.length; i++) {
var messages = thread[i].getMessages();
for (var j=0; j<messages.length; j++)
{
var msg = messages[j].getPlainBody();
var trim = msg.substring(5,15);
var trim1 = msg.substring(40, 90);
var tot = trim+trim1;
}
GmailApp.sendEmail(Session.getEffectiveUser().getEmail(), 'Subject', tot);
}

Google apps script, forward all emails except one

I have a script that forwards all of my emails that come in during specific times to email#domain.com.
The problem I am having, is that sometimes email#domain.com sends me an email during that time.
Can anyone suggest a way to add a rule that it should forward to all addresses except forwarding address?
function forwardEmails() {
try {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var settings = ss.getSheetByName('Settings').getDataRange().getValues();
if (settings[1][1] == 'No')
return;
if (settings[2][1] == "")
throw new Error('Please set Forward Email!');
var email = PropertiesService.getScriptProperties().getProperty('email');
if (!email)
throw new Error('First authorize script by clicking on menu: Email Forwarder >> Authorize Script');
var today = (new Date());
var applicableRules = validRules(today);
if (applicableRules) {
var unread = GmailApp.getInboxUnreadCount();
if (!unread)
return;
var threads = GmailApp.getInboxThreads(0, unread>100?100:unread);
var cutOff = today.getTime() - (MINUTES*60*1000 + 100); // 10 mins + 100 ms
for (var i=0; i<threads.length; i++) {
var msgs = threads[i].getMessages();
for (var j=0; j<msgs.length; j++) {
var from = msgs[j].getFrom();
var msgDate = msgs[j].getDate();
var msgTime = (new Date(msgDate)).getTime();
var diff1 = msgTime - cutOff;
if (diff1 > 0 && from.indexOf(email) == -1) {
var to = msgs[j].getTo();
var subject = msgs[j].getSubject();
var attach = msgs[j].getAttachments();
var body = msgs[j].getBody();
var plainBody = msgs[j].getPlainBody();
var replyTo = msgs[j].getReplyTo();
var options = {replyTo: from};
if (attach.length > 0)
options.attachment = attach;
GmailApp.sendEmail(settings[2][1], subject, plainBody, options );
}
}
}
}
} catch (error) {
var html = '<p>'+ error + '</p><br><br>Email Forwarder Rules & Settings<p>Line: '+ error.lineNumber + ', Filename: ' + error.fileName + '</p>';
if (!email)
email = Session.getActiveUser().getEmail();
MailApp.sendEmail(email, 'Email Forwarder Script Failed!', error + '\n\nEmail Forwarder Rules & Settings URL: ' + ss.getUrl(), {htmlBody: html});
}
}
Instead of using getInboxThreads() use search().
getInboxThreads() will return threads in your inbox while search() will return those that meet the search query. The following query will include include messages in your inbox but exclude those from email#domain.com
in:inbox -from:email#domain.com
You could add a check in the second loop of the "forwardEmails" function. The code below would skip any unread emails which have arrived from the forwarding address (I'm assuming the forwarding email is referenced in "settings[2][1]".
for (var i=0; i<threads.length; i++) {
var msgs = threads[i].getMessages();
for (var j=0; j<msgs.length; j++) {
var from = msgs[j].getFrom();
var msgDate = msgs[j].getDate();
var msgTime = (new Date(msgDate)).getTime();
var diff1 = msgTime - cutOff;
// New code
if (from === settings[2][1]) {
continue;
}

Google Apps Script - Relabeling Emails

I have been playing around with this script for the last couple weeks. The goal of the script is to go through a reporting inbox, pull reporting data from email attachments, copy into a google spreadsheet, and then relabel the emails to remove them from the inbox to prevent accidental double copying reports.
The script functions in this order:
Look for new emails in the Inbox with attachments
Copy attachment data
Paste into Spreadsheet in the next open row
Relabel the email with "Report" instead of "Inbox" to move all reports into a reporting folder
I have successfully accomplished steps 1 - 3, but for the life of me, I can not get the relabeling to work. When I run debug in the Google Apps console, it doesn't come back with any errors. Pasted below is the excerpt from the script doing the relabeling:
for (var i = 0; i < myLabel.length; i++) {
labels = myLabel[i].getLabels();
for (var j = 0; j < labels.length; j++) {
labels[j].addLabel("test_2");
labels[j].removeLabel("Test");
}
}
Below is the full script I am running.
function getCSV() {
// Create variable that looks for Gmails in the main inbox
var myLabel = GmailApp.getUserLabelByName("test");
Logger.log("myLabel:",myLabel);
// Create variable that is filled with all threads within Inbox label
var threads = myLabel.getThreads();
Logger.log("threads:",threads);
// Retrieves all messages in the specified thread
var msgs = GmailApp.getMessagesForThreads(threads);
Logger.log("msgs:",msgs);
// Uses active sheet the script is implemented on
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("test");
// Grabs CSV data from attachments and pastes into next available row in Spreadsheet
for (var i = 0; i < threads.length; i++) {
var messages = threads[i].getMessages();
for (var j = 0; j < messages.length; j++) {
var attachments = messages[j].getAttachments();
Logger.log("attachments:",attachments);
var csvData = Utilities.parseCsv(attachments[j].getDataAsString(), ",");
Logger.log(csvData);
for (var k = 1; k < csvData.length; k++) {
var dataPaste = sheet.appendRow(csvData[k]);
Logger.dataPaste;
}
}
}
// Removes Inbox Label and Adds Report Label
for (var i = 0; i < myLabel.length; i++) {
labels = myLabel[i].getLabels();
for (var j = 0; j < labels.length; j++) {
labels[j].addLabel("test_2");
labels[j].removeLabel("Test");
}
}
}
I ended up figuring this out. In addition, I added a section that can pull data if the CSVs are zipped.
function getCSV() {
// Associated Inbox label and Report Label with variables
var myInboxLabel = GmailApp.getUserLabelByName("Test");
var myReportLabel = GmailApp.getUserLabelByName("test_2");
// Create variable that is filled with all threads within Inbox label
var threads = myInboxLabel.getThreads();
Logger.log("threads:" + threads);
// Retrieves all messages in the specified thread
var msgs = GmailApp.getMessagesForThreads(threads);
Logger.log("msgs:" + msgs);
// Uses active sheet the script is implemented on
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("test");
/* Script to pull data from CSV that is NOT zipped
// Grabs CSV data from attachments and pastes into next available row in Spreadsheet
for (var i = 0; i < threads.length; i++) {
var messages = threads[i].getMessages();
for (var j = 0; j < messages.length; j++) {
var attachments = messages[j].getAttachments();
Logger.log("attachments:" + attachments);
var csvData = Utilities.parseCsv(attachments[j].getDataAsString(), ",");
Logger.log("csvData:" + csvData);
for (var k = 1; k < csvData.length; k++) {
var dataPaste = sheet.appendRow(csvData[k]);
Logger.dataPaste;
}
}
}
*/
// Grabs CSV within a zip folder and pastes into next available row in Spreadsheet
for (var i = 0; i < threads.length; i++) {
var messages = threads[i].getMessages();
for (var j = 0; j < messages.length; j++) {
var attachments = messages[j].getAttachments();
var extracted = Utilities.unzip(attachments[j]);
var csvData = Utilities.parseCsv(extracted[j].getDataAsString(), ",");
Logger.log(csvData);
for (var k = 1; k < csvData.length; k++) {
var dataPaste = sheet.appendRow(csvData[k]);
Logger.dataPaste;
}
}
}
// Removes Inbox Label and Adds Report Label
for (var x in threads) {
var thread = threads[x];
thread.removeLabel(myInboxLabel);
thread.addLabel(myReportLabel);
}
}

Email a reminder based on the status of a cell Google apps script

I am attempting to set a simple reminder email to a technician to remind when a routine service is due. I have a 2d array and code that works, but it only sends 1 email, which is the lowest row.
I'm kinda new to this, but I would like it to run through each row and send a reminder for every overdue.
Any help appreciated.
This is what I have now:
function Email_Reminder()
{;
var sheet = SpreadsheetApp.getActiveSheet();
statusArray = sheet.getDataRange().getValues();
status = "overdue";
for (i=3;i < statusArray.length;i++){
if (status == statusArray[i][6]) {
var customer = statusArray[i][0];
}
}
var email = "djens12#gmail.com"
var subject = "Reminder";
var body = "This is a reminder that the service is overdue for " +customer+ "";
MailApp.sendEmail(email,subject,body,{NoReply : true});
}
thanks
Just move your MailApp.sendEmail() inside your for loop
function Email_Reminder()
{;
var sheet = SpreadsheetApp.getActiveSheet();
statusArray = sheet.getDataRange().getValues();
status = "overdue";
var email = "djens12#gmail.com"
var subject = "Reminder";
for (i=3;i < statusArray.length;i++){
if (status == statusArray[i][6]) {
var customer = statusArray[i][0];
var body = "This is a reminder that the service is overdue for " +customer+ "";
MailApp.sendEmail(email,subject,body,{NoReply : true});
}
}
}