Posts Tagged ‘GMail’

OAuth with IMAP

Monday, June 28th, 2010

OAuth is an open protocol to allow secure API authorization in a simple and standard method from desktop and web applications.

In this post I’ll show how to access GMail account using OAuth authentication method. The key advantage of this method is that it allows an application to access users email without knowing user’s password.

You can read more on OAuth authentication with Google accounts here:
http://code.google.com/apis/accounts/docs/OAuth_ref.html

Gmail IMAP and SMTP using OAuth:
http://code.google.com/apis/gmail/oauth/protocol.html

If your application is not registered, please select HMAC-SHA1 and use the following key and secret:
consumer key: “anonymous”
consumer secret: “anonymous”

You can manage your domains here:
https://www.google.com/accounts/ManageDomains

The following code makes several HTTP requests to authenticate your application. It also fires up the web browser, so the user can allow or deny the application to access his emails.

const string userEmailAccount = "alice@gmail.com";
const string consumerKey = "anonymous";
const string consumerSecret = "anonymous";

// First: get request token
ParameterList parameters1 = OAuth.ForUrl(
        "https://www.google.com/accounts/OAuthGetRequestToken")
    .Consumer(consumerKey, consumerSecret)
    .AddParameter("scope", "https://mail.google.com/")
    .AddParameter(OAuthParameterName.OAuthCallback, "oob")
    .Sign()
    .ExecuteWebRequest();

// Second: user interaction
string url2 = OAuth.ForUrl(
        "https://www.google.com/accounts/OAuthAuthorizeToken")
   .Consumer(consumerKey, consumerSecret)
   .Token(parameters1.GetValue(OAuthParameterName.OAuthToken))
   .TokenSecret(parameters1.GetValue(OAuthParameterName.OAuthTokenSecret))
   .Sign()
   .GetUrl();

// Fire up the browser
Process.Start(url2);
Console.WriteLine("Please enter the key: ");
string key = Console.ReadLine().Trim();

// Third: get access token
ParameterList parameters3 = OAuth.ForUrl(
        "https://www.google.com/accounts/OAuthGetAccessToken")
   .Consumer(consumerKey, consumerSecret)
   .Token(parameters1.GetValue(OAuthParameterName.OAuthToken))
   .TokenSecret(parameters1.GetValue(OAuthParameterName.OAuthTokenSecret))
   .AddParameter("oauth_verifier", key)
   .Sign()
   .ExecuteWebRequest();

// Log-in to IMAP server using XOAuth
using (Imap client = new Imap())
{
    client.ConnectSSL(TestConstants.GmailImapServer);

    string imapUrl = string.Format(
        "https://mail.google.com/mail/b/{0}/imap/", userEmailAccount);

    string oauthImapKey = OAuth.ForUrl(imapUrl)
        .Consumer(consumerKey, consumerSecret)
        .Token(parameters3.GetValue(OAuthParameterName.OAuthToken))
        .TokenSecret(parameters3.GetValue(OAuthParameterName.OAuthTokenSecret))
        .Sign()
        .GetXOAuthKey();

    client.LoginOAUTH(oauthImapKey);

    // Now you can access user's emails.

    client.Close(true);
}

New Mail.dll tutorial video

Wednesday, April 7th, 2010

New Mail.dll tutorial video is out. You can watch it here:

Mail.dll tutorial video.

Delete email permanently in GMail

Tuesday, March 23rd, 2010

If you delete a message from your Inbox or one of your custom folders, it will still appear in [Gmail]/All Mail.

Here’s why: in most folders, deleting a message simply removes that folder’s label from the message, including the label identifying the message as being in your Inbox.

[Gmail]/All Mail shows all of your messages, whether or not they have labels attached to them.

If you want to permanently delete a message from all folders:

  1. Move it to the [Gmail]/Trash folder.
  2. Delete it from the [Gmail]/Trash folder.

All emails in [Gmail]/Spam and [Gmail]/Trash are deleted after 30 days.
If you delete a message from [Gmail]/Spam or [Gmail]/Trash, it will be deleted permanently.

Here’s how this looks like using Mail.dll IMAP client:

// C# version:

