开发者

Reading emails from Gmail in C#

开发者 https://www.devze.com 2023-03-28 04:36 出处:网络
I am trying to read emails from Gmail. I have tried every API / open source project I can fin开发者_如何学运维d,and can not get any of them working.

I am trying to read emails from Gmail. I have tried every API / open source project I can fin开发者_如何学运维d, and can not get any of them working.

Does anyone have a sample of working code that will allow me to authenticate and download emails from a Gmail account?

Final working version posted below: https://stackoverflow.com/a/19570553/550198


Using the library from: https://github.com/pmengal/MailSystem.NET

Here is my complete code sample:

Email Repository

using System.Collections.Generic;
using System.Linq;
using ActiveUp.Net.Mail;

namespace GmailReadImapEmail
{
    public class MailRepository
    {
        private Imap4Client client;

        public MailRepository(string mailServer, int port, bool ssl, string login, string password)
        {
            if (ssl)
                Client.ConnectSsl(mailServer, port);
            else
                Client.Connect(mailServer, port);
            Client.Login(login, password);
        }

        public IEnumerable<Message> GetAllMails(string mailBox)
        {
            return GetMails(mailBox, "ALL").Cast<Message>();
        }

        public IEnumerable<Message> GetUnreadMails(string mailBox)
        {
            return GetMails(mailBox, "UNSEEN").Cast<Message>();
        }

        protected Imap4Client Client
        {
            get { return client ?? (client = new Imap4Client()); }
        }

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

Usage

[TestMethod]
public void ReadImap()
{
    var mailRepository = new MailRepository(
                            "imap.gmail.com",
                            993,
                            true,
                            "yourEmailAddress@gmail.com",
                            "yourPassword"
                        );

    var emailList = mailRepository.GetAllMails("inbox");

    foreach (Message email in emailList)
    {
        Console.WriteLine("<p>{0}: {1}</p><p>{2}</p>", email.From, email.Subject, email.BodyHtml.Text);
        if (email.Attachments.Count > 0)
        {
            foreach (MimePart attachment in email.Attachments)
            {
                Console.WriteLine("<p>Attachment: {0} {1}</p>", attachment.ContentName, attachment.ContentType.MimeType);
            }
        }
    }
}

Another example, this time using MailKit

public class MailRepository : IMailRepository
{
    private readonly string mailServer, login, password;
    private readonly int port;
    private readonly bool ssl;

    public MailRepository(string mailServer, int port, bool ssl, string login, string password)
    {
        this.mailServer = mailServer;
        this.port = port;
        this.ssl = ssl;
        this.login = login;
        this.password = password;
    }

    public IEnumerable<string> GetUnreadMails()
    {
        var messages = new List<string>();

        using (var client = new ImapClient())
        {
            client.Connect(mailServer, port, ssl);

            // Note: since we don't have an OAuth2 token, disable
            // the XOAUTH2 authentication mechanism.
            client.AuthenticationMechanisms.Remove("XOAUTH2");

            client.Authenticate(login, password);

            // The Inbox folder is always available on all IMAP servers...
            var inbox = client.Inbox;
            inbox.Open(FolderAccess.ReadOnly);
            var results = inbox.Search(SearchOptions.All, SearchQuery.Not(SearchQuery.Seen));
            foreach (var uniqueId in results.UniqueIds)
            {
                var message = inbox.GetMessage(uniqueId);

                messages.Add(message.HtmlBody);

                //Mark message as read
                //inbox.AddFlags(uniqueId, MessageFlags.Seen, true);
            }

            client.Disconnect(true);
        }

        return messages;
    }

    public IEnumerable<string> GetAllMails()
    {
        var messages = new List<string>();

        using (var client = new ImapClient())
        {
            client.Connect(mailServer, port, ssl);

            // Note: since we don't have an OAuth2 token, disable
            // the XOAUTH2 authentication mechanism.
            client.AuthenticationMechanisms.Remove("XOAUTH2");

            client.Authenticate(login, password);

            // The Inbox folder is always available on all IMAP servers...
            var inbox = client.Inbox;
            inbox.Open(FolderAccess.ReadOnly);
            var results = inbox.Search(SearchOptions.All, SearchQuery.NotSeen);
            foreach (var uniqueId in results.UniqueIds)
            {
                var message = inbox.GetMessage(uniqueId);

                messages.Add(message.HtmlBody);

                //Mark message as read
                //inbox.AddFlags(uniqueId, MessageFlags.Seen, true);
            }

            client.Disconnect(true);
        }

        return messages;
    }
}

Usage

[Test]
public void GetAllEmails()
{
    var mailRepository = new MailRepository("imap.gmail.com", 993, true, "YOUREMAILHERE@gmail.com", "YOURPASSWORDHERE");
    var allEmails = mailRepository.GetAllMails();

    foreach(var email in allEmails)
    {
        Console.WriteLine(email);
    }

    Assert.IsTrue(allEmails.ToList().Any());
}


You don't need any extra 3rd Party Libraries if a summary of the 20 most recent emails is sufficient for you. You can read the data from API that Gmail has provided here: https://mail.google.com/mail/feed/atom

The response in XML format can be handled by the code below:

try {
    const string emailAddress = "YourEmail";
    // App Password, not password
    // See: https://support.google.com/accounts/answer/185833?hl=en
    const string appPassword = "YourAppPassword";

    string response;
    string title;
    string summary;
    XmlDocument xmlDocument = new XmlDocument();

    HttpClient httpClient = new HttpClient();

    // Logging in Gmail server to get data
    httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(Encoding.UTF8.GetBytes($"{emailAddress}:{appPassword}")));

    // Reading data and converting to string
    response = await httpClient.GetStringAsync(@"https://mail.google.com/mail/feed/atom");

    // Remove XML namespace to simplify parsing/selecting nodes
    response = response.Replace(@"<feed version=""0.3"" xmlns=""http://purl.org/atom/ns#"">", @"<feed>");

    // Loading into an XML so we can get information easily
    xmlDocument.LoadXml(response);

    // Amount of emails
    string nr = xmlDocument.SelectSingleNode(@"/feed/fullcount").InnerText;

    // Reading the title and the summary for every email
    foreach (XmlNode node in xmlDocument.SelectNodes(@"/feed/entry")) {
        title = node.SelectSingleNode("title").InnerText;
        summary = node.SelectSingleNode("summary").InnerText;

        Console.WriteLine($"> {title}");
        Console.WriteLine($"{summary}");
        Console.WriteLine();
    }
} catch (Exception ex) {
    MessageBox.Show($"Error retrieving mails: {ex.Message}");
}


Have you tried POP3 Email Client with full MIME Support ?

If you don't it's a very good example for you. As an alternativ;

OpenPop.NET

.NET class library in C# for communicating with POP3 servers. Easy to use but yet powerful. Includes a robust MIME parser backed by several hundred test cases. For more information, visit our project homepage.

Lumisoft


You can also try Mail.dll IMAP client.

It supports all Gmail IMAP protocol extensions:

  • Thread ID,
  • Message ID,
  • Labels,
  • Localized folder names,
  • Google search syntax
  • OAuth authentication.

Please note that Mail.dll is a commercial product, I've developed.

0

精彩评论

暂无评论...
验证码 换一张
取 消