Posts Tagged ‘IMAP’

Get supported server extensions (IMAP, POP3, SMTP)

Thursday, October 6th, 2011

You can use SupportedExtensionsmethod to retrieve all protocol extensions supported by the server:

// C#

using (Imap client = new Imap())
{
    client.ConnectSSL("imap.example.org");
    client.UseBestLogin("user", "password");

    Console.WriteLine("Supported extensions:");

    foreach (ImapExtension extension in client.SupportedExtensions())
    {
        Console.WriteLine(extension.Name);
    }

    Console.WriteLine("Supports IDLE:");

    bool supportsIdle = client.SupportedExtensions()
        .Contains(ImapExtension.Idle);

    Console.WriteLine(supportsIdle);

    client.Close();
}
' VB.NET

Using client As New Imap()
    client.ConnectSSL("imap.example.org")
    client.UseBestLogin("user", "password")

    Console.WriteLine("Supported extensions:")

    For Each extension As ImapExtension In client.SupportedExtensions()
	    Console.WriteLine(extension.Name)
    Next

    Console.WriteLine("Supports IDLE:")

    Dim supportsIdle As Boolean = client.SupportedExtensions() _
        .Contains(ImapExtension.Idle)

    Console.WriteLine(supportsIdle)

    client.Close()
End Using

For example Gmail produces following output:

Supported extensions:
IMAP4rev1
UNSELECT
IDLE
NAMESPACE
QUOTA
ID
XLIST
CHILDREN
X-GM-EXT-1
UIDPLUS
COMPRESS

Supports IDLE:
True

We take great care for the API to look similar for all protocols (IMAP, POP3, SMTP).

Here’s the sample for POP3:

// C#

using (Pop3 client = new Pop3())
{
    client.ConnectSSL("pop3.example.org");
    client.UseBestLogin("user", "password");

    Console.WriteLine("Supported extensions:");

    foreach (Pop3Extension extension in client.SupportedExtensions())
    {
        Console.WriteLine(extension.Name);
    }

    Console.WriteLine("Supports TOP:");

    bool supportsTop= client.SupportedExtensions()
        .Contains(Pop3Extension.Top);

    Console.WriteLine(supportsTop);

    client.Close();
}
' VB.NET

Using client As New Pop3()
    client.ConnectSSL("pop3.example.org")
    client.UseBestLogin("user", "password")

    Console.WriteLine("Supported extensions:")

    For Each extension As Pop3Extension In client.SupportedExtensions()
	    Console.WriteLine(extension.Name)
    Next

    Console.WriteLine("Supports TOP:")

    Dim supportsTop As Boolean = client.SupportedExtensions() _
        .Contains(Pop3Extension.Top)

    Console.WriteLine(supportsTop)

    client.Close()
End Using

Here’s the sample for SMTP:

// C#

using (Smtpclient = new Smtp())
{
    client.Connect("smtp.example.org");
    client.UseBestLogin("smtp", "password");

    Console.WriteLine("Supported extensions:");

    foreach (SmtpExtension  extension in client.SupportedExtensions())
    {
        Console.WriteLine(extension.Name);
    }

    Console.WriteLine("Supports STARTTLS:");

    bool supportsStartTLS = client.SupportedExtensions()
        .Contains(SmtpExtension.StartTLS);

    Console.WriteLine(supportsStartTLS);

    client.Close();
}
' VB.NET

Using client As New Smtp()
    client.Connect("smtp.example.org")
    client.UseBestLogin("user", "password")

    Console.WriteLine("Supported extensions:")

    For Each extension As SmtpExtension In client.SupportedExtensions()
	    Console.WriteLine(extension.Name)
    Next

    Console.WriteLine("Supports STARTTLS:")

    Dim supportsStartTLS As Boolean = client.SupportedExtensions() _
        .Contains(SmtpExtension.StartTLS)

    Console.WriteLine(supportsStartTLS)

    client.Close()
End Using

Remove attachments from email

Thursday, October 6th, 2011

First I want to make one thing clear, neither POP3 nor IMAP protocols does not provide any way to remove attachments from existing emails.
This is because email stored on the server is immutable.
With IMAP protocol you can copy it to different folder, you can apply some flags (SEEN) to it, but you can’t change any part of the message.

The second important thing is that attachments are not stored separately from the message text and headers – they are embedded inside the email.

Nevertheless Mail.dll provides an easy way to create new email without the attachments from existing email message.

// C# 

IMail original = new MailBuilder().CreateFromEml(eml);
IMail email = original.RemoveAttachments().Create();
' VB.NET

Dim original As IMail = New MailBuilder().CreateFromEml(eml)
Dim email As IMail = original.RemoveAttachments().Create()

RemoveAttachments method also has an overloaded version that allows to remove only visual (content-disposition: inline) or/and non-visual (content-disposition: attachment) attachments:

// C# 

MailBuilder RemoveAttachments();

MailBuilder RemoveAttachments(
    bool removeVisuals,
    bool removeNonVisuals);
' VB.NET

Function RemoveAttachments() As MailBuilder

Function RemoveAttachments( _
    removeVisuals As Boolean, _
    removeNonVisuals As Boolean) As MailBuilder