using(Imap imap = new Imap())
{
	imap.Connect("imap.gmail.com");
	imap.Login("user", "password");

	// Find all emails we want to delete
	imap.SelectInbox();
	List<long> uids = imap.Search(
		Expression.Subject("email to delete"));

	// Delete each email permanently
	foreach (long uid in uids)
	{
		// Move to Trash
		long uidInTrash = (long)imap.MoveByUID(uid, "[Gmail]/Trash");

		// Delete from Trash
		imap.Select("[Gmail]/Trash");
		imap.DeleteMessageByUID(uidInTrash);
	}
	imap.Close(true);
}
' VB.NET version:

Using imap As New Imap()
	imap.Connect("imap.gmail.com")
	imap.Login("user@gmail.com", "password")

	' Find all emails we want to delete
	imap.SelectInbox()
	Dim uids As List(Of Long) = imap.Search(_
		Expression.Subject("email to delete"))

	' Delete each email permanently
	For Each uid As Long In uids
		' Move to Trash
		Dim uidInTrash As Long = imap.MoveByUID(uid, "[Gmail]/Trash")

		' Delete from Trash
		imap.[Select]("[Gmail]/Trash")
		imap.DeleteMessageByUID(uidInTrash)
	Next
	imap.Close(True)
End Using

Localized GMail IMAP Folders

Monday, March 22nd, 2010


There are no well-know names for common folders such as Drafts, Trash, Spam, … on IMAP servers.

The problem is even worse when you use localized version of IMAP client. GMail folder names are localized with respect to the user localization settings, so ‘[Gmail]/All Mail’ show as ‘[Gmail]/Todos’ to Spanish users for example.

Google and Apple developed a special IMAP command XLIST to address this issue.

IMAP XLIST command returns a list of folders and their well-know flags (\Inbox, \Drafts, \Trash, \Sent, \Spam).

Mail.dll IMAP client supports XLIST command. It is used automatically when server advertises support for this feature.

Take a look at the examples:

// C# version:

using (Imap imap = new Imap())
{
    imap.Connect("imap.gmail.com");
    imap.Login("user", "password");

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

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

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

Using imap As New Imap()
	imap.Connect("imap.gmail.com")
	imap.Login("user", "password")

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

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

	imap.Close(True)
End Using

Uploading emails using IMAP

Monday, January 4th, 2010

Uploading emails to the IMAP server is fairly easy with Mail.dll IMAP client

First we’ll use Mail.dll to upload an existing email in eml format to the IMAP server:

// C# code

using (Imap imap = new Imap())
{
    imap.Connect("server");
    imap.Login("user", "password");

    string eml = File.ReadAllText("email.eml");

    // The name of the folder depends on your IMAP server
    imap.UploadMessage("[Gmail]/Sent Mail", eml);

    imap.Close(true);
}
' VB.NET code

Using imap As New Imap()
	imap.Connect("server")
	imap.Login("user", "password")

	Dim eml As String = File.ReadAllText("email.eml")

	' The name of the folder depends on your IMAP server
	imap.UploadMessage("[Gmail]/Sent Mail", eml)

	imap.Close(True)
End Using

Second sample shows how to create new email message and upload it to IMAP server.

// C# code

using (Imap imap = new Imap())
{
    imap.Connect("server");
    imap.Login("user", "password");

    // Create new mail message
    MailBuilder builder = new MailBuilder();
    builder.Subject = "subject";
    builder.From.Add(new MailBox("alice@email.com", "Alice"));
    builder.To.Add(new MailBox("bob@email.com", "Bob"));
    builder.SetTextData("This is plain text email");

    // Upload
    // The name of the folder depends on your IMAP server
    imap.UploadMessage("[Gmail]/Sent Mail", builder.Create());

    imap.Close(true);
}
' VB.NET code

Using imap As New Imap()
	imap.Connect("server")
	imap.Login("user", "password")

	' Create new mail message
	Dim builder As New MailBuilder()
	builder.Subject = "subject"
	builder.From.Add(New MailBox("alice@email.com", "Alice"))
	builder.[To].Add(New MailBox("bob@email.com", "Bob"))
	builder.SetTextData("This is plain text email")

	' Upload
	' The name of the folder depends on your IMAP server
	imap.UploadMessage("[Gmail]/Sent Mail", builder.Create())

	imap.Close(True)
End Using

Please note that only few IMAP servers are going to send the message to the actual recipients. Most servers will only upload the message without sending it.
You should use SMTP protocol for this.
You can download Mail.dll IMAP client here.