Extract last email with gscript - email

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);
}

Related

How to loop and collect MultiInput values?

I am using sap.m.MultiInput. How to send that data to the SAP Backend?
I tried using a loop:
for(var i = 0; i < oLenght; i++) {
var oData = this.getView().byId("myMultiInputControl").getTokens()[i].getKey();
}
But oData is holding always a new value. How to hold the data?
you can use a delimiter for example ("/" character) between the keys of the multinput and send the data to the backend System :
if(oMultiInputElement.tokens.length > 1) {
var dataToSend = "";
for(var i = 0; i < oMultiInputElement.tokens.length; i++) {
dataToSend = oFilterData.tokens[i].key + "/" + dataToSend;
}
} else {
dataToSend = oMultiInputElement.tokens[0].key;
}

Send multiple attachments using DriveApp.getFileById in Google Apps Script

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});
}

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);
}
}

Google Spreadsheet - How to avoid sending email duplicates?

I am having an issue with a script. I used the following script from Google Developers Website in order to do a simple merge mail. See https://developers.google.com/apps-script/articles/mail_merge
I modified a bit the script so to prevent email duplicates. However, even if the script seems to work as it marks 'EMAIL_SENT' in each row every time an email is sent. It does not pay attention if the mail as already been marked and still send the mail.
I believe there is an error at line 16 "var emailSent = rowData[6];"
I would really appreciate if someone could help me. Whoever you are thanks in advance.
Here is the modified script :
var EMAIL_SENT = "EMAIL_SENT";
function sendEmails() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var dataSheet = ss.getSheets()[0];
var dataRange = dataSheet.getRange(2, 1, dataSheet.getMaxRows() - 1, 7);
var templateSheet = ss.getSheets()[1];
var emailTemplate = templateSheet.getRange("A2").getValue();
var objects = getRowsData(dataSheet, dataRange);
for (var i = 0; i < objects.length; ++i) {
var Resume = DriveApp.getFilesByName('Resume.pdf') var Portfolio = DriveApp.getFilesByName('Portfolio.pdf') var rowData = objects[i];
var emailText = fillInTemplateFromObject(emailTemplate, rowData);
var emailSubject = "Architectural Internship";
var emailSent = rowData[6];
if (emailSent != EMAIL_SENT) {
MailApp.sendEmail(rowData.emailAddress, emailSubject, emailText, {
attachments: [Resume.next(), Portfolio.next()]
});
dataSheet.getRange(2 + i, 7).setValue(EMAIL_SENT);
SpreadsheetApp.flush();
}
}
}
function fillInTemplateFromObject(template, data) {
var email = template;
var templateVars = template.match(/\${\"[^\"]+\"}/g);
for (var i = 0; i < templateVars.length; ++i) {
var variableData = data[normalizeHeader(templateVars[i])];
email = email.replace(templateVars[i], variableData || "");
}
return email;
}
function getRowsData(sheet, range, columnHeadersRowIndex) {
columnHeadersRowIndex = columnHeadersRowIndex || range.getRowIndex() - 1;
var numColumns = range.getEndColumn() - range.getColumn() + 1;
var headersRange = sheet.getRange(columnHeadersRowIndex, range.getColumn(), 1, numColumns);
var headers = headersRange.getValues()[0];
return getObjects(range.getValues(), normalizeHeaders(headers));
}
function getObjects(data, keys) {
var objects = [];
for (var i = 0; i < data.length; ++i) {
var object = {};
var hasData = false;
for (var j = 0; j < data[i].length; ++j) {
var cellData = data[i][j];
if (isCellEmpty(cellData)) {
continue;
}
object[keys[j]] = cellData;
hasData = true;
}
if (hasData) {
objects.push(object);
}
}
return objects;
}
function normalizeHeaders(headers) {
var keys = [];
for (var i = 0; i < headers.length; ++i) {
var key = normalizeHeader(headers[i]);
if (key.length > 0) {
keys.push(key);
}
}
return keys;
}
function normalizeHeader(header) {
var key = "";
var upperCase = false;
for (var i = 0; i < header.length; ++i) {
var letter = header[i];
if (letter == " " && key.length > 0) {
upperCase = true;
continue;
}
if (!isAlnum(letter)) {
continue;
}
if (key.length == 0 && isDigit(letter)) {
continue;
}
if (upperCase) {
upperCase = false;
key += letter.toUpperCase();
} else {
key += letter.toLowerCase();
}
}
return key;
}
// Returns true if the cell where cellData was read from is empty. // Arguments: // - cellData: string function isCellEmpty(cellData) {
return typeof(cellData) == "string" && cellData == "";
}
// Returns true if the character char is alphabetical, false otherwise. function isAlnum(char) { return char >= 'A' && char <= 'Z' || char >= 'a' && char <= 'z' || isDigit(char); }
// Returns true if the character char is a digit, false otherwise. function isDigit(char) { return char >= '0' && char <= '9'; }
Your code is really hard to read and the functions that return 2 or more objects make it even harder...you are using variable names that are also a bit confusing.... but that is probably a personal pov :-)
Anyway, I think I've found the issue: when you write var rowData = objects[i];
This "object" is actually the result of the getRowData function but if you look at this function, you'll see that it returns 2 objects, the first one being itself the result of another function (getObjects) ...
You are checking the value is the 6th element of the array which is actually an object and compare it to a string. The equality will never be true.
I didn't go further in the analyse since I found it really confusing ( as I already said) but at least you have a first element to check .
I would suggest you rewrite this code in a more simple way and use more appropriate variable names to help you while debugging.
I would recommend logging both values before executing to make sure they are the same. I would also guess that the email_sent and EMAIL_SENT are different data types. Can also try forcing the value to string for comparison.
To clarify:
logger.Log(emailSent);
logger.Log(EMAIL_SENT);
if (emailSent.toString() != EMAIL_SENT.toString())
{...
Error is in this line of code -
var dataRange = sheet.getRange(startRow, 1, numRows, 2)
It's considering only 2 columns in the range. Changed 2 to 3 and it worked fine.