Posts Tagged ‘IMAP’

Folder access with IMAP

Tuesday, May 15th, 2012

This article describes how to access different folder then inbox using Mail.dll IMAP library.

In most cases the first thing you need from an IMAP server is to access INBOX folder. Mail.dll has a special method for that, as this is the only folder that must exist on every IMAP server. It’s Imap.SelectInbox.

Most servers, of course, allow client to access more folders. You can list all IMAP folders using Imap.GetFolders method.

If you want to access different IMAP folder than Inbox, you need to use overloaded Imap.Select method which takes string parameter (folder name) or FolderInfo parameter (returned from a call to Imap.GetFolders method).

After that you can use GetAll, Search and GetMessageByUID methods to search and download email messages.

// C#

using (Imap imap = new Imap())
{
    imap.Connect("imap.example.com");    // or ConnectSSL for SSL
    imap.Login("user", "password");

    imap.Select("Sent items");

    Console.WriteLine(
        "There are {0} messages in 'Sent items'",
        imap.GetAll().Count);

    imap.Close();
}
' VB.NET

Using imap As New Imap()
	imap.Connect("imap.example.com")	' or ConnectSSL for SSL
	imap.Login("user", "password")

	imap.[Select]("Sent items")

	Console.WriteLine( _
		"There are {0} messages in 'Sent items'", _
		imap.GetAll().Count)

	imap.Close()
End Using

There is no established standard on naming common IMAP folders like ‘Sent mail’, ‘Spam’ etc. However some servers support XLIST command (Gmail) or SpecialUse extension that allow to identify common folders on this particular IMAP server.

Common IMAP folders

Thursday, April 19th, 2012

There are no well-know names for common folders such as Drafts, Trash, Spam, … defined in IMAP protocol standards.

This makes quite difficult for an IMAP client to know the real purpose of the folders on the server.

Fortunately there are two IMAP protocol extensions:

You can check if your servers support it by checking if SupportedExtensions returns ImapExtension.XList or ImapExtension.SpecialUse

Both extensions are supported by Mail.dll and, if your server supports any of them, you can take advantage of CommonFolders class. CommonFolders allows you to get the name of the folder and Select it, by knowing its purpose (for example Spam folder may be called “Junk email” on the server).

// C# version:

using (Imap imap = new Imap())
{
    imap.ConnectSSL("imap.gmail.com");
    imap.Login("pat@gmail.com", "password");

    CommonFolders folders = new CommonFolders(imap.GetFolders());

    Console.WriteLine("Inbox folder: " + folders.Inbox.Name);
    Console.WriteLine("Sent folder: " + folders.Sent.Name);
    Console.WriteLine("Spam folder: " + folders.Spam.Name);

    // You can select folders easy:
    imap.Select(folders.Inbox);
    imap.Select(folders.Sent);
    imap.Select(folders.Spam);

    imap.Close();
}
' VB.NET version:

Using imap As New Imap()
    imap.ConnectSSL("imap.gmail.com")
    imap.Login("pat@gmail", "password")

    Dim folders As New CommonFolders(imap.GetFolders())

    Console.WriteLine("Inbox folder: " + folders.Inbox.Name)
    Console.WriteLine("Sent folder: " + folders.Sent.Name)

    ' You can select folders easy:
    imap.Select(folders.Inbox)
    imap.Select(folders.Sent)

    imap.Close()
End Using

You can check if you can use CommonFolders with following code:

// C#

List<ImapExtension> extensions = client.SupportedExtensions();
bool canUseCommonFolders = extensions.Contains(ImapExtension.XList)
    || extensions.Contains(ImapExtension.SpecialUse);
' VB.NET

Dim extensions As List(Of ImapExtension) = client.SupportedExtensions()
Dim canUseCommonFolders As Boolean = extensions.Contains(ImapExtension.XList) OrElse extensions.Contains(ImapExtension.SpecialUse)

