Gmail script forward without attachment - gmail

I am editing online available snooze script for gmail, where i would like to bring back an email unread, in inbox and on top of the list. I am able to make it unread, and bring back to inbox based on the available script, but to bring on top of the inbox, i am forwarding the email to myself. By this, I am able to get the email thread on top of the list, but when an email which is snoozed has an attachment, it forwards the email with attachment. I have tons of emails, and have limited available space. Hence i am ending up using extra storage for duplicate attachment which is unneeded.
I would like to forward the email, without attachment. Below is my current script:
var firstThread = page[i];
var giattachment = null;
var sub = firstThread.getFirstMessageSubject();
var newsub = "Reminder: " + firstThread.getFirstMessageSubject() + " : ";
var id = newsub + firstThread.getPermalink();
var messages = firstThread.getMessages();
var totalThreadCount= firstThread.getMessageCount();
for (var j = 0; j < messages.length; j++) {
var forwardlength=messages.length-1;
if(j == forwardlength) {
if (MARK_UNREAD) {
messages[j].markUnread();
}
messages[j].forward(userEmail,{subject: newsub, from:userEmail, name: EmailFrom, body: newbody, attachments:giattachment});
}
}
Inspite of this, the email gets forwarded with an attachment. Please advise..
Thanks in advance

To selectively forward messages, use filters to create rules that forward in response to message attributes or content.
You can filter messages by properties such as the sender, subject date, size, and message contents. Any query using Gmail's advanced search syntax can also be used in a filter. Try to set criteria.hasAttachment=true to false.
For more information, follow this link: https://developers.google.com/gmail/api/v1/reference/users/settings/filters

You can't forward using Class GmailMessage because it forces you to forward the original attachments. While unforunately undocumented, its advanced parameter attachments can only add new attachments.
However, you can forward by creating a new message using Class MailApp instead, in your case it would be:
var from, firstThread = page[i];
var sub = firstThread.getFirstMessageSubject();
var newsub = "Reminder: " + firstThread.getFirstMessageSubject() + " : ";
var id = newsub + firstThread.getPermalink();
var messages = firstThread.getMessages();
var totalThreadCount= firstThread.getMessageCount();
for (var j = 0; j < messages.length; j++) {
var forwardlength=messages.length-1;
if(j == forwardlength) {
if (MARK_UNREAD) {
messages[j].markUnread();
}
from = message.getHeader('From');
if (from.indexOf(' <') > -1)
from = from.substring(0, from.indexOf(' <'));
else
from = '';
MailApp.sendEmail(userEmail, newsub, '', {htmlBody: messages[j].getBody(), name: from, replyTo: message[j].getFrom()});
}
}
Changes:
Removed your var giattachment = null;
Replaced your messages[j].forward with MailApp.sendEmail
Used messages[j].getBody() to simulate the original body
Added the original sender's name as the "sender's" name
Added the original sender's address as reply-to
The last 2 points mean the forwarded message will arrive from "someone else's name" <your#address> which for most recipients will appear like a true forward.

Related

New Filter of Gmail for auto movetrash specific subjects with time condition. Warning: it never matches the incoming email

I want to make filters in Gmail email with certain subjects automatically deleted if more than 1 day from example#gmail.com. but when the filter is entered there is a warning from gmail:
Filter searches containing "label:", "in:", "is:", date range (e.g. "before:" or "after:") or stars criteria (e.g. "has:yellow-star") are not recommended as they will never match incoming emails. Do you still wish to continue to the next step?
How do you do it in the latest version (Gmail)?
I want to delete emails with certain subjects more than 1 day from example#gmail.com, how do that?.
Try using Google Script:
- Open: https://script.google.com
- Click File => New => Script File
- Type this code
// reference: https://medium.com/#fw3d/a-cleaning-robot-for-your-gmail-inbox-f44c01306ea2
// Modify by: Dicky Ibrohim for delete (move to trash) specific subject, sender, and time
function removetotrash() {
var delayDays = 1; // Impact form email more than 1day
var maxDate = new Date();
maxDate.setDate(maxDate.getDate()-delayDays);
// What will be executed, adjust the string here
var searches = [
'"SUBJECT WANT SEARCH TO DELETE" from:example#gmail.com'
];
// Looping for 500 last email
var threads = [];
for (var i = 0; i < searches.length; i++) {
var tmp_threads = GmailApp.search(searches[i], 0, 500); // search until 500 mail
var threads = threads.concat(tmp_threads);
}
// Then remove all to trash
for (var i = 0; i < threads.length; i++) {
if (threads[i].getLastMessageDate()<maxDate)
{
threads[i].moveToTrash();
}
}
}
Click File => Save
Make it work automatic: Click icon "Current project's triggers",
Click "Create new triger"
Setup AND SELECT intermediate time
Save

