I'm working with MailKit lib and have a problem.
My application is read specify email in Inbox (Gmail), and delete them.
IList<UniqueId> listUid = inbox.Search(query);
for (int i = 0; i < listUid.Count; i++)
{
var message = inbox.GetMessage(listUid[i]);
inbox.AddFlags(msg.Uid, MessageFlags.Deleted, true);
inbox.Expunge();
}
It run OK, But when Gmail setting Conversation View = Conversation view on, the message that marked as deletion will comback in Inbox if have same email subject and same sender. In next-time I count message, all of deletion message will be re-count. How to avoid it? (save Uid of deletion message is one way but when message number increase, processing will be slow)
Thanks very much.
GMail unfortunately does not behave the same way most other IMAP servers behave and so when you mark a message as \Deleted, it gets moved to the Trash folder automatically and so the Expunge does nothing.
What you need to do is go to your GMail settings and change the behavior of your IMAP account so that it doesn't move the messages to Trash.
Either that or MoveTo() the message to the Trash folder yourself so you can get the UID of the message in the Trash folder (hint: use the return value of the MoveTo() method) and then open the Trash folder and expunge the message from there.
Note: this code is untested, but it should look something like this:
var trash = client.GetFolder (SpecialFolder.Trash);
var moved = client.Inbox.MoveTo (uid, trash);
if (moved.HasValue) {
trash.Open (FolderAccess.ReadWrite);
trash.AddFlags (moved.Value, MessageFlags.Deleted, true);
trash.Expunge (new [] { moved.Value });
}
Related
I wrote a simple VSTO addin for Outlook 2016(part of office 365) to check if there is some email addresses outside our company are mixed in the recipients list.
I simplified the code like below:
int countExternalAddress;
string externalAddresses;
string internalDomain=“#example.com”;
//indicates the email domain of our company, we use exchange server.
private void Application_ItemSend(object Item, ref bool Cancel)
{
countExternalAddress = 0;
externalAddresses="";
Outlook.MailItem item = (Outlook.MailItem)Item;
foreach (Outlook.Recipient recp in item.Recipients)
{
ConvertExchangeAddrToSMTPAddr(recp.AddressEntry.Address);
//by access ExchangeUser.PrimarySmtpAddress
CheckTheAddress(recp.AddressEntry.Address);
}
if (countExternalAddress > 0)
{
Warn();
}
}
The code works with no problem most of time, but some times Warn() function shows warnings based on (part of) the recipients of the LAST email, not the CURRENT one.
The problem cannot be reproduced all the time, but when it occurs, the procedure is like:
Send an email to internal recipients(my colleagues, exchange addresses), the exchange addresses are successfully converted to SMTP address, because they are predefined as "internal" address, the mail will be sent without warning.
send another email to some other internal recipients, the program shows warning of "external address mixed", and the "external" address are from the previously sent email(mentioned in 1 above, not all addresses just one of them), and, the detected external address is in Exchange address format which is supposed to be converted to SMTP format.
Strangely, I cannot find the address in the recipients list of the current email.
If I save the current email and restart outlook, when I pick the saved email and try to resend it, no such "external" address will be detected again.
It looks like the Item object passed by ItemSend event contains some recipient(s) not only belong to the current email but also from the previously sent one, but they are not visible in the current email, moreover I cannot find such recipients in the sent email as well.
The work PC I am using doesn't have debug environment so I am running out of means. Please give me your helps, thanks in advance.
Could it have anything to do with you doing >
if (countExternalAddress > 0)
{
Warn();
}
and not ==
if (countExternalAddress == 0)
{
Warn();
}
Seems odd but it would leave one more email to warn you about.
I'm trying to read emails from specific Gmail account. I have found something here(Stackoverflow) but I can't manage reading the emails.
this is what I'm using:
public static void logingmail()
{
// Connect to the IMAP server. The 'true' parameter specifies to use SSL
// which is important (for Gmail at least)
ImapClient ic = new ImapClient("imap.gmail.com", "Any#gmail.com", "4521945219",AuthMethods.Login, 993, true);
// Select a mailbox. Case-insensitive
ic.SelectMailbox("Inbox");
string countmessages = ic.GetMessageCount().ToString();
// Get the first *11* messages. 0 is the first message;
// and it also includes the 10th message, which is really the eleventh ;)
// MailMessage represents, well, a message in your mailbox
MailMessage[] mm = ic.GetMessages(0, 10);
foreach (MailMessage m in mm)
{
var subject = m.Subject.ToString();
}
// Probably wiser to use a using statement
ic.Dispose();
}
The problem I'm experiencsing probably happening when I'm first creating the new ImapCliient class. for some reason it's opening a browse path to choose a file(?).
I'll be happy for some assistance.
Thanks
You should use the solution of the second post of the topic were you have found something, S22.Imap.
(Here you can find a compiled version).
After download, you can read the documentation. It is simple and readable.
Actually, I use this library and that works well !
I have the problem that when i add a custom UserProperty to an Outlook MailItem, it does not get synced to other connected Outlooks.
What can i do to force Outlook to sync the whole email?
My overal problem:
I've got a shared Exchange Mailbox, opened on two clients (in Outlook)
I would like to lock a mail item, if it gets opened in one Outlook and show the second Outlook user a message like "The user XX is currently reading this email"
My way to solve the problem:
Creating a Outlook Plugin.
When user "A" is opening the Email, I am adding a "LockingUser" UserProperty to the MailItem object. If user "B" is trying to open the Email, I am first looking if a "LockingUser" Property exists.
I have disabled the cached mode.
I have tried to update the subject of the email: this works perfectly and gets synced immediatly (but is not a solution for my problem)
private void SetLockingUser(Outlook.MailItem mail)
{
var lockingUserProperty = mail.UserProperties.Find("LockingUser");
if (lockingUserProperty != null)
{
MessageBox.Show("Email locked by: " + lockingUserProperty.Value);
return;
}
var identity = System.Security.Principal.WindowsIdentity.GetCurrent();
var username = identity != null ? identity.Name : "";
lockingUserProperty = mail.UserProperties.Add("LockingUser", Outlook.OlUserPropertyType.olText, false, 1);
lockingUserProperty.Value = username;
mail.Save();
}
Please show the relevant snippet of your code and make sure you call MailItem.Save. Also keep in mind that there will always be lag since the changes will take up to a couple minutes to sync to Exchange and then to another user if cached mode is used. You'd be better off using some external sync mechanism instead of a user property.
I am trying to move a message to another folder in a mail box using the IMAP functionality of ae.net.mail. The problem is that although the message is moved into the target folder, it is not removed from INBOX.
I'm also having a problem deleting a message. In this case I'm finding that the status of the message merely changes from unseen to seen.
Here is what I have tried:
using (ImapClient ic = new ImapClient(
host, email, password, ImapClient.AuthMethods.Login, 993, true))
{
ic.SelectMailbox("INBOX");
string[] uids = ic.Search(SearchCondition.From("someone#gmail.com"));
MailMessage[] messages =
ic.GetMessages(uids[0], uids[uids.Length - 1], false);
ic.MoveMessage(uids[0], "Junk");
}
The standard IMAP protocol does not have a MOVE command (but there is an extension that adds it). So, depending on your IMAP server, the client may need to implement MOVE as a UID COPY + UID STORE +FLAGS.SILENT (\Deleted) + UID EXPUNGE, but that assumes that the server supports the UIDPLUS extension. If the server doesn't support UIDPLUS, either, then it becomes essentially impossible to implement properly. All you can do is COPY + STORE +FLAGS.SILENT (\Deleted) but cannot do the EXPUNGE because there's no way to limit the messages that will get expunged (I suppose you could unmark any other deleted messages, then EXPUNGE, then re-mark them as \Deleted, but that starts to become risky).
This would explain why the messages might still exist in the INBOX (although they should be at least marked as deleted).
Not sure why marking a message as deleted is marking it as Seen. That seems like a bug in AE.NET.Mail.
Does anyone know a way to execute a bulk dump of every email of a gmail account and write the emails to a file?
I'm looking to write a program that would let users back up there gmail (probably via imap) and back it up to either individual files or as a pst (I know pst will probably be much harder)
some time ago I wrote a blog post about exactly same topic. See HOWTO: Download emails from a GMail account in C# for details.
Code uses our Rebex Mail component:
using Rebex.Mail;
using Rebex.Net;
...
// create the POP3 client
Pop3 client = new Pop3();
try
{
// Connect securely using explicit SSL.
// Use the third argument to specify additional SSL parameters.
Console.WriteLine("Connecting to the POP3 server...");
client.Connect("pop.gmail.com", 995, null, Pop3Security.Implicit);
// login and password
client.Login(email, password);
// get the number of messages
Console.WriteLine("{0} messages found.", client.GetMessageCount());
// -----------------
// list messages
// -----------------
// list all messages
ListPop3MessagesFast(client); // unique IDs and size only
//ListPop3MessagesFullHeaders(client); // full headers
}
finally
{
// leave the server alone
client.Disconnect();
}
public static void ListPop3MessagesFast(Pop3 client)
{
Console.WriteLine("Fetching message list...");
// let's download only what we can get fast
Pop3MessageCollection messages =
client.GetMessageList(Pop3ListFields.Fast);
// display basic info about each message
Console.WriteLine("UID | Sequence number | Length");
foreach (Pop3MessageInfo messageInfo in messages)
{
// display header info
Console.WriteLine
(
"{0} | {1} | {2} ",
messageInfo.UniqueId,
messageInfo.SequenceNumber,
messageInfo.Length
);
// or download the whole message
MailMessage mailMessage = client.GetMailMessage(messageInfo.SequenceNumber);
}
}
Gmail provides POP access. So just use any library that allows you to communicate using POP and you're golden.
Edit: I just noticed that you mentioned IMAP; I recommend you use POP instead for bulk dumps. IMAP is too chatty for what you want to do.
If you must use IMAP, here's a library for you.
You can use fetchmail from a Unix environment to create an mbox file.
http://lifehacker.com/software/gmail/geek-to-live--back-up-gmail-with-fetchmail-235207.php
There is an open-source Python program compiled to Windows (using py2exe) at
https://github.com/jay0lee/got-your-back/wiki
But Mac users would need to compile it (which I haven't completely figured out due to a py2exe error).
Either way, you also need a way to execute the program automatically in a schedule.