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.UseBestLogin("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.UseBestLogin("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)
Posted in Mail.dll | Tags: C#, IMAP, IMAP component, SPECIAL-USE, VB.NET, XLIST
Consider using OAuth 2.0:
https://www.limilabs.com/blog/get-google-contacts-with-oauth2
Although neither POP3 nor IMAP protocol allows retrieving the list of user’s contacts, it is possible to use Google API for that.
As long as you are using OAuth to access Gmail, Mail.dll email component allows you to easy download Gmail contacts of a particular user.
// C#
GmailOAuth oauth = new GmailOAuth(_consumerKey, _consumerSecret);
List<GoogleScope> scopes = new List<GoogleScope>;
{
GoogleScope.EmailScope,
GoogleScope.ContactsScope
};
string authUrl = oauth.GetAuthorizationUrl("http://localhost:64119/", scopes);
// ASP.NET client:
// Save oauth in permanent storage:
// Cache[oauth.RequestToken.Token] = oauth;
// Windows client:
Process.Start(url);
// ASP.NET client:
// Response.Redirect(url);
// Windows client with url:
string rawReturnUrl = Console.ReadLine();
ReturnUrl returnUrl = new ReturnUrl(rawReturnUrl);
oauth.GetAccessToken(returnUrl.OAuthVerifier);
// Windows client with verification code (oob):
// string oauthVerifier = HttpUtility.UrlDecode(Console.ReadLine());
// oauth.GetAccessToken(oauthVerifier);
// ASP.NET client:
// ReturnUrl returnUrl = new ReturnUrl(Request.RawUrl);
// Retrieve oauth from permanent storage:
// GmailOAuth oauth = Cache[returnUrl.OAuthToken]
// oauth.GetAccessToken(returnUrl.OAuthVerifier);
GoogleApi google = new GoogleApi(oauth.ConsumerToken, oauth.AccessToken);
XmlDocument contacts = google.GetContacts();
XmlNamespaceManager nsmgr = new XmlNamespaceManager(contacts.NameTable);
nsmgr.AddNamespace("gd", "http://schemas.google.com/g/2005");
nsmgr.AddNamespace("a", "http://www.w3.org/2005/Atom");
foreach (XmlNode contact in contacts.GetElementsByTagName("entry"))
{
XmlNode title = contact.SelectSingleNode("a:title", nsmgr);
XmlNode email = contact.SelectSingleNode("gd:email", nsmgr);
Console.WriteLine("{0}: {1}",
title.InnerText,
email.Attributes["address"].Value);
}
oauth.RevokeToken(oauth.AccessToken.Token);
' VB.NET
Dim oauth As New GmailOAuth(_consumerKey, _consumerSecret)
Dim scopes As New List(Of GoogleScope)() { _
GoogleScope.EmailScope, _
GoogleScope.ContactsScope _
}
Dim authUrl As String = oauth.GetAuthorizationUrl("http://localhost:64119/", scopes)
' ASP.NET client:
' Save oauth in permanent storage:
' Cache[oauth.RequestToken.Token] = oauth;
' Windows client:
Process.Start(url)
' ASP.NET client:
' Response.Redirect(url)
' Windows client with url:
Dim rawReturnUrl As String = Console.ReadLine()
Dim returnUrl As New ReturnUrl(rawReturnUrl)
oauth.GetAccessToken(returnUrl.OAuthVerifier)
' Windows client with verification code (oob):
' Dim oauthVerifier As String = HttpUtility.UrlDecode(Console.ReadLine())
' oauth.GetAccessToken(oauthVerifier)
' ASP.NET client:
' Dim returnUrl As New ReturnUrl(Request.RawUrl)
' Retrive oauth from permanent storage:
' Dim oauth As GmailOAuth = Cache(returnUrl.OAuthToken)
' oauth.GetAccessToken(returnUrl.OAuthVerifier)
Dim google As New GoogleApi(oauth.ConsumerToken, oauth.AccessToken)
Dim contacts As XmlDocument = google.GetContacts()
Dim nsmgr As New XmlNamespaceManager(contacts.NameTable)
nsmgr.AddNamespace("gd", "http://schemas.google.com/g/2005")
nsmgr.AddNamespace("a", "http://www.w3.org/2005/Atom")
For Each contact As XmlNode In contacts.GetElementsByTagName("entry")
Dim title As XmlNode = contact.SelectSingleNode("a:title", nsmgr)
Dim email As XmlNode = contact.SelectSingleNode("gd:email", nsmgr)
Console.WriteLine("{0}: {1}", _
title.InnerText, _
email.Attributes("address").Value)
Next
oauth.RevokeToken(oauth.AccessToken.Token)
Posted in Mail.dll | Tags: Email component, Gmail, OAuth
Mail.dll MIME and email component may be used to retrieve plain-text body or HTML body from an email message.
If a message contains HTML, no conversion is necessary. You just need to use HTML property of IMail interface.
If however an email does not contain HTML and only plain-text content is available, many times plain-text needs be converted to HTML.
You can use GetBodyAsHtml method that always returns body in HTML format (it uses IMail.HTML property or creates valid HTML from IMail.Text).
// C#
IMail email = ...
string html = email.GetBodyAsHtml();
Console.WriteLine(html);
' VB.NET
Dim email As IMail = ...
Dim html As String = email.GetBodyAsHtml()
Console.WriteLine(html)
Posted in Mail.dll | Tags: C#, Email component, HTML, VB.NET
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.UseBestLogin("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.UseBestLogin("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.UseBestLogin("pat@gmail.com", "password");
List<FolderInfo> folders = imap.GetFolders();
imap.SelectInbox();
long last = imap.GetAll().Last();
imap.CopyByUID(last, new CommonFolders(folders).Flagged);
imap.Close();
}
' VB.NET
Using imap As New Imap()
imap.ConnectSSL("imap.gmail.com")
imap.UseBestLogin("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).Flagged)
imap.Close()
End Using
Posted in Mail.dll | Tags: C#, Gmail, IMAP, IMAP component, VB.NET, X-GM-LABELS
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:
Inbox
Personal
Receipts
Travel
Upload
Work
my label
my label/nested
my second label
Posted in Mail.dll | Tags: C#, Gmail, IMAP, IMAP component, VB.NET, X-GM-LABELS