Gmail Api - Get Attachments

is it possible the get all the attachments for a specific message?
i only find a GET AttachmentById
First you get a list of your messages from a specific tag
var re = service.Users.Messages.List("me");
re.LabelIds = "Label_2";
re.Q = "is:unread";
var res = re.Execute();
Then you get the message through the id
foreach (var email in res.Messages)
{
GetAttachments(service, "me", email.Id, credPath);
}

Netsuite Past Due Reminder using SuiteScript

The script is complete! Thanks for all those who replied :)
/*
* Author: Laura Micek
* Date: 5-13-15
* Purpose: This script creates a saved search in order to pull the information needed to send out an email to alert customers that
* their account is past due. The saved searched makes sure that the customer is 11 days or more past due, checks to see if they are
* exempt from past due reminders, and that their account balance is greater than 1. Once the saved search runs, it will loop thru the
* customers that meet these requirements and it will use the days past due to determine if an email needs to be sent. An email will
* only be sent if the days past due are equal to 11 or if the days past due minus 11, modded by 8 equals 0 which means that it has
* been 8 days since the last notification.
*/
function email_late_customers(type) {
//variables
var send_from = 22730; // Internal ID of NS User
//setup filters and result columns for a customer saved search
var filters = new Array();
filters[0] = new nlobjSearchFilter('daysoverdue',null,'greaterthanorequalto',11);
filters[1] = new nlobjSearchFilter('custentitypastdueremind',null,'is', 'F');
filters[2] = new nlobjSearchFilter('balance',null,'greaterthan', 1);
var columns = new Array();
columns[0] = new nlobjSearchColumn('internalid');
columns[1] = new nlobjSearchColumn('email');
columns[2] = new nlobjSearchColumn('daysoverdue');
//run saved search and loop thru results
var customers = nlapiSearchRecord('customer',null,filters,columns);
for (var i = 0; customers != null && i < customers.length; i++) {
//grab all the customer data
var this_customer = customers[i];
var cust_id = this_customer.getValue('internalid');
var send_to = this_customer.getValue('email');
var getpastduedays = this_customer.getValue('daysoverdue');
//this is the check to see if the amount of days is over 11 to see if another email needs to be sent.
if(getpastduedays > 11) {
var checkPastDue = (getpastduedays - 11) % 8;
}
/*
if the above checkPastDues evaluates to zero then it has been 8 days since the last notification, this is the other condition to send an email. The first being that the customer is 11 days past due.
*/
if(getpastduedays == 11 || checkPastDue == 0) {
//email subject
var subject = 'Your Account is Past Due';
// create body text
var body = 'Hello, \r\r';
body += ' This is a reminder that your account is currently past due. Attached is a current detailed aging of your account for your reference.\r\r ';
body += ' Can you please review and let me know the status of payment?\r\r';
body += ' Your prompt attention to this matter would be greatly appreciated. If you have any questions reguarding this account, please ';
body += ' contact us as soon as possible. Any questions or invoice copy requests can be email to ar#doubleradius.com.\r\r';
body += ' If payment has been recently been made, please accept our thanks and ignore this reminder.\r\r';
body += 'Thank You!\r\r';
//setup filters and result columns for a transaction saved search
var filters = new Array();
filters[0] = new nlobjSearchFilter('status',null,'is', 'CustInvc:A');
filters[1] = new nlobjSearchFilter('type',null,'is', 'CustInvc');
filters[2] = new nlobjSearchFilter('email',null,'is', send_to);
filters[3] = new nlobjSearchFilter('mainline',null,'is', 'T');
var columns = new Array();
columns[0] = new nlobjSearchColumn('internalid');
//run saved search and loop thru results
var transactions = nlapiSearchRecord('transaction',null,filters,columns);
var invoices = [];
for (var i = 0; transactions != null && i < transactions.length; i++) {
//grab all the transaction data
var this_transaction = transactions[i];
invoices[i] = this_transaction.getValue('internalid');
}
//print the statement to a PDF file object
var attachment = [];
for (var i = 0; invoices != null && i < invoices.length; i++) {
attachment[i] = nlapiPrintRecord('TRANSACTION',invoices[i],'DEFAULT',null);
}
//send the PDF as an attachment
nlapiSendEmail(send_from,/*send_to*/ 'lauram#doubleradius.com', subject, body, null, null, null, attachment);
}
}
}
You don't need scripting to achieve this simple requirement. All you need is a saved search and a workflow. The key thing here is you need to come up with the right criteria on your saved search. Once you have the right saved search you set your workflow's Initiation to run on Scheduled and choose the frequency. Use the Send Email action to send the email to the customers and you are good to go.
Also, from the saved search you can join the customer record to the Messages Field so you will have the ability to check when was the last email sent.
You might also need a Email Template.
If you're going to use a Scheduled Script you will need to collect the records you want to inspect. If these are Customer records then be sure to setup searchFilters and searchColumns to come back and then collect the results.
// set Customer record filters and columns to return
var filters = new Array();
filters.push( new nlobjSearchFilter('isActive', null, 'is', 'F') );
filters.push( new nlobjSearchFilter('someotherfield', null, 'isempty') );
var cust_cols = new Array();
cust_cols.push( new nlobjSearchColumn('companyname') );
cust_cols.push( new nlobjSearchColumn('someotherfield') );
// now get the records that fit your filters and return the cols specified
overdue_customers = nlapiSearchRecord('customer', null, searchfilter, columns);
I generally like to move my content/body creating code into separate functions but it's really not that important depending on how complicated your script is. For instance I have a couple of scripts that do a lot of processing that have to send some information on a record by record basis but also sends "digest" type emails to others. Think customers and account managers. While it was a pain to set up everything up to handle both cases having a email content generating function was much saner and easier to read.
Though there are many approaches you could use for this, I think your scheduled script approach will work just fine. You can make the logic for identifying which emails to send by offloading the 8-day calculation to your search filters, instead of manually trying to compute. I would have a filter in my search of something like:
new nlobjSearchFilter('custentity_dayssincelastemailed', null, 'before', 'previousOneWeek');
See the Help article titled Search Date Filters for more details on what you can do with Dates in filters.
After that, I believe you should be able to create an Email Template and utilize that in your code to set the title and the boilerplate of the email body.
Where I'm a little less certain, and what may be more difficult for you, is your A/R Aging attachment. Not sure I've worked with attaching statements.

