MimeKit: How to delete an email by MessageId? - c#

I am using MailKit/MimeKit 1.2.7 (latest NuGet version).
Deleting an email with the ImapClient is pretty easy ...
client.Inbox.AddFlags(uniqueId, MessageFlags.Deleted, silent: true);
... if you know the emails UniqueId or its Index.
In my case, I don't know either one nor the other. All I have is the message itself (MimeMessage) ad its MessageId.
I was hoping that MessageId == UniqueId, but obviously this is not the case.
Do I have any chance to delete an email by just having the corresponding MimeMessage/MessageId?

You could try doing something like this:
var uids = folder.Search (SearchQuery.HeaderContains ("Message-Id", message.MessageId));
folder.AddFlags (uids, MessageFlags.Deleted, silent: true);
Ideally, though, you'd keep track of the UniqueId that you used to fetch the message so that you can just use that value.

Related

Fetched Emails not ordered when I use pop3

First I were Fetching emails by POP3 using this library OpenPop.Pop3 and it was working ok and it was returns emails ordered from last email to first email
but when I change the library to mailkit library the returned messages not ordered and couldn't know based on what mailkit order fetched emails
that's my code after I change to mailkit library
using (Pop3Client client = new Pop3Client())
{
// Connect to the server
client.Connect(hostname, port, useSsl);
client.AuthenticationMechanisms.Remove("XOAUTH2");
client.Authenticate((username), password);
int messageCount = client.Count;
// We want to download all messages
List<MimeMessage> allMessages = new List<MimeMessage>(messageCount);
for (int i = messageCount-1; i > 0; i--)
{
var msg = client.GetMessage(i);
allMessages.Add(msg);
}
}
by this way allmessages variable should contains emails ordered from last email to first email but that's not happened emails not ordered at all
although I were using the same authenticated email before with OpenPop.Pop3 and fetched emails were ordered
I don't know why they wouldn't be ordered for you since MailKit is not doing any kind of sorting.
That said, MailKit uses 0-based indexes while I suppose OpenPOP.NET must have used 1-based indexes, so your loop should make the following change:
for (int i = messageCount-1; i >= 0; i--)
{
var msg = client.GetMessage(i);
allMessages.Add(msg);
}
Perhaps this will produce the expected results?
Update: It turns out that MailKit was correctly downloading the messages in reverse order just as his code was trying to do (as mentioned in his follow-up question). The problem this user was facing is that his GMail account settings were only providing MailKit's Pop3Client with a subset of his total Inbox as is explained in Google's FAQ in the section titled "Emails aren't downloading correctly", where it states:
After you set up POP in your Gmail settings, your emails become available
in batches. It might take a while to see all your emails.
Note: Gmail downloads a copy of every email you send or receive, except
for emails in Chats, Spam, and Trash. To avoid duplicates, Gmail doesn't
download emails sent within your mail client, but you can still see them
if you log in to Gmail.
If you continue to have problems downloading emails, try using recent
mode:
In your email client's POP settings page, find the "Email address" or
"User name" field.
Add recent: in front of your email address. For example,
recent:example#gmail.com.
If that doesn't fix the problem, try deleting your Gmail address from your email client, then re-adding it.

EWS - Send Email With ConversationId (Not Reply)

