Mailkit:获取消息并将其复制到MySQL,驱动器附件

时间:2017-10-30 07:54:33

标签: c# mysql imap mailkit mailsystem.net

到目前为止,我一直在使用this code MailSystem.Net从Imap INBOX获取电子邮件,并添加了使用$"SENTSINCE {Date}"检索邮件的选项。

string mailBox = "INBOX";
public IEnumerable<Message> GetMailsSince(string mailBox) {
  return GetMails(mailBox, $"SENTSINCE {DateTime.Now.AddDays(-3).ToString("dd-MMM-yyyy")}").Cast<Message>();
}

private MessageCollection GetMails(string mailBox, string searchPhrase) {
  Mailbox mails = Client.SelectMailbox(mailBox);
  MessageCollection messages = mails.SearchParse(searchPhrase);
  return messages;
}

但即使在研究mailkit数小时后,我似乎无法提炼出如何做同样的事情。我的目标是获取一个消息对象列表,然后我可以将其属性映射到我创建的另一个类,该类将其写入mysql数据库。我还想将附件保存到磁盘。到目前为止,这一切都很好,但性能是一个问题。我希望mailkit能够大大改善这一点。

我的主要来源是the sample here,但由于我不熟悉异步编程和树视图,因此很难看清它。

我怎样才能将我想要的“INBOX”硬编码为“IMFolder”? 我在哪里或如何使用Mailkit中的“SENTSINCE {Date}”过滤器? 如何在邮件系统中获得与“邮件”对象相同的“无法”的Mailkits(可能是“IMessageSummary”)?

如果您可以指向我一些代码,甚至将链接的MailSystem.Net示例转换为Mailkit,这将是非常棒的。

2 个答案:

答案 0 :(得分:2)

MimeMessage is the equivalent of MailSystem.NET's Message object, but that's not what you want. What you want is MailKit's IMessageSummary which will allow you to download individual MIME parts (aka "attachments").

It also allows you to get summary information about the message (flags, received date (aka "InternalDate") pre-parsed/decoded common header values (such as subject, sender, recipients, etc) really quickly because the IMAP server has those pieces of information cached in its database for quick retrieval.

using (var client = new ImapClient ()) {
    client.Connect ("imap.mail-server.com", 993, SecureSocketOptions.SslOnConnect);
    client.Authenticate ("username", "password");

    // if you don't care about modifying message flags or deleting
    // messages, you can open the INBOX in read-only mode...
    client.Inbox.Open (FolderAccess.ReadOnly);

    // search for messages sent since a particular date
    var uids = client.Inbox.Search (SearchQuery.SentAfter (date));

    // using the uids of the matching messages, fetch the BODYSTRUCTUREs
    // of each message so that we can figure out which MIME parts to
    // download individually.
    foreach (var item in client.Inbox.Fetch (uids, MessageSummaryItems.BodyStructure MessageSummaryItems.UniqueId)) {
        foreach (var attachment in item.Attachments.OfType<BodyPartBasic> ()) {
            var part = (MimePart) client.Inbox.GetBodyPart (item.UniqueId, attachment);

            using (var stream = File.Create (part.FileName))
                part.ContentObject.DecodeTo (stream);
        }
    }
}

Note: Each property on IMessageSummary has a corresponding MessageSummaryItems enum value that you will need to use in order to have that property populated.

For example, if you want to use IMessageSummary.Envelope, you will need to include MessageSummaryItems.Envelope in your Fetch() request.

Since MessageSummaryItems is marked with the [Flags] attribute, you can bitwise-or enum values together like this:

MessageSummaryItems.BodyStructure | MessageSummaryItems.Envelope and both pieces of information will be fetched.

Update:

Here's the inefficient way that is closer to how MailSystem.NET does it.

using (var client = new ImapClient ()) {
    client.Connect ("imap.mail-server.com", 993, SecureSocketOptions.SslOnConnect);
    client.Authenticate ("username", "password");

    // if you don't care about modifying message flags or deleting
    // messages, you can open the INBOX in read-only mode...
    client.Inbox.Open (FolderAccess.ReadOnly);

    // search for messages sent since a particular date
    var uids = client.Inbox.Search (SearchQuery.SentAfter (date));

    // using the uids of the matching messages, fetch the BODYSTRUCTUREs
    // of each message so that we can figure out which MIME parts to
    // download individually.
    foreach (var uid in uids) {
        var message = client.Inbox.GetMessage (uid);

        foreach (var attachment in message.Attachments.OfType<MimePart> ()) {
            using (var stream = File.Create (attachment.FileName))
                attachment.ContentObject.DecodeTo (stream);
        }
    }
}

Note: if you care about saving message/rfc822 attachments, then take a look at this StackOverflow answer: MailKit save Attachments

答案 1 :(得分:1)

“收件箱”文件夹始终可用于IMAP邮件帐户。使用MailKit,它可以ImapClient.Inbox获得。对于日期过滤,您可以使用DateSearchQuery类。 MailKit的入门页面几乎涵盖了您的所有问题。