Creating spam filter for Gmail

I am so sick of getting unwanted mails in my gmail inbox that I am now willing to create a white-list kind of extension which filters all mails coming from people who are not in my contacts list. I searched for this many hours but could not find anything hence thinking of doing this exercise (if it exists, please share the link). I have created 100's of filters but definitely spammers outpace me everytime.
Can someone tell me whether this is possible in first place? I have seen extensions which add functionality in gmail but I don't know how to block an email through an extension. Plz help.
You can setup a whitelist in Gmail but it is unlikely to work for such a large list of addresses. What you can do is create a Google sheet with a list of valid addresses and a Google Script that will scan your inbox against these addresses.
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheets()[0];
var range = sheet.getDataRange();
var values = range.getValues();
var emails = [];
for (var i in values) {
emails.push(values[i][0]);
}
var threads = GmailApp.search("in:inbox is:unread");
for (var i=0; i<threads.length; i++) {
var from = threads[i].getMessages()[0].getFrom();
if ( !emails.indexOf(from) ) {
threads[i].moveToSpam();
}
}
You need to setup a trigger that runs this script every 5 minutes or so.
Thanks a lot Amit for sharing this snippet. With the help of this, I was able to come up with a working solution (ver1.0) and sharing below for others:
function createTriggers() {
ScriptApp.newTrigger('runSpamFilter').timeBased().everyMinutes(10).create();
SpreadsheetApp.getActiveSpreadsheet().toast("The program will check for spam email every 10 minutes and"
+ " send them to Spam Folder after applying label MySpam. You may please close this window.", "Initialized");
}
function removeTriggers(show) {
var triggers = ScriptApp.getScriptTriggers();
for (i=0; i<triggers.length; i++) {
ScriptApp.deleteTrigger(triggers[i]);
}
if (show) {
SpreadsheetApp.getActiveSpreadsheet().toast("The program has stopped.", "Uninstalled");
}
}
function runSpamFilter() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheets()[0];
var range = sheet.getDataRange();
var values = range.getValues();
var emails = [];
var regex = /([a-zA-Z0-9+._-]+#[a-zA-Z0-9._-]+\.[a-zA-Z0-9._-]+)/gi;
var my_label = GmailApp.getUserLabelByName("MySpam");
var spamCount = 0;
for (var i in values) {
emails.push(values[i][0]);
}
var threads = GmailApp.search("in:inbox is:unread");
for (var i=0; i<threads.length; i++) {
var from = threads[i].getMessages()[0].getFrom();
var from_email = from.match(regex);
if ( emails.indexOf(from_email[0]) == -1 ) {
threads[i].addLabel(my_label);
threads[i].moveToSpam();
spamCount++;
}
}
Logger.log("Spams found = %s", spamCount);
}
function startProgram() {
removeTriggers(false);
createTriggers();
}
function onOpen() {
var sheet = SpreadsheetApp.getActiveSpreadsheet();
var menu = [
{name: "Step 1: Initialize", functionName: "startProgram"},
{name: "Step 2: Start ", functionName: "runSpamFilter"},
{name: "Uninstall (Stop)", functionName: "removeTriggers"}
];
sheet.addMenu("Gmail Spam Filter v1.0", menu);
}
I may also come up with ver2.0 which removes the current limitation of this script. As of now, you have to make a spreadsheet having all your contacts email addresses. But once you add a new contact, this spreadsheet needs to be updated manually. Hence this script needs an additional trigger which would update the spreadsheet once in say 15 days with the recently added contacts/email addresses. I will share that too later or may be someone can pick from here and come up with ver2.0.
Thanks again.

Extra characters in end of string when using MQC MQMessage WriteString in C# CharacterSet 819 Encoding 273

I have a huge problem. Most of the time when I send a message to my customers message queue server there appears some "invisible" characters at the end of the message. The characters are only visible in my cutomers log, not in for example Notepad++. The last word in the message string is an email address, can it be the # who causes the trouble? I've got the message "Wrong email address" back from the MQ server. In the customers log the email address looks like this "fname.ename#address.se;XINT;" and other times like this "fname.ename#address.se;[[;" Here is my C# code:
var message = "some text some text some other text fname.ename#address.se ";
var corr = new byte[24];
for (var i = 0; i < 24; i++)
{
corr[i] = byte.Parse("20", System.Globalization.NumberStyles.HexNumber);
}
var mess = new MQMessage
{
ReplyToQueueName = queueRead,
CorrelationId = corr,
UserId = userId,
ApplicationIdData = userPwd,
CharacterSet = 819,
Encoding = 273,
Format = MQC.MQFMT_STRING
};
mess.WriteString(message);
var pmo = new MQPutMessageOptions();
queue.Put(mess, pmo);
The problem is solved! The specification I've got from the customer was incomplete. The length of last field in the message should be multiplicated with 7 which I didn't knew. But now I know!

Resources