I have a conversation going on between the user I'm logged in as on EWS, and some other user. I know the conversation Id. I want to send the other person a message that is a part of the same conversation. I want to make sure that the message has the same conversation Id. But, this is not a reply. I want to send a new email that is a part of the same conversation. How do I do this in c#? The ConversationId property of EmailMessage is read only.
This article is of no help:
https://msdn.microsoft.com/en-us/library/office/dn610351(v=exchg.150).aspx
Alternatively, I can actually get the latest email from the conversation from the server and reply using that with this code:
var latestConversationNode = _ExchangeService.GetConversationItems(conversationId, new PropertySet { ItemSchema.Id, ItemSchema.ConversationId }, null, null, ConversationSortOrder.DateOrderDescending).ConversationNodes.FirstOrDefault();
if (latestConversationNode != null)
{
var latestEmailInConversation = latestConversationNode.Items.FirstOrDefault() as EmailMessage;
if (latestEmailInConversation != null)
{
var replyMessage = latestEmailInConversation.CreateReply(false);
replyMessage.Body = body;
replyMessage.Subject = subject;
foreach (var toRecipient in toRecipients)
{
replyMessage.ToRecipients.Add(toRecipient);
}
replyMessage.SendAndSaveCopy();
return;
}
}
This works sometimes, but for some reason, sometimes the reply doesn't appear as a reply in my inbox. I.e. my mail client doesn't recognize it as being a part of the same conversation.
I guess that what is happening is that the last email received on the server is not actually from the email address that I am sending to, and therefore either Exchange or my mail client don't realise that it's part of the same conversation even though the conversation Id is the same.
What do you want to accomplish with this? And what do you mean with "not a reply". Is it a forward, a new message or something else?
From my understanding, messages must not only have the same conversationId to be in the same conversation, but also have the same conversationTopic and a plausible conversationIndex (which is something like the conversationId concatenated with the timestamps of the mail-reply-history).
If your mails get lost, you could take a look for inconsistencies in these two attributes.
Hope that helps.

EWS API get Sender name when Cc information is missing

In work we have service mailbox and suddenly started coming mails with attachement daily, no one know why and how to stop that and nobody need that.
So im writing deleting script and i dont know how to detect/find these emails, because Cc field is blank and email with same Subject from same email address is already coming but difference is between alias, how can i read information from the image ?
I need declare a SearchFilter like
SearchFilter subjectFilter =
new SearchFilter.ContainsSubstring(ItemSchema.?WHATHERE?, "JOBRUN <something#company.com>");
Thank you :-)
If I do understand you correctly, and based on your screenshot, you want to get those emails that have the string JOBRUN in their Display Name (not in their Subject as your variable name states).
Altough I'm not sure if the following does the filtering based on the email-address of the sender only or additionally based on the sender's displayname (the documentation is pretty poor...), you could try the following:
var filter = new SearchFilter.ContainsSubstring(EmailMessageSchema.Sender, "JOBRUN");

MailKit Delete single message from gmail

I am using MailKit (https://github.com/jstedfast/MailKit) to connect to google apps via imap, how can I delete a single message though ? (I am fine to have it moved to trash, just need it out of the inbox.
So far I have it connected, downloading, parsing links from message bodies. I just need this one last action to have what I need.
Thanks!
To delete a message from a folder on the IMAP server, this is all you need to do:
client.Inbox.AddFlags (new int[] { index }, MessageFlags.Deleted);
or
client.Inbox.AddFlags (new UniqueId[] { uid }, MessageFlags.Deleted);
Now the message is marked as \Deleted on the server.
You can then purge the folder of all deleted items by calling:
client.Inbox.Expunge ();
If you are using UIDs instead of indexes and the IMAP server supports the UIDPLUS extension (check the client.Capabilities), you can expunge just a selected set of messages like this:
if (client.Capabilities.HasFlag (ImapCapabilities.UidPlus))
client.Inbox.Expunge (new UniqueId[] { uid });

OpenPop - Gmail - GetMessageCount() returns 0 (zero)

When connecting to Gmail with OpenPop, I can only retrieve an email once, even if I do not delete it. Using GetMessageCount() I always receive 0 emails. How can I get all the emails that are there?
Only after reading them and processing them do I give order to delete. I am using the following code to get the emails:
using (var client = new Pop3Client())
{
// Connect to the server
client.Connect(serverData.Hostname, serverData.Port, serverData.UseSsl);
// Authenticate ourselves towards the server
client.Authenticate(serverData.Username, serverData.Password, AuthenticationMethod.UsernameAndPassword);
var emailAmount = client.GetMessageSizes().Count;
// Fetch all the current uids seen
var msgCount = client.GetMessageCount();
.....
}
Gmail is special. Take a look at this StackOverflow post which explains the non-standard behavior.
What you are interested in, is that Gmail will only show a message in ONE POP3 session, unless you do special stuff, like prepending recent: in front of your username.
Getting only the unread mails is how POP3 is supposed to work. If you want to see and manage older mails, you should use IMAP instead.

Categories