Label message with Gmail system label (e.g. Starred)

Saturday, March 31st, 2012

If you want to use user-defined label please read label message with user defined label.

There are two ways of labeling message with Gmail system label (e.g. Starred)

Imap.GmailLabelMessageByUID method

GmailLabelMessageByUID method uses Gmail’s X-GM-LABELS extension to the IMAP protocol. You need to provide a folder flag name for it to work correctly e.g. @”\Starred”.

You can use FolderFlag class static properties to get common flags:
FolderFlag.XImportant, FolderFlag.XSpam, FolderFlag.XStarred.

// C#

using (Imap imap = new Imap())
{
    imap.ConnectSSL("imap.gmail.com");
    imap.Login("pat@gmail.com", "password");

    imap.SelectInbox();
    long last = imap.GetAll().Last();

    imap.GmailLabelMessageByUID(last, FolderFlag.XStarred.Name);

    imap.Close();
}
' VB.NET

Using imap As New Imap()
    imap.ConnectSSL("imap.gmail.com")
    imap.Login("pat@gmail.com", "password")

    imap.SelectInbox()
    Dim last As Long = imap.GetAll().Last()

    imap.GmailLabelMessageByUID(last, FolderFlag.XStarred.Name)

    imap.Close()
End Using

Imap.CopyByUID method

The second method basis on the fact that Gmail treats labels as regular IMAP folders.
You just need to know correct folder name and copy the message to this folder.

You can use CommonFolders class to get common folders:

// C#

using (Imap imap = new Imap())
{
    imap.ConnectSSL("imap.gmail.com");
    imap.Login("pat@gmail.com", "password");

    List<FolderInfo> folders = imap.GetFolders();

    imap.SelectInbox();
    long last = imap.GetAll().Last();

    imap.CopyByUID(last, new CommonFolders(folders).Starred);

    imap.Close();
}
' VB.NET

Using imap As New Imap()
    imap.ConnectSSL("imap.gmail.com")
    imap.Login("pat@gmail.com", "password")

    Dim folders As List(Of FolderInfo) = imap.GetFolders()

    imap.SelectInbox()
    Dim last As Long = imap.GetAll().Last()

    imap.CopyByUID(last, New CommonFolders(folders).Starred)

    imap.Close()
End Using

List all Gmail labels

Friday, March 30th, 2012

Gmail treats labels as folders for the purposes of IMAP.

As such, labels can be modified using the standard IMAP commands, CreateFolder, RenameFolder, and DeleteFolder, that act on folders.

System labels, which are labels created by Gmail, are reserved and prefixed by “[Gmail]” or “[GoogleMail]” in the list of labels.

// C#

using (Imap imap = new Imap())
{
    imap.ConnectSSL("imap.gmail.com");
    imap.Login("pat@gmail.com", "password");

    List<FolderInfo> folders = imap.GetFolders();
    List<FolderInfo> system = folders.FindAll(x => x.Name.StartsWith("[Gmail]"));
    List<FolderInfo> user = folders.FindAll(x => !x.Name.StartsWith("[Gmail]"));

    Console.WriteLine("System labels:");
    system.ForEach(x => Console.WriteLine(x.Name));
    Console.WriteLine();
    Console.WriteLine("User labels:");
    user.ForEach(x => Console.WriteLine(x.Name));

    imap.Close();
}
' VB.NET

Using imap As New Imap()
    imap.ConnectSSL("imap.gmail.com")
    imap.Login("pat@gmail.com", "password")

    Dim folders As List(Of FolderInfo) = imap.GetFolders()
    Dim system As List(Of FolderInfo) =
        folders.FindAll(Function(x) x.Name.StartsWith("[Gmail]"))
    Dim user As List(Of FolderInfo) =
        folders.FindAll(Function(x) Not x.Name.StartsWith("[Gmail]"))

    Console.WriteLine("System labels:")
    system.ForEach(Function(x) Console.WriteLine(x.Name))
    Console.WriteLine()
    Console.WriteLine("User labels:")
    user.ForEach(Function(x) Console.WriteLine(x.Name))

    imap.Close()
