Reading emails from Gmail in C#
Solution 1
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,
"[email protected]",
"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, "[email protected]", "YOURPASSWORDHERE");
var allEmails = mailRepository.GetAllMails();
foreach(var email in allEmails)
{
Console.WriteLine(email);
}
Assert.IsTrue(allEmails.ToList().Any());
}
Solution 2
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 {
System.Net.WebClient objClient = new System.Net.WebClient();
string response;
string title;
string summary;
//Creating a new xml document
XmlDocument doc = new XmlDocument();
//Logging in Gmail server to get data
objClient.Credentials = new System.Net.NetworkCredential("Email", "Password");
//reading data and converting to string
response = Encoding.UTF8.GetString(
objClient.DownloadData(@"https://mail.google.com/mail/feed/atom"));
response = response.Replace(
@"<feed version=""0.3"" xmlns=""http://purl.org/atom/ns#"">", @"<feed>");
//loading into an XML so we can get information easily
doc.LoadXml(response);
//nr of emails
var nr = doc.SelectSingleNode(@"/feed/fullcount").InnerText;
//Reading the title and the summary for every email
foreach (XmlNode node in doc.SelectNodes(@"/feed/entry")) {
title = node.SelectSingleNode("title").InnerText;
summary = node.SelectSingleNode("summary").InnerText;
}
} catch (Exception exe) {
MessageBox.Show("Check your network connection");
}
Solution 3
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;
.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.
Seany84
Updated on June 02, 2020Comments
-
Seany84 almost 4 years
I am trying to read emails from Gmail. I have tried every API / open source project I can find, 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
-
Seany84 almost 13 yearsThanks, somehow I managed to try every C# non-working POP3 email client :) thanks
-
Seany84 almost 13 yearsI have no budget to pay for this as there are open-source and free alternatives available.
-
Eric over 10 yearsThe only problem with this approach, and it's important to many people, is that you can't get the full text of the message body via the ATOM route.
-
E-Riddie over 10 yearsThere is another method of getting the route of ATOM with XML. You just have to create a namespace for XML form and you can access it easily! Read about that and you will understand because its no difference from this! :)
-
Kiquenet over 10 yearsany free version, not premium? Any open source alternative ?
-
newman over 9 yearsJust tried your code, it compiles okay. But when I try to run, it got stuck for more than 5 minutes at the line mails.SearchParse(searchPhrase) via call GetUnreadMails. I only have 53 unread emails in my inbox. Any explanation?
-
Seany84 over 9 yearsI have not used this code since around the time of the OP. However, I fired up my unit test and it did retrieve my unreal emails (count=12). Test took approximately 66 seconds to run.
-
Gurpreet Singh over 7 yearsI have build the console application in c# using above code, everything fixed but gmail not allowing to login. Here is my error message:- ** failed : * NO [WEBALERT accounts.google.com/signin/… Web login required. 161116082452398 NO [ALERT] Please log in via your web browser: support.google.com/mail/accounts/answer/78754 (Failure)**
-
Kjensen about 7 yearsIn order for this to work, you need to enable "Less secure apps" with your gmail account, if that is an option for you. I did that, and now the code works. Read more here: google.com/settings/security/lesssecureapps
-
Nulle over 6 yearsThen please illustrate how you would retrieve the message body.
-
Nulle over 6 yearsI have copy pasted your code. Exception thrown: 'System.IndexOutOfRangeException' in ActiveUp.Net.Imap4.dll when it tries get mail via GetAllMails("inbox");
-
Nulle over 6 yearswhat is ? IMailRepository. Mailkit does not have that Interface.
-
Seany84 over 6 years@Nulle This was from my code base. You can remove that interface for your own use-case.
-
Bengi Besçeli over 6 yearsnr is undefined
-
Toolkit over 5 yearscan I limit GetAllMails by date?
-
Seany84 over 5 years@Toolkit Yes, it is definitely possible. You should really post a different question on this site though.
-
Mr. B about 5 yearsLove your answer - Does every single thing need a NuGet package to be viable these days. Is that what we've become :(
-
MohaMad over 4 years@Seany84 thanks for your nice sample codes. I tried to use
MailSystem.NET
, but has error on Client.Log() : BAD Too many arguments provided . My password contains spaces and this login fails! -
Yijun Yuan over 4 yearsI got a 401 Unauthorized error. How should I fix that?
-
Albert Arul prakash about 4 yearsanother problem with this model is that, you cannot get entire mailbox information. max 20 email details. No more than that.
-
Ashok kumar Ganesan almost 4 yearsWhen I try to read the UnreadEmail I get the exception on GetMail method with exception like index out of exception