I made a script that forwards emails to different people when clicking on a card button. This is the main part of the code:
function forwardtest() {
var threadsa = GmailApp.search('label: Inbox label: product-a');
for (var i = 0; i < threadsa.length; i++) {
var recipient = 'producta#gmail.com';
var messages = threadsa[i].getMessages();
for (var j = 0; j < messages.length; j++) {
var body = messages[j].getBody();
messages[j].forward(recipient,{htmlBody: body});
}
GmailApp.moveThreadToArchive(threadsa[i]);
}
var threadsb = GmailApp.search('label: Inbox label: product-b');
for (var i = 0; i < threadsb.length; i++) {
var recipient = 'productb#gmail.com';
var messages = threadsb[i].getMessages();
for (var j = 0; j < messages.length; j++) {
var body = messages[j].getBody();
messages[j].forward(recipient,{htmlBody: body});
}
GmailApp.moveThreadToArchive(threadsb[i]);
}
}
Sometimes, we'll need to change the forwarding addresses. Since I don't want people to change it directly in the code, I made a Google Sheets in which the forwarding addresses are listed depending on the email labels:
Product label
Forward address
product-a
producta#gmail.com
product-b
productb#gmail.com
Is there a way to replace the var recipient = 'producta#gmail.com'; with "Look for the cell containing "product-a" content and define recipient as the content in the cell which is next to it"?
Thank you very much in advance!
Solution:
Since you will be referencing a Google Sheet to fetch the data, you would need to use Sheets API starting from the SpreadsheetApp class. Also, since this script is not attached to the sheet from your use case, you would need to open the sheet by it's ID, which is in the URL link:
https://docs.google.com/spreadsheets/d/<SHEET-ID>/edit#gid=0
Take note of the SHEET-ID since we will use it in the code.
For the code itself, I made a separate functions for finding the recipient and sending the emails for modularity:
EDIT: Rearranged the code, moved the function into a for loop instead.
function forwardtest() {
var sheet = SpreadsheetApp.openById("SHEET-ID").getSheetByName("Sheet1");
var prodList = sheet.getRange(2,1,sheet.getLastRow()-1,2).getValues();
for (var k = 0; k < prodList.length; k++) {
var prod = prodList[k][0];
var recipient = prodList[k][1];
var threads = GmailApp.search('label: Inbox label: '+prod);
for (var i = 0; i < threads.length; i++) {
var messages = threads[i].getMessages();
for (var j = 0; j < messages.length; j++) {
var body = messages[j].getBody();
messages[j].forward(recipient,{htmlBody: body});
}
GmailApp.moveThreadToArchive(threads[i]);
}
}
}
Note: Replace the SHEET-ID with the sheet ID from the URL.
Sample Output:
Using a sample table with a variable number of products:
References:
Class SpreadsheetApp
Class Sheet
Class Range
Related
I have the following code in my script:
function getEmail() {
var label = GmailApp.getUserLabelByName("parse");
var threads = label.getThreads();
for (var i = threads.length - 1; i >= 0; i--) {
var messages = threads[i].getMessages();
for ( var j = 0; j < messages.length; j++ ) {
var msg = messages[j].getBody();
Logger.log(msg);
}
threads[i].removeLabel(label);
}
}
When no emails with label, everything is fine.
But if new email arriving and gets label "parse", there are all emails inside messages array, not just the one with label.
I have the same code in another account and everything works perfect.
Please help me figure it out.
I have two codes, the first of which works and shows all attachments and the second shows only the first. "getAttachmentAndMessage" is used by several of my scripts so I need to have it in a separate function in order not to duplicate my configuration. Please help.
//this function get me all attachments
//this function is just an example of how I built my code below;
function searchEmailsData(){
var search = GmailApp.search('in:inbox newer_than:3d');
var threads = GmailApp.getMessagesForThreads(search);
for (var i = 0 ; i < threads.length; i++) {
var thread = threads[i];
for (var j = 0; j < thread.length; j++) {
var message = thread[j];
var attachments = message.getAttachments();
for (var k = 0; k < attachments.length; k++) {
var attachment = attachments[k];
Logger.log(attachment.getName());
}
}
}
}
//this functions get me only first attachment but I need all of them;
function searchEmailsData2(){
var search = GmailApp.search('in:inbox newer_than:3d');
var threads = GmailApp.getMessagesForThreads(search);
for (var i = 0 ; i < threads.length; i++) {
var thread = threads[i];
var obj = getAttachmentAndMessage(thread);
Logger.log(obj[1].getName())
}
}
function getAttachmentAndMessage(thread){
for (var j = 0; j < thread.length; j++) {
var message = thread[j];
var attachments = message.getAttachments();
for (var k = 0; k < attachments.length; k++) {
var attachment = attachments[k];
var obj = [message, attachment];
return obj;
}
}
}
In order to return not the first attachment but rather all of them, you can modify the getAttachmentAndMessage() function as follows:
function getAttachmentAndMessage(thread) {
var results = [];
for (var j = 0; j < thread.length; j++) {
var message = thread[j];
var attachments = message.getAttachments();
var obj = {'message': message, 'attachments': attachments};
results.push(obj);
}
return results;
}
The above will return a list of objects, in which each objects contains a property message, and a property attachments (which is a list of attachments).
In order to return a list containing only the attachments in the thread, you can use the following variation of the code above:
function getAttachmentAndMessage(thread) {
var results = [];
for (var j = 0; j < thread.length; j++) {
var message = thread[j];
var attachments = message.getAttachments();
results = results.concat(attachments);
}
return results;
}
Your original code
In your original getAttachmentAndMessage() code, you were using a return statement inside of the for loop. That means that upon finding the first message (first iteration of the outer loop) and upon finding its first attachment (first iteration of the inner loop) the function would simply return one value, which is a list containing the first message and its first attachment.
i have create this script:
function myTest() {
var ss = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var label = GmailApp.getUserLabelByName("Label1");
var threads = label.getThreads();
var countMail = 0;
//get first message in first thread
for (var i = 0; i < threads.length; i++) {
var messages=threads[i].getMessages();
countMail = countMail + messages.length;
}
ss.getRange(1,1).setValue(countMail);
}
it runs nearly perfect. Here I get all eMails back which are connected with this treads (marked with Label1 or not).
Does anyone can share a simply script how I can count all eMails which are "realy" marked with the Label.
Thanks
Try this:
function labelMsgs(){
var labels = Gmail.Users.Labels.list("me").labels;
var lblId;
for (var i = 0; i < labels.length; i ++){
if (labels[i].name == "Label1"){
lblId = labels[i].id;
break;
}
}
var optionalArgs = {
"labelIds" : lblId,
"maxResults" : 200
}
var messages = Gmail.Users.Messages.list("me", optionalArgs).messages;
}
This method uses the Gmail API directly, for this you'll need to enable Google Advanced Services, it will return a list of all messages tagged with the "Label1" label. You can play around with maxResults and with the pageToken to see more results, but this is the general approach.
I want to set the variable "subject" to be the subject line of each email that matches my GmailApp.search criteria. Right now when it searches, it stores every subject line into the "subject" variable and I am unsure how to make it so I can perform subject[0] for the first subject, subject[1] for the second subject, etc
var threads = GmailApp.search("label:bills")
for (var i = 0; i < threads.length; i++) {
var messages = threads[i].getMessages();
for (var m = 0; m < messages.length; m++) {
var subject = messages[m].getSubject()
}
}
If I have 2 emails that match the "bills" label, it will store both subject lines under "var = subject".
Instead of assigning the subject to a variable in you for loop, you need to push them into an array then you can access them like you wanted to with subject[1].
var subject = new Array();
var threads = GmailApp.search("label:bills")
for (var i = 0; i < threads.length; i++) {
var messages = threads[i].getMessages();
for (var m = 0; m < messages.length; m++) {
subject.push(messages[m].getSubject());
}
}
The Code which i have tried is not able to get the email with specific subject line please let me know what is the mistake in the script mentioned below
Tried the Below mentioned Script but still not working:
function amy() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = ss.getActiveSheet();
var threads = GmailApp.search('subject: "New submission from Free Diagnosis*"');
var a=[];
for (var i = 0; i < threads.length; i++) {
var messages = GmailApp.getMessagesForThread(threads[i]);
for (var j = 0; j < messages.length; j++) {
a[j]=parseMail(messages[j].getPlainBody());
}
}
var nextRow=s.getDataRange().getLastRow()+1;
var numRows=a.length;
var numCols=a[0].length;
s.getRange(nextRow,1,numRows,numCols).setValues(a);
}