Gmail Api - Get Attachments - gmail

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

Related

Search for emails in MailKit not with the SearchQuery method but with simple text string criterias

Mailkit.SearchQuery provides a very powerful search system for finding emails with various parameters. But I want to make a research getting the criteria from a simple text string, to give the user the capability to do complex search by his own.
So I DONT'T want to do this:
var query = SearchQuery.DeliveredAfter(DateTime.Parse("2021-10-06"))
.And(SearchQuery.FromContains("mailer-daemon#myprovider.it"));
but I want to do this:
string query = "SENTSINCE 2021-10-06 FROM mailer-daemon#myprovider.it";
The problem is that inbox is ImailFolder object (which doesn't have Search method with simple text string parameter overload) and not ImapFolder object (which instead got it!).
How can I do?
static void ReadMsgs(Options opts)
{
using (var client = new ImapClient(new ProtocolLogger("imap.log")))
{
client.Connect(opts.Host, opts.Port, opts.UseSSL);
client.Authenticate(opts.UserName, opts.Password);
var inbox = client.Inbox;
inbox.Open(FolderAccess.ReadOnly);
Console.WriteLine("Total messages: {0}", inbox.Count);
Console.WriteLine("Recent messages: {0}", inbox.Recent);
// let's try searching for some messages...
Console.WriteLine("Search in progress...");
// this is a functional query based on SearchQuery
//var query = SearchQuery.DeliveredAfter(DateTime.Parse("2021-10-06"))
// .And(SearchQuery.FromContains("mailer-daemon#myprovider.it"));
// this is the code I would like to integrate based on a IMAP UID SEARCH text string
//string query = "SENTSINCE 2021-10-06 FROM mailer-daemon#myprovider.it";
foreach (var uid in inbox.Search(query))
{
var message = inbox.GetMessage(uid);
Console.WriteLine("{0}|{1}|{2}|{3}|{4}", uid, message.Date, message.From, message.To,message.Subject);
}
client.Disconnect(true);
}
}
You can just cast from the IMailFolder to the ImapFolder.
var inbox = (ImapFolder) client.Inbox;
All IMailFolders returned by the ImapClient are ImapFolders.

How to get a list of internal id in netsuite

Is there a proper way to get a list of all internal id in a Netsuite Record?
var record = nlapiLoadRecord('customer', 1249);
var string = JSON.stringify(record);
nlapiLogExecution('DEBUG', 'string ', string );
I can get most of the id using json string but i am looking for a proper way. It prints all the data including internal id. Is there any Api or any other way ?
I actually developed a Chrome extension that displays this information in a convenient pop-up.
I ran into the same issue of nlobjRecord not stringifying properly, and what I ended up doing was manually requesting and parsing the same AJAX page NS uses internally when you call nlapiLoadRecord()
var id = nlapiGetRecordId();
var type = nlapiGetRecordType();
var url = '/app/common/scripting/nlapihandler.nl';
var payload = '<nlapiRequest type="nlapiLoadRecord" id="' + id + '" recordType="' + type + '"/>';
var response = nlapiRequestURL(url, payload);
nlapiLogExecution('debug', response.getBody());
You can have a look at the full source code on GitHub
https://github.com/michoelchaikin/netsuite-field-explorer/
The getAllFields() function will return an array of all field names, standard and custom, for a given record.
var customer = nlapiLoadRecord('customer', 5069);
var fields = customer.getAllFields();
fields.forEach(function(field) {
nlapiLogExecution('debug', field);
})

Gmail script forward without attachment

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.

Email template netsuite

I have really big problem, i mean im working in a company where we are using NetSuite as our business platform and now they updated our account with new APIs.
Developer before me wrote this code
for(var k = 0; k < ResultsPPCI.length; k++){
EmployeePPCI = ResultsPPCI[k].getValue('internalid'); //get the value
// log('Internal ID', EmployeePPCI);
// Merge, send, and associate an email with Purchase Order record (id=1000)
var mergeValuesPPCI = {};
mergeValuesPPCI.NLEMPFIRST = nlapiLookupField('employee', EmployeePPCI, 'firstname');
mergeValuesPPCI.NLEMPLAST = nlapiLookupField('employee', EmployeePPCI, 'lastname');
mergeValuesPPCI.NLSUPPLIER = nlapiLookupField('customer', cust, 'companyname');
mergeValuesPPCI.NLPRODUCTCODE = productcodehtml;
var emailBodyPPCI = nlapiMergeRecord(65, 'purchaseorder', poID, null, null, mergeValuesPPCI);
var recordsPPCI = {};
recordsPPCI['transaction'] = poID;
nlapiSendEmail(EmployeePPCI, EmployeePPCI, emailBodyPPCI.getName(), emailBodyPPCI.getValue(), null, null, recordsPPCI);
// log('EmployeePPCI',EmployeePPCI);
nlapiLogExecution('AUDIT', 'Potentional Problem', 'Email Sent');
}
I have problem now because nlapiMergeRecord is deprecated and it wont work. But i really cant find any working example online for hours... The most important part here is actually body of this email that has to be sent. In this case it is productcodehtml or mergeValuesPPCI.NLPRODUCTCODE.
This is how my template looks like :
<p>The QA Release has been submitted by <nlsupplier> for ${transaction.tranId}.</nlsupplier></p>
<p>The following item(s) have a short shelf life:</p>
<nlproductcode></nlproductcode>
Please can you help me with converting this code to new method? How can i connect nlproductcode from template with mergeValuesPPCI.NLPRODUCTCOD from my code?
Thanks in advance!
You can use kotnMergeTemplate as a drop in replacement for nlapiMergeRecord
e.g.:
kotnMergeTemplate(65, 'purchaseorder', poID, null, null, mergeValuesPPCI);
the nlobjEmailMerger does not take custom values so you'd have to post process the results. Again you can look at the example in my script where you'd get the merged string and then run:
var oldCustFieldPatt = /<(nl[^ >]+)>(\s*<\/\1>)?/ig;
content = content.replace(oldCustFieldPatt, function(a,m){
return mergeValuesPPCI[m.toUpperCase()] || mergeValuesPPCI[m.toLowerCase()] || '';
});
You can use the new nlapiCreateEmailMerger(templateId)
First you need to create your email template in netsuite and get the internal id.
Then:
Use nlapiCreateEmailMerger(templateId) to create an nlobjEmailMerger object.
var emailMerger = nlapiCreateEmailMerger(templateId);
Use the nlobjEmailMerger.merge() method to perform the mail merge.
var mergeResult = emailMerger.merge();
Use the nlobjMergeResult methods to obtain the e-mail distribution’s subject and body in string format.
var emailBody = mergeResult.getBody();
Send your email
nlapiSendEmail(senderInternalId, 'receiver#email.com','subject',emailBody, null, null, null);
Good luck!

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.

Resources