In this article I will describe how you can use C# and MailSystem.NET to read mails from any IMAP source, including GMail.
MailSystem.NET is a Open Source, GNU Library General Public Licensed library for managing emails using SMTP, POP3, IMAP and many more protocols.
I needed a component that will read mails from an IMAP source and import them into Sitecore. So I built this simple repository to get me all mails from a certain mailbox. Here is how I did it.
First you need to copy ActiveUp.Net.Common.dll and ActiveUp.Net.Imap4.dll from the MailSystem.NET package to your /bin/ folder.
Reading from MailSystem.NET is pretty straight forward:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using ActiveUp.Net.Mail; namespace PT.MailIntegration.IMAP { public class MailRepository { private Imap4Client _client = null; 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 { if (_client == null) _client = new Imap4Client(); return _client; } } private MessageCollection GetMails(string mailBox, string searchPhrase) { Mailbox mails = Client.SelectMailbox(mailBox); MessageCollection messages = mails.SearchParse(searchPhrase); return messages; } } }
This repository can now be used to read all mails or all unread mails from a mailbox. The constructor takes the mail server name, port and SSL information, as well as the email address and password of the account to read from. GetAllMails() read all mails from the specified mailbox, while GetUnreadMails() reads all unread mails. Both functions returns a list of Message objects. A Message is the complete email in one object.
To read from a GMail mailbox you need to connect using SSL on port 993:
using ActiveUp.Net.Mail; using PT.MailIntegration.IMAP; protected void TestMail() { MailRepository rep = new MailRepository("imap.gmail.com", 993, true, @"mailaddress@gmail.com", "password"); foreach (Message email in rep.GetUnreadMails("Inbox")) { Response.Write(string.Format("{0}: {1} {2} ", email.From, email.Subject, email.BodyHtml.Text)); if (email.Attachments.Count > 0) { foreach (MimePart attachment in email.Attachments) { Response.Write(string.Format("Attachment: {0} {1} ", attachment.ContentName, attachment.ContentType.MimeType)); } } } }
Other IMAP mail servers might not need SSL, or requires another port number.
When calling GetUnreadMails(), mails will be marked as read afterwards.
Please note that reading using IMAP (at lest from GMail accounts) is very slow. Don’t be surprised if it takes up to a minute to get 30 mails from a mailbox.
How can I insert the dll to wpf?
LikeLike
Is there any way of using OAuth 2.0 with the MailSystem.NET in the code sample the username, password combination. For some applications however you are unlikely to have that combination.
LikeLike
Thank you very much. Your example works perfectly!!
LikeLike
I am getting the following error.
A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond 173.194.70.108:993.
Pls help me…!
LikeLike
The message implies that there is no connection between your server and the IMAP server you are trying to connect to.
For further information try this link: http://lmgtfy.com/?q=A+connection+attempt+failed+because+the+connected+party+did+not+properly+respond+after+a+period+of+time%2C+or+established+connection+failed+because+connected+host+has+failed+to+respond+
LikeLike
I need to get the contents of the mail.if used “email.BodyHtml.Text” then it automatically insert HTML code.I try “email.BodyText” but is not, please help me
LikeLike
hoang – try mail.BodyText.TextStripped instead of email.BodyText
LikeLike
a problem occurred when retrieving mail.eg: in gmail, mail sent to the Inbox, 2 mail has the same title, it will be classified in the same group.While it only took a second mail, mail for no gain.How do I fix this problem?
LikeLike
hi , your article is very good
when i use your code, while connecting to our imap server, its give me following message:
Unable to read data from the transport connection: An established connection was aborted by the software in your host machine.
any idea, what can be problem
LikeLike
This exception is thrown when the mail server you are requesting closes the connection. You need to ensure that you are requesting data from the correct port, and use SSL if needed.
You should also ansure that your firewall and antivirus allows you to send AND receive data from the port you are requesting. McAfee antivirus for example is known for blocking mail send requests.
Detecting network related issues is very difficult but tools like Fiddler (http://www.fiddler2.com), NetTool (http://nettool.sourceforge.net/) and especially Wireshark (http://www.wireshark.org/) is great tools for seeing what’s going on between your machine and the target host.
The following articles gives you a more technical description of the issue:
– http://www.experts-exchange.com/Programming/Languages/C_Sharp/Q_24942090.html
– http://social.msdn.microsoft.com/Forums/da-DK/ncl/thread/29cabe89-db35-48ae-bc54-91b583eeed55
LikeLike
hey here UNSEEN is not working as it gives a error saying that
“object reference not set ot an instance of object ” pointing out the
line -“messagecollection messages=mails.SearchParse(searchphrase);
can u please help me out it’s important part of my academic project please reply me soon thnks
LikeLike
The “UNSEEN” is a mail server search phrase describing to the mail server that it must return all unread mails from the inbox.
Not all mailservers uses this phrase. Please refer to the manual of your mailserver what phrase to use when looking for unread mails.
LikeLike
Hi,
Nice article with good information. I have following query, if you can help?
– Can we identify from Headers if email have attachments?
I want to display attachment icon with email information same hotmail, gmail inbox.
Thanks
LikeLike
FYI – You can speed up your login by using Imap4Client.LoginFast() and then lazy load whatever you need.
LikeLike
I am getting the following error.
“The remote certificate is invalid according to the validation procedure”,
Where do i have to specify the certificate or is there a method which allows me to skip the validation. Can you please help me out
Thanks in advance
LikeLike
how to send mails using this IMAP server url?
LikeLike
A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond 173.194.70.108:993.
same problem persist for me also while connection to gmail (imap.gmail.com)
LikeLike
why this application dose not work in .net windows form application. it only works on web application
LikeLike
hi sir,
your sample worked perfectly for me.. thanks a lot.. can u pls let me know how to get mails from send folder..
LikeLike
Good stuff! Thanks for sharing.
LikeLike
Thank you for your effort.
Would you please provide us with any book that contains tutorials about mailsystem.net
LikeLike
Thanx on library.
Is there a chance to count unread messages without setting flag on IMAP server readed.
When I do mails.SearchParse(“UNSEEN”);
All messages get status readed.
LikeLike
Hello,
I`ve got a question, the “UNSEEN” messages are not marked as “read” after i executet the programm. Do you know why this could happen ?
LikeLike
Hi,
I have a requirement to read link from the email body and go to the link. Is there any way in the library to get the link in email body or we need to manually scan the email body to get the link?
Thanks
Pooja
LikeLike
Admin Hod:
To count unread messages just use mailbox.messageCount and substract the ordinal position of the first unseen message in the mailbox using the property of the mailbox called “firstunseen”.
Pooja:
There is no way with MailSystem.net to determine a link within the body of a mail. You will have to parse it yourself unfortunately.
vinodh:
To open mails from the Sent mailbox, just need to select that mailbox instead of Inbox. However, different mail servers (gmail, yahoo, etc) name the “Sent” mailbox differently (for example its [Gmail]/Sent with gmail with an english account or [Gmail]/Enviados with a spanish account). To figure out the exact name, you can issue a “List” command, or you can debug and check the “allMailboxes” property of an already connected Imap4Client (which was connected by login method and not by fastLogin).
Krishna Varma:
IMAP is only for retrieval of mails, to send one you need to use Simple Message Transfer Protocol (SMTP) which has different host, port and commands (still supported with MailSystem.net though).
Martin H:
Unseen mails are mails that do not posess the “seen” flag. There isn’t a “not seen” flag. The way to adquire the Message object in MailSystem.net determines whether this flag is automatically eliminated or not. Use mailbox.Fetch.messageObject(…) to get the Message object and setting the “seen” flag, or use mailbox.Fetch.messageObjectPeek(…) to get the Message object without chaging the “seen” flag (so mails not seen will remain the same.
If you use mailbox.searchPhrase(…), the server will always add the “seen” flag (there is a workaround this but its like bypassing MailSystem library, by issuing a Command with BODY.PEEK parameter).
Hope this helps!
LikeLike
give me error,the method is must return type( MailRepository
)
LikeLike
How to Monitor mail server for incoming mails? Threading? or is there any inbuilt method to do it?
LikeLike
Hi, I tried this library with Gmail. Got a successful connection but it took ages to do the login even though it eventually succeeded.
LikeLike
It works perfectly…. I would like to download the attachment…. how I should do it could you please help me….
LikeLike
Client.Login(login, password) => Client.LoginFast(login, password);
It can resolve the very slow problem.
LikeLike
How to import folders from one imap email client for C #?
LikeLike
Where the [][] is your response (Response.Write(…)). What the [][] is Response? A tree? A potato?
LikeLike
Yes it’s a tree. No, its a test function on an .aspx page from a web project. The Response.Write() is part of the HttpContext.Current. namespace.
LikeLike
Thank you for this, i made a few additions. 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 GetAllMails(string mailBox)
{
return GetMails(mailBox, “ALL”).Cast();
}
public IEnumerable GetAllTo(string mailBox, string emailFilter)
{
var test = GetMails(mailBox, string.Format(“TO ‘{0}'”, emailFilter)).Cast();
return test;
}
public IEnumerable GetAllToFromDate(string mailBox, string emailFilter, DateTime date)
{
var dateFormatted = date.ToString(“dd-MMM-yyyy”);
var test = GetMails(mailBox, string.Format(“TO ‘{0}’ NOT BEFORE {1}”, emailFilter, dateFormatted)).Cast();
return test;
}
public IEnumerable GetMailsFromDate(string mailBox, DateTime date)
{
var dateFormatted = date.ToString(“dd-MMM-yyyy”);
return GetMails(mailBox, string.Format(“NOT BEFORE {0}”, dateFormatted)).Cast();
}
public IEnumerable GetUnreadMails(string mailBox)
{
return GetMails(mailBox, “UNSEEN”).Cast();
}
public IEnumerable GetUnreadMailsFromDate(string mailBox, DateTime date)
{
var dateFormatted = date.ToString(“dd-MMM-yyyy”);
return GetMails(mailBox, string.Format(“UNSEEN NOT BEFORE {0}”, dateFormatted)).Cast();
}
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;
}
}
LikeLike
Thaks, it works very fine. Compliments….
LikeLike
“The handshake failed due to an unexpected packet format”. Error is coming while executing the application.
LikeLike
Thanks a lot.. It works great and downloads normal files(non password protected) which is attached to the mail.
but when i try to download a zip file(which contains a password protected pdf), i am unable to open the zip file. It says its corrupted.
I am able to download from gmail directly. Also the zip asks for password only while extracting the content. Not while downloading.
any idea how to download password protected files via Activeup.Net?
LikeLike
Hi,
I am looking for how to use Search Phrases while filtering for email. I do not want to see all Unread or all read. But I need to see the emails from a particular sender & in a particular date interval.
Pls help me how can i do that. Is there any documentation available how I can use searching for emails ?
LikeLike
Any 3.5 framework version?
LikeLike
Thanks a lot, it’s worked.
but I need to display inline attachments like images.
How is that?
LikeLike
Great !
Maybe libraries for Imap in Nuget.
Suggestions for working together with:
https://higlabo.codeplex.com/documentation
https://mailsystem.codeplex.com/
https://imapx.codeplex.com/
https://github.com/andyedinborough/aenetmail
https://github.com/jstedfast/MailKit
Lumisoft Mail
References:
http://stackoverflow.com/questions/545724/using-c-sharp-net-librarires-to-check-for-imap-messages-from-gmail-servers
http://stackoverflow.com/questions/670183/accessing-imap-in-c-sharp
LikeLike
The operation is not allowed on non-connected sockets.
LikeLike
I got this Error…..
The operation is not allowed on non-connected sockets.
LikeLike
i want to develop an app on getting unread mails and send these emails to mobile number as text message,i m begginer plz help me
thanx
LikeLike
What is the maximum number of messages that can be retrieved at a time from the mail server ? Can we retrieve 500 messages at a time? And can we retrieve messages in groups (say a group of 50 messages at a time ? Please help
LikeLike
Could not load file or assembly ‘ActiveUp.Net.Imap4’ or one of its dependencies. This assembly is built by a runtime newer than the currently loaded runtime and cannot be loaded
Getting this error
LikeLike
Hi,
Any 3.5 framework version, please?
Thank’s in advance
LikeLike
How can i use pop3 and exchange server??
LikeLike
how to save attachment to sql server database
LikeLike
foreach (MimePart attachment in emails.Attachments)
{
attachment .????????
}
LikeLike
when login through “Client.Login(login, password); ” using imap yahoo mail I got System.StackOverflow Exception
LikeLike
I used gmail imap, used code above. The login is successful, but I got error “Index and length must refer to a location within the string. Parameter name: length” at line “MessageCollection messages = mails.SearchParse(searchPhrase);”. Anyone got this problem?
LikeLike
Has anyone seen a case where the email.Attachments AttachmentCollection doesn’t show anything within the collection, yet the email does in fact have an attachment? I have a program that is running successfully on a number of emails where the program is able to determine that there are attachments with the email. However, I am running into a case where the email has a .CSV file attachment, yet the Attachments collection is empty. The program has worked well with many other CSV attachments, so I am not at all clear as to why it would fail on this email. Hoping someone can help as this has just become a critical issue for me on a big project.
LikeLike
Sewerrat y have the same problem did you solved it?? Thanks!!!
LikeLike
Too many simultaneous connections?
LikeLike
hey thanks for the example: i have a question.
how can i get emails from a public folder?
i use this
var inbox = imap.SelectMailbox(“MyPublicFolder”);
but don´t works!
plz help!
LikeLike
I get an error
No connection could be made because the target machine actively refused it 74.125.68.108:993
on Client.ConnectSsl(mailServer, port);
Trying to connect imap.gmail.com, 993
Is it because of the Proxy I am behind?
LikeLike
No connection could be made because the target machine actively refused it 74.125.68.108:993
Trying to connect imap.gmail.com, 993
Because of Proxy??
LikeLike
I am having the same problem as @Jonathan, where the email.Attachments.count=0, yet the email does have an attachment. It worked initially, but suddenly, whatever I try, the Attachments collection is empty.
@Jonathan, did you find the cause of this problem? Or even a workaround? I thought this part of my project was over and done with. Suddenly, at implementation stage, I am stuck.
Any help/guidance would be appreciated.
Thanks in advance
LikeLike
How can i get the list draft email ??
LikeLike
Thank you very much
LikeLike
All of the mail boxes are found using the searchPhrase. And since each mail server have their own set of names for folders, you will have to either find the documentation or to guess your way out of it.
Have you tried with “drafts” or “draft”?
GetMails(mailBox, “DRAFTS”).Cast();
GetMails(mailBox, “DRAFT”).Cast();
LikeLike
Hi i have tried the same code it worked but some hours the GetUnreadEmails is no longer working. The error message is as follows ” Input string was not in a correct format.” on GetMails method. Can anyone help me with this.
public IEnumerable GetUnreadMails(string mailBox)
{
return GetMails(mailBox, “UNSEEN”).Cast();
}
LikeLike
Thanks for the post! I have a question! How can I Fetch the single message using its Id?
LikeLike
Hi, I ‘m having trouble reading the mail from the IMAPClient , when do the Mailbox.Fetch.MessageObject ( x ) the body of the mesage both BodyHTML as BodyText me is empty , I could you indicate why ?
Thank you very much.
LikeLike
I have the problem when i try to retrive mails from Godaddy workspace mail
private MessageCollection GetMails(string mailBox, string searchPhrase)
{
Mailbox mails = Client.SelectMailbox(mailBox);
MessageCollection messages = mails.SearchParse(searchPhrase);
return messages;
}
For me SearchParse method givng error but it is connecting to godaddy
How can i solve this problem
Thanks
Venkat Kondaveeti
LikeLike
How to download File Attachments to disc
LikeLike
How i can delete the read mail from the server..Please help
LikeLike
To save the attachments to disk:
Imports ActiveUp.Net.Mail
Imports PT.MailIntegration.IMAP
‘————————————————
Dim rep As New MailRepository(“YourEmailDomain”,143, False,”YourEmailAddress”,”Password”)
For Each email As Message In rep.GetAllMails(“Inbox”)
If email.Attachments.Count > 0 Then
For Each attachment As MimePart In email.Attachments
File.WriteAllBytes(“D:\” & attachment.Filename, attachment.BinaryContent)
Next
End If
Next
‘————————————————
I’m also looking for the same solution as Ranjan – Delete message after read
LikeLike
Hopefully you don’t mind I share OpenPop solution here.
In your project, go to Website > Manage NuGet Pakages and then install OpenPop.Net
————————————————————————————
Imports OpenPop
Imports OpenPop.Pop3
Imports OpenPop.Mime.Header
Imports OpenPop.Mime
Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs)
‘ Connect to the server
client.Connect(“YourEmailDomain”, 110, False)
client.Authenticate(“EmailAddress”, “Password”, Nothing)
Dim messageCount As Integer = client.GetMessageCount()
Dim allMessages As New List(Of Message)(messageCount)
For i As Integer = messageCount To 1 Step -1
allMessages.Add(client.GetMessage(i))
Dim headers As MessageHeader = client.GetMessageHeaders(i)
Dim from As RfcMailAddress = headers.From
Dim subject As String = headers.Subject
Dim mailMsg As Message = client.GetMessage(i)
Dim msgHtml As MessagePart = mailMsg.FindFirstHtmlVersion()
‘ Display the message or you can save it to database
Label1.Text = Label1.Text & “From: ” & from.ToString & “Subject: ” & subject & “” & System.Text.Encoding.UTF8.GetString(msgHtml.Body) & “”
‘ Save the full message to disk
Dim msgFile As New FileInfo(“D:\Test.eml”)
mailMsg.Save(Msgfile)
‘ Save attachment
For Each attachment As MessagePart In mailMsg.FindAllAttachments()
‘ if you want to check the attachment file name
‘If attachment.FileName.Equals(“useful.pdf”) Then …
File.WriteAllBytes(“D:\” & attachment.FileName, attachment.Body)
Next
‘ Delete Message
‘client.DeleteMessage(i)
Next
End Sub
LikeLike
I am having quite puzzling issue. I am able to fetch from one gmail id (corporate plan) but not other.
When I run my .exe for other gmail id, the process runs forever and i have to forcefully close it. One time I got error as “No such host is known
at PcrmInMail.MailRepository..ctor(String mailServer, Int32 port, Boolean ssl, String login, String password)”
Request suggest what should i do.
I am using configuration as below –
imap.gmail.com, 993, true
LikeLike
Hi Jeff!
Imports OpenPop
Imports OpenPop.Pop3
Imports OpenPop.Mime.Header
Imports OpenPop.Mime
Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs)
‘ Connect to the server
client.Connect(“YourEmailDomain”, 110, False)
client.Authenticate(“EmailAddress”, “Password”, Nothing)
Dim messageCount As Integer = client.GetMessageCount()
Dim allMessages As New List(Of Message)(messageCount)
For i As Integer = messageCount To 1 Step -1
allMessages.Add(client.GetMessage(i))
Dim headers As MessageHeader = client.GetMessageHeaders(i)
Dim from As RfcMailAddress = headers.From
Dim subject As String = headers.Subject
Dim mailMsg As Message = client.GetMessage(i)
Dim msgHtml As MessagePart = mailMsg.FindFirstHtmlVersion()
‘ Display the message or you can save it to database
Label1.Text = Label1.Text & “From: ” & from.ToString & “Subject: ” & subject & “” & System.Text.Encoding.UTF8.GetString(msgHtml.Body) & “”
‘ Save the full message to disk
Dim msgFile As New FileInfo(“D:\Test.eml”)
mailMsg.Save(Msgfile)
‘ Save attachment
For Each attachment As MessagePart In mailMsg.FindAllAttachments()
‘ if you want to check the attachment file name
‘If attachment.FileName.Equals(“useful.pdf”) Then …
File.WriteAllBytes(“D:\” & attachment.FileName, attachment.Body)
Next
‘ Delete Message
‘client.DeleteMessage(i)
Next
End Sub
==>
client.DeleteMessage(i) not working.
I want to after read mail. Mail will is deleted in host mail.
Pls suggest for me.
Thank’s alot.
LikeLike
Hi, I want to open/ get unseen emails with a certain subject without downloading all the unread emails. Does anyone here know how to do that?
For example, there are 10 unread/ unseen emails in my gmail inbox, I don’t want to open all of them, I only want to open the email with the subject ‘Good morning’, so that only that email will be marked read, the rest will remain unread
Thank a lot
LikeLike
Hello,
Thanks for the code. It works well.
I have one problem. It works fine with gmail account but when I configure GoDaddy account, I am able to fetch unread emails but they are not getting marked as read.
Please help.
Thanks a lot.
LikeLike
Hi,
I am using this code to fetch mails from my gmail. I need to fetch mails received from some specific email id & after a particular date.
I used Search phrase as “NOT BEFORE 12-Mar-2019” in Inbox, but its not working. I get Exception as follows:
ERROR MailRepository – Unexpected end of stream
at ActiveUp.Net.Mail.Imap4Client.Command(String command, String stamp, CommandOptions options)
at ActiveUp.Net.Mail.Imap4Client.Command(String command, CommandOptions options)
at ActiveUp.Net.Mail.Fetch.MessageRawString(Int32 messageOrdinal, Boolean markMessagesAsRead, String[] extraDataItemToFetch)
at ActiveUp.Net.Mail.Fetch.MessageString(Int32 messageOrdinal)
at ActiveUp.Net.Mail.Mailbox.SearchParse(String query)
at MailRepository.GetMails(String mailBox, String searchPhrase)
Please advice how can we filter the emails as per date and from email address too.
LikeLike