The following example illustrates the full process of downloading email from IMAP server,
creating new email, with the same information, but without attachments, and finally uploading it, and removing the original message:

// C# 

using(Imap imap = new Imap())
{
    imap.ConnectSSL("imap.example.org");
    imap.UseBestLogin("user", "password");
    imap.SelectInbox();

    foreach (long uid in imap.GetAll())
    {
        string eml = imap.GetMessageByUID(uid);
        IMail original = new MailBuilder().CreateFromEml(eml);
        if (original.Attachments.Count > 0)
        {
            IMail email = original.RemoveAttachments().Create();

            imap.UploadMessage("Inbox", email);

            imap.DeleteMessageByUID(uid);
        }
    }
    imap.Close();
}
' VB.NET

Using imap As New Imap()
   imap.ConnectSSL("imap.example.org")
   imap.UseBestLogin("user", "password")
   imap.SelectInbox()

   For Each uid As Long In imap.GetAll()
      Dim eml As String = imap.GetMessageByUID(uid)
      Dim original As IMail = New MailBuilder().CreateFromEml(eml)
      If original.Attachments.Count > 0 Then
         Dim email As IMail = original.RemoveAttachments().Create()

         imap.UploadMessage("Inbox", email)

         imap.DeleteMessageByUID(uid)
      End If
   Next
   imap.Close()
End Using

Create Gmail url-ID via IMAP

Tuesday, August 30th, 2011

This is Gmail link that points to certain conversation:

https://mail.google.com/mail/u/0/#inbox/13216515baefe747

“13216515baefe747″ is the Gmail thread-ID in hex.

Here’s the code that:

  1. Selects “All Mail” folder
  2. Gets the newest message UID
  3. Obtains Gmail thread ID for this message (X-GM-THRID)
  4. Converts it to hex
  5. Creates the url that point to the Gmail conversation
// C# version

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

    // select "All Mail" folder
    List<FolderInfo> allFolders = client.GetFolders();
    FolderInfo allMail = new CommonFolders(allFolders).AllMail;
    client.Select(allMail);

    // get IMAP uid of the newest message
    long lastUid = client.GetAll().Last();

    // get message info
    MessageInfo info = client.GetMessageInfoByUID(lastUid);

    // extract Gmail thread ID
    Int64 threadId = Int64.Parse(info.Envelope.GmailThreadId);
    string threadIdAsHex = threadId.ToString"X");

    // create url
    string url = string.Format(
        "https://mail.google.com/mail/u/0/#inbox/{0}",
        threadIdAsHex);

    Console.WriteLine(url);

    client.Close();
}
' VB.NET version

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

	' select "All Mail" folder
	Dim allFolders As List(Of FolderInfo) = client.GetFolders()
	Dim allMail As FolderInfo = New CommonFolders(allFolders).AllMail
	client.[Select](allMail)

	' get IMAP uid of the newest message
	Dim lastUid As Long = client.GetAll().Last()

	' get message info
	Dim info As MessageInfo = client.GetMessageInfoByUID(lastUid)

	' extract Gmail thread ID
	Dim threadId As Int64 = Int64.Parse(info.Envelope.GmailThreadId)
	Dim threadIdAsHex As String = threadId.ToString("X")

	' create url
	Dim url As String = String.Format( _
		"https://mail.google.com/mail/u/0/#inbox/{0}", _
		threadIdAsHex)

	Console.WriteLine(url)

	client.Close()
End Using

Here you can find some more information about how to search by X-GM-THRID and all other Gmail IMAP extensions.

Gmail extensions in Mail.dll

Monday, June 13th, 2011


Here’s the list of Gmail IMAP protocol extensions implemented in Mail.dll:

  • Extension of the LIST command: XLIST
  • Extension of the SEARCH command: X-GM-RAW
  • Access to the Gmail unique message ID: X-GM-MSGID
  • Access to the Gmail thread ID: X-GM-THRID
  • Access to Gmail labels: X-GM-LABELS

You can read on how to use Mail.dll with Gmail in the following articles:

Search Gmail label

Sunday, June 12th, 2011

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.

Use the XLIST command to get the entire list of labels for a mailbox.

The labels for a given message may be retrieved by using the X-GM-LABELS attribute with the FETCH command.

It is also possible to use the X-GM-LABELS attribute to return the UIDs for all messages with a given label, using the SEARCH command.

// C# version

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

    imap.SelectInbox();

    List<long> uids = imap.Search().Where(
        Expression.GmailLabel("MyLabel"));

    foreach (MessageInfo info in imap.GetMessageInfoByUID(uids))
    {
        Console.WriteLine("{0} - {1}",
            info.Envelope.GmailThreadId,
            info.Envelope.Subject);
    }

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

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

	imap.SelectInbox()

	Dim uids As List(Of Long) = imap.Search().Where(Expression.GmailLabel("MyLabel"))

	For Each info As MessageInfo In imap.GetMessageInfoByUID(uids)
            Console.WriteLine("{0} - {1}",  _
                info.Envelope.GmailThreadId,  _
                info.Envelope.Subject)
	Next

	imap.Close()
End Using

You can learn more about this Gmail IMAP extension here:
http://code.google.com/apis/gmail/imap/#x-gm-labels