End Using

Here is the output:


System labels:
[Gmail]
[Gmail]/All Mail
[Gmail]/Drafts
[Gmail]/Sent Mail
[Gmail]/Spam
[Gmail]/Starred
[Gmail]/Trash


User labels:
my label
my label/nested
my second label

Receive vCard business card

Saturday, March 3rd, 2012

Mail.dll .NET email component makes receiving vCard business cards easy.

IMail object exposes VCards collection that contains all vCard business cards that were found while parsing an email.

You can use both IMAP or POP3 protocol to download email from the server.

Here’s the simple sample showing how to process VCard business cards:

// C#

IMail email = new MailBuilder().CreateFromEml(client.GetMessageByUID(uid));

foreach (VCard vCard in email.VCards)
{

    Console.WriteLine("first name: " + vCard.Name.FirstName);
    Console.WriteLine("last name: " + vCard.Name.LastName);
    Console.WriteLine("full name: " + vCard.FullName);

    Console.WriteLine("email: " + vCard.Email);
    Console.WriteLine("work phone: " + vCard.WorkPhone);
    Console.WriteLine("home phone: " + vCard.HomePhone);

    if (vCard.WorkAddress != null)
    {
        Console.WriteLine(vCard.WorkAddress.PostOfficeBox);
        Console.WriteLine(vCard.WorkAddress.ApartmentNumber);
        Console.WriteLine(vCard.WorkAddress.Street);
        Console.WriteLine(vCard.WorkAddress.City);
        Console.WriteLine(vCard.WorkAddress.Region);
        Console.WriteLine(vCard.WorkAddress.PostalCode);
        Console.WriteLine(vCard.WorkAddress.Country);
    }
    if (vCard.HomeAddress != null)
    {
        //...
    }

    foreach (VCardPhone phone in vCard.Phones)
    {
        Console.WriteLine("phone: " + phone.Value);
    }
    foreach (VCardAddress address in vCard.Addresses)
    {
        Console.WriteLine("street: " + address.Street);
    }
    foreach (VCardEmail mail in vCard.Emails)
    {
        Console.WriteLine("email: " + mail.Value);
    }
}
' VB.NET

Dim email As IMail = New MailBuilder().CreateFromEml(client.GetMessageByUID(uid))

For Each vCard As VCard In email.VCards

	Console.WriteLine("first name: " + vCard.Name.FirstName)
	Console.WriteLine("last name: " + vCard.Name.LastName)
	Console.WriteLine("full name: " + vCard.FullName)

	Console.WriteLine("email: " + vCard.Email)
	Console.WriteLine("work phone: " + vCard.WorkPhone)
	Console.WriteLine("home phone: " + vCard.HomePhone)

	If vCard.WorkAddress IsNot Nothing Then
		Console.WriteLine(vCard.WorkAddress.PostOfficeBox)
		Console.WriteLine(vCard.WorkAddress.ApartmentNumber)
		Console.WriteLine(vCard.WorkAddress.Street)
		Console.WriteLine(vCard.WorkAddress.City)
		Console.WriteLine(vCard.WorkAddress.Region)
		Console.WriteLine(vCard.WorkAddress.PostalCode)
		Console.WriteLine(vCard.WorkAddress.Country)
	End If
			'...
	If vCard.HomeAddress IsNot Nothing Then
	End If

	For Each phone As VCardPhone In vCard.Phones
		Console.WriteLine("phone: " + phone.Value)
	Next
	For Each address As VCardAddress In vCard.Addresses
		Console.WriteLine("street: " + address.Street)
	Next
	For Each mail As VCardEmail In vCard.Emails
		Console.WriteLine("email: " + mail.Value)
	Next
Next

You can learn here how to send email with VCard.