Retrieve and List Emails from IMAP Server
Retrieving and Listing Messages
How to Obtain Identification Information for Messages in a Mailbox
When retrieving and processing email messages, you can obtain detailed identification information, such as sequence numbers and unique IDs, using the following features provided by the latest version of Aspose.Email for .NET:
Aspose.Email.ImapMessageInfo class: Represents the identification information about a message in an IMAP mailbox.
ImapMessageInfo.SequenceNumber property: Retrieves the sequence number of the message.
ImapMessageInfo.UniqueId property: Retrieves the unique identifier of the message.
Aspose.Email.MailMessage.ItemId property: Represents additional identification information about the message within the mailbox.
The following code snippet demonstrates how to obtain identification information for messages in an IMAP mailbox:
- Create an instance of the ImapClient class by providing the necessary parameters such as the IMAP server host, port, email address, password, and security options.
- Use the ListMessages method to retrieve a list of messages from the “INBOX” folder. Limit the list to the first five messages using the Take(5) method.
- Extract the sequence numbers of the listed messages by using the SequenceNumber property of each message.
- Use the FetchMessages method to retrieve the full details of the messages from the server, using the sequence numbers obtained in the previous step.
- Loop through the fetched messages and for each message, retrieve and display the following information:
- The sequence number of the message.
- The ItemId.SequenceNumber property.
- The subject of the message.
using (var client = new ImapClient(imapHost, port, emailAddress, password, securityOption))
{
// List the first 5 messages from the inbox
var msgs = client.ListMessages("INBOX").Take(5);
// Get sequence numbers of the messages
var seqIds = msgs.Select(t => t.SequenceNumber);
// Fetch messages based on sequence numbers
var msgsViaFetch = client.FetchMessages(seqIds);
for (var i = 0; i < 5; i++)
{
var thisMsg = msgsViaFetch[i];
Console.WriteLine($"Message ID: {seqIds.ElementAt(i)} SequenceNumber: {thisMsg.ItemId.SequenceNumber} Subject: {thisMsg.Subject}");
}
}
List MIME Message IDs from Server
ImapMessageInfo provides the MIME MessageId for message identification without extracting the complete message. The following code snippet shows you how to list MIME messageId.
// For complete examples and data files, please go to https://github.com/aspose-email/Aspose.Email-for-.NET | |
ImapClient client = new ImapClient(); | |
client.Host = "domain.com"; | |
client.Username = "username"; | |
client.Password = "password"; | |
try | |
{ | |
ImapMessageInfoCollection messageInfoCol = client.ListMessages("Inbox"); | |
foreach (ImapMessageInfo info in messageInfoCol) | |
{ | |
// Display MIME Message ID | |
Console.WriteLine("Message Id = " + info.MessageId); | |
} | |
} | |
catch (Exception ex) | |
{ | |
Console.WriteLine(ex.Message); | |
} |
List Messages from Server
Aspose.Email provides a 2-member overloaded variant of ListMessages() to retrieve a specified number of messages based on a query. The following code snippet shows you how to list Messages.
// For complete examples and data files, please go to https://github.com/aspose-email/Aspose.Email-for-.NET | |
imapClient.SelectFolder("Inbox"); | |
ImapQueryBuilder builder = new ImapQueryBuilder(); | |
MailQuery query = | |
builder.Or( | |
builder.Or( | |
builder.Or( | |
builder.Or( | |
builder.Subject.Contains(" (1) "), | |
builder.Subject.Contains(" (2) ")), | |
builder.Subject.Contains(" (3) ")), | |
builder.Subject.Contains(" (4) ")), | |
builder.Subject.Contains(" (5) ")); | |
ImapMessageInfoCollection messageInfoCol4 = imapClient.ListMessages(query, 4); | |
Console.WriteLine((messageInfoCol4.Count == 4) ? "Success" : "Failure"); |
List Messages Recursively
The IMAP protocol supports listing messages recursively from a mailbox folder. This helps list messages from subfolders of a folder as well. The following code snippet shows you how to list messages recursively.
// For complete examples and data files, please go to https://github.com/aspose-email/Aspose.Email-for-.NET | |
// Create an imapclient with host, user and password | |
ImapClient client = new ImapClient(); | |
client.Host = "domain.com"; | |
client.Username = "username"; | |
client.Password = "password"; | |
client.SelectFolder("InBox"); | |
ImapMessageInfoCollection msgsColl = client.ListMessages(true); | |
Console.WriteLine("Total Messages: " + msgsColl.Count); |
List Messages with MultiConnection
ImapClient provides a UseMultiConnection property which can be used to create multiple connections for heavy operations. You may also set the number of connections to be used during multiconnection mode by using ImapClient.ConnectionsQuantity. The following code snippet demonstrates the use of the multiconnection mode for listing messages and compares its performance with single connection mode.
// For complete examples and data files, please go to https://github.com/aspose-email/Aspose.Email-for-.NET | |
ImapClient imapClient = new ImapClient(); | |
imapClient.Host = "<HOST>"; | |
imapClient.Port = 993; | |
imapClient.Username = "<USERNAME>"; | |
imapClient.Password = "<PASSWORD>"; | |
imapClient.SupportedEncryption = EncryptionProtocols.Tls; | |
imapClient.SecurityOptions = SecurityOptions.SSLImplicit; | |
imapClient.SelectFolder("Inbox"); | |
imapClient.ConnectionsQuantity = 5; | |
imapClient.UseMultiConnection = MultiConnectionMode.Enable; | |
DateTime multiConnectionModeStartTime = DateTime.Now; | |
ImapMessageInfoCollection messageInfoCol1 = imapClient.ListMessages(true); | |
TimeSpan multiConnectionModeTimeSpan = DateTime.Now - multiConnectionModeStartTime; | |
imapClient.UseMultiConnection = MultiConnectionMode.Disable; | |
DateTime singleConnectionModeStartTime = DateTime.Now; | |
ImapMessageInfoCollection messageInfoCol2 = imapClient.ListMessages(true); | |
TimeSpan singleConnectionModeTimeSpan = DateTime.Now - singleConnectionModeStartTime; | |
double performanceRelation = singleConnectionModeTimeSpan.TotalMilliseconds / multiConnectionModeTimeSpan.TotalMilliseconds; | |
Console.WriteLine("Performance Relation: " + performanceRelation); |
List Messages with Paging Support
In scenarios, where the email server contains a large number of messages in the mailbox, it is often desired to list or retrieve the messages with paging support. Aspose.Email API’s ImapClient lets you retrieve the messages from the server with paging support.
// For complete examples and data files, please go to https://github.com/aspose-email/Aspose.Email-for-.NET | |
///<summary> | |
/// This example shows the paging support of ImapClient for listing messages from the server | |
/// Available in Aspose.Email for .NET 6.4.0 and onwards | |
///</summary> | |
using (ImapClient client = new ImapClient("host.domain.com", 993, "username", "password")) | |
{ | |
try | |
{ | |
int messagesNum = 12; | |
int itemsPerPage = 5; | |
MailMessage message = null; | |
// Create some test messages and append these to server's inbox | |
for (int i = 0; i < messagesNum; i++) | |
{ | |
message = new MailMessage( | |
"from@domain.com", | |
"to@domain.com", | |
"EMAILNET-35157 - " + Guid.NewGuid(), | |
"EMAILNET-35157 Move paging parameters to separate class"); | |
client.AppendMessage(ImapFolderInfo.InBox, message); | |
} | |
// List messages from inbox | |
client.SelectFolder(ImapFolderInfo.InBox); | |
ImapMessageInfoCollection totalMessageInfoCol = client.ListMessages(); | |
// Verify the number of messages added | |
Console.WriteLine(totalMessageInfoCol.Count); | |
////////////////// RETREIVE THE MESSAGES USING PAGING SUPPORT//////////////////////////////////// | |
List<ImapPageInfo> pages = new List<ImapPageInfo>(); | |
PageSettings pageSettings = new PageSettings(); | |
ImapPageInfo pageInfo = client.ListMessagesByPage(itemsPerPage, 0, pageSettings); | |
Console.WriteLine(pageInfo.TotalCount); | |
pages.Add(pageInfo); | |
while (!pageInfo.LastPage) | |
{ | |
pageInfo = client.ListMessagesByPage(itemsPerPage, pageInfo.NextPage.PageOffset, pageSettings); | |
pages.Add(pageInfo); | |
} | |
int retrievedItems = 0; | |
foreach (ImapPageInfo folderCol in pages) | |
retrievedItems += folderCol.Items.Count; | |
Console.WriteLine(retrievedItems); | |
} | |
finally | |
{ | |
} | |
} |
List Message Attachments
To get information about attachments such as name, size without fetching the attachment data, try the following APIs:
- Aspose.Email.Clients.Imap.ImapAttachmentInfo - Represents an attachment information.
- Aspose.Email.Clients.Imap.ImapAttachmentInfoCollection - Represents a collection of the ImapAttachmentInfo class.
- Aspose.Email.Clients.Imap.ListAttachments(int sequenceNumber) - Gets an information for each attachment in a message.
The code sample with steps below will show you how to use the APIs:
- Call the ListMessages() method on the imapClient object. This method will return an ImapMessageInfoCollection containing information about the messages in the mailbox.
- Iterate through each message in the messageInfoCollection using a foreach loop.
- Call the ListAttachments() method on the imapClient object, passing the SequenceNumber property of the message object as a parameter. This method will return an ImapAttachmentInfoCollection containing information about the attachments in the message.
- Iterate through each attachment in the attachmentInfoCollection using a foreach loop.
- Within the inner loop, you can access the information about each attachment using properties of the attachmentInfo object.
var messageInfoCollection = imapClient.ListMessages();
foreach (var message in messageInfoCollection)
{
var attachmentInfoCollection = imapClient.ListAttachments(message.SequenceNumber);
foreach (var attachmentInfo in attachmentInfoCollection)
{
Console.WriteLine("Attachment: {0} (size: {1})", attachmentInfo.Name, attachmentInfo.Size);
}
}
Fetching and Saving Messages
Fetch Messages from Server
The ImapClient class can fetch messages from an IMAP server and save the messages in EML format to a local disk. The following steps are required to save the messages to disk:
- Create an instance of the ImapClient class.
- Specify a hostname, port, username, and password in the ImapClient constructor.
- Select the folder using SelectFolder() method.
- Call the ListMessages method to get the ImapMessageInfoCollection object.
- Iterate through the ImapMessageInfoCollection collection, call the SaveMessage() method and provide the output path and file name.
The following code snippet shows you how to fetch email messages from a server and save them.
// For complete examples and data files, please go to https://github.com/aspose-email/Aspose.Email-for-.NET | |
// Select the inbox folder and Get the message info collection | |
client.SelectFolder(ImapFolderInfo.InBox); | |
ImapMessageInfoCollection list = client.ListMessages(); | |
// Download each message | |
for (int i = 0; i < list.Count; i++) | |
{ | |
// Save the EML file locally | |
client.SaveMessage(list[i].UniqueId, dataDir + list[i].UniqueId + ".eml"); | |
} |
Fetch Messages in Descending Order
Aspose.Email provides ImapClient.ListMessagesByPage method which lists messages with paging support. Some overloads of ImapClient.ListMessagesByPage accept PageSettings as a parameter. PageSettings provides an AscendingSorting property which, when set to false, returns emails in descending order.
The following example code demonstrates the use of AscendingSorting property of the PageSettings class to change the order of emails.
// For complete examples and data files, please go to https://github.com/aspose-email/Aspose.Email-for-.NET | |
ImapClient imapClient = new ImapClient(); | |
imapClient.Host = "<HOST>"; | |
imapClient.Port = 993; | |
imapClient.Username = "<USERNAME>"; | |
imapClient.Password = "<PASSWORD>"; | |
imapClient.SupportedEncryption = EncryptionProtocols.Tls; | |
imapClient.SecurityOptions = SecurityOptions.SSLImplicit; | |
PageSettings pageSettings = new PageSettings { AscendingSorting = false }; | |
ImapPageInfo pageInfo = imapClient.ListMessagesByPage(5, pageSettings); | |
ImapMessageInfoCollection messages = pageInfo.Items; | |
foreach (ImapMessageInfo message in messages) | |
{ | |
Console.WriteLine(message.Subject + " -> " + message.Date.ToString()); | |
} |
Save Messages in MSG Format
To save emails in MSG format, the ImapClient.FetchMessage() method needs to be called. It returns the message in an instance of the MailMessage class. The MailMessage.Save() method can then be called to save the message to MSG. The following code snippet shows you how to save messages in MSG Format.
// For complete examples and data files, please go to https://github.com/aspose-email/Aspose.Email-for-.NET | |
// The path to the file directory. | |
string dataDir = RunExamples.GetDataDir_IMAP(); | |
// Create an imapclient with host, user and password | |
ImapClient client = new ImapClient("localhost", "user", "password"); | |
// Select the inbox folder and Get the message info collection | |
client.SelectFolder(ImapFolderInfo.InBox); | |
ImapMessageInfoCollection list = client.ListMessages(); | |
// Download each message | |
for (int i = 0; i < list.Count; i++) | |
{ | |
// Save the message in MSG format | |
MailMessage message = client.FetchMessage(list[i].UniqueId); | |
message.Save(dataDir + list[i].UniqueId + "_out.msg", SaveOptions.DefaultMsgUnicode); | |
} |
Group Fetched Messages
ImapClient provides a FetchMessages method which accepts iterable of Sequence Numbers or Unique ID and returns a list of MailMessage. The following code snippet demonstrates the use of the FetchMessages method to fetch messages by Sequence Numbers and Unique ID.
// For complete examples and data files, please go to https://github.com/aspose-email/Aspose.Email-for-.NET | |
ImapClient imapClient = new ImapClient(); | |
imapClient.Host = "<HOST>"; | |
imapClient.Port = 993; | |
imapClient.Username = "<USERNAME>"; | |
imapClient.Password = "<PASSWORD>"; | |
imapClient.SupportedEncryption = EncryptionProtocols.Tls; | |
imapClient.SecurityOptions = SecurityOptions.SSLImplicit; | |
ImapMessageInfoCollection messageInfoCol = imapClient.ListMessages(); | |
Console.WriteLine("ListMessages Count: " + messageInfoCol.Count); | |
int[] sequenceNumberAr = messageInfoCol.Select((ImapMessageInfo mi) => mi.SequenceNumber).ToArray(); | |
string[] uniqueIdAr = messageInfoCol.Select((ImapMessageInfo mi) => mi.UniqueId).ToArray(); | |
IList<MailMessage> fetchedMessagesBySNumMC = imapClient.FetchMessages(sequenceNumberAr); | |
Console.WriteLine("FetchMessages-sequenceNumberAr Count: " + fetchedMessagesBySNumMC.Count); | |
IList<MailMessage> fetchedMessagesByUidMC = imapClient.FetchMessages(uniqueIdAr); | |
Console.WriteLine("FetchMessages-uniqueIdAr Count: " + fetchedMessagesByUidMC.Count); |
Fetch Folders and Read Messages Recursively
In this article, most of the ImapClient features are used to create an application that lists all the folders and sub-folders recursively from an IMAP server. It also saves the messages in each folder and sub-folder in MSG format on a local disk. On the disk, folders and messages are created and saved in the same hierarchical structure as on the IMAP server. The following code snippet shows you how to get the messages and sub-folders information recursively.
// For complete examples and data files, please go to https://github.com/aspose-email/Aspose.Email-for-.NET | |
public static void Run() | |
{ | |
// Create an instance of the ImapClient class | |
ImapClient client = new ImapClient(); | |
// Specify host, username, password, Port and SecurityOptions for your client | |
client.Host = "imap.gmail.com"; | |
client.Username = "your.username@gmail.com"; | |
client.Password = "your.password"; | |
client.Port = 993; | |
client.SecurityOptions = SecurityOptions.Auto; | |
try | |
{ | |
// The root folder (which will be created on disk) consists of host and username | |
string rootFolder = client.Host + "-" + client.Username; | |
// Create the root folder and List all the folders from IMAP server | |
Directory.CreateDirectory(rootFolder); | |
ImapFolderInfoCollection folderInfoCollection = client.ListFolders(); | |
foreach (ImapFolderInfo folderInfo in folderInfoCollection) | |
{ | |
// Call the recursive method to read messages and get sub-folders | |
ListMessagesInFolder(folderInfo, rootFolder, client); | |
} | |
// Disconnect to the remote IMAP server | |
client.Dispose(); | |
} | |
catch (Exception ex) | |
{ | |
Console.Write(Environment.NewLine + ex); | |
} | |
Console.WriteLine(Environment.NewLine + "Downloaded messages recursively from IMAP server."); | |
} | |
/// Recursive method to get messages from folders and sub-folders | |
private static void ListMessagesInFolder(ImapFolderInfo folderInfo, string rootFolder, ImapClient client) | |
{ | |
// Create the folder in disk (same name as on IMAP server) | |
string currentFolder = RunExamples.GetDataDir_IMAP(); | |
Directory.CreateDirectory(currentFolder); | |
// Read the messages from the current folder, if it is selectable | |
if (folderInfo.Selectable) | |
{ | |
// Send status command to get folder info | |
ImapFolderInfo folderInfoStatus = client.GetFolderInfo(folderInfo.Name); | |
Console.WriteLine(folderInfoStatus.Name + " folder selected. New messages: " + folderInfoStatus.NewMessageCount + ", Total messages: " + folderInfoStatus.TotalMessageCount); | |
// Select the current folder and List messages | |
client.SelectFolder(folderInfo.Name); | |
ImapMessageInfoCollection msgInfoColl = client.ListMessages(); | |
Console.WriteLine("Listing messages...."); | |
foreach (ImapMessageInfo msgInfo in msgInfoColl) | |
{ | |
// Get subject and other properties of the message | |
Console.WriteLine("Subject: " + msgInfo.Subject); | |
Console.WriteLine("Read: " + msgInfo.IsRead + ", Recent: " + msgInfo.Recent + ", Answered: " + msgInfo.Answered); | |
// Get rid of characters like ? and :, which should not be included in a file name and Save the message in MSG format | |
string fileName = msgInfo.Subject.Replace(":", " ").Replace("?", " "); | |
MailMessage msg = client.FetchMessage(msgInfo.SequenceNumber); | |
msg.Save(currentFolder + "\\" + fileName + "-" + msgInfo.SequenceNumber + ".msg", SaveOptions.DefaultMsgUnicode); | |
} | |
Console.WriteLine("============================\n"); | |
} | |
else | |
{ | |
Console.WriteLine(folderInfo.Name + " is not selectable."); | |
} | |
try | |
{ | |
// If this folder has sub-folders, call this method recursively to get messages | |
ImapFolderInfoCollection folderInfoCollection = client.ListFolders(folderInfo.Name); | |
foreach (ImapFolderInfo subfolderInfo in folderInfoCollection) | |
{ | |
ListMessagesInFolder(subfolderInfo, rootFolder, client); | |
} | |
} | |
catch (Exception) { } | |
} |
Handling Special Message Information
Retrieve Extra Parameters as Summary Information
// For complete examples and data files, please go to https://github.com/aspose-email/Aspose.Email-for-.NET | |
using (ImapClient client = new ImapClient("host.domain.com", "username", "password")) | |
{ | |
MailMessage message = new MailMessage("from@domain.com", "to@doman.com", "EMAILNET-38466 - " + Guid.NewGuid().ToString(), "EMAILNET-38466 Add extra parameters for UID FETCH command"); | |
// append the message to the server | |
string uid = client.AppendMessage(message); | |
// wait for the message to be appended | |
Thread.Sleep(5000); | |
// Define properties to be fetched from server along with the message | |
string[] messageExtraFields = new string[] { "X-GM-MSGID", "X-GM-THRID" }; | |
// retreive the message summary information using it's UID | |
ImapMessageInfo messageInfoUID = client.ListMessage(uid, messageExtraFields); | |
// retreive the message summary information using it's sequence number | |
ImapMessageInfo messageInfoSeqNum = client.ListMessage(1, messageExtraFields); | |
// List messages in general from the server based on the defined properties | |
ImapMessageInfoCollection messageInfoCol = client.ListMessages(messageExtraFields); | |
ImapMessageInfo messageInfoFromList = messageInfoCol[0]; | |
// verify that the parameters are fetched in the summary information | |
foreach (string paramName in messageExtraFields) | |
{ | |
Console.WriteLine(messageInfoFromList.ExtraParameters.ContainsKey(paramName)); | |
Console.WriteLine(messageInfoUID.ExtraParameters.ContainsKey(paramName)); | |
Console.WriteLine(messageInfoSeqNum.ExtraParameters.ContainsKey(paramName)); | |
} | |
} |
Get List-Unsubscribe Header Information
List-Unsubscribe header contains the URL for unsubscribing from email lists e.g. advertisements, newsletters, etc. To get the List-Unsubscribe header, use the ListUnsubscribe property of the ImapMessageInfo class. The following example shows the use of the ListUnsubscribe property to get the List-Unsubscribe header.
// For complete examples and data files, please go to https://github.com/aspose-email/Aspose.Email-for-.NET | |
ImapClient imapClient = new ImapClient(); | |
imapClient.Host = "<HOST>"; | |
imapClient.Port = 993; | |
imapClient.Username = "<USERNAME>"; | |
imapClient.Password = "<PASSWORD>"; | |
imapClient.SupportedEncryption = EncryptionProtocols.Tls; | |
imapClient.SecurityOptions = SecurityOptions.SSLImplicit; | |
ImapMessageInfoCollection messageInfoCol = imapClient.ListMessages(); | |
foreach (ImapMessageInfo imapMessageInfo in messageInfoCol) | |
{ | |
Console.WriteLine("ListUnsubscribe Header: " + imapMessageInfo.ListUnsubscribe); | |
} |