
Gmail is a popular and widely used email service provided by Google. Along with sending and receiving emails, it offers various additional features such as auto-reply, chats, etc. As a programmer, you may come across the scenario when you need to import contacts from a particular Gmail account. To accomplish that from within .NET applications, this article covers how to import Gmail contacts in C# .NET. Moreover, we will demonstrate how to fetch contacts from a specific email group.
C# .NET API to Import Gmail Contacts
To import contacts from a Gmail account, we will use Aspose.Email for .NET. It is a feature-rich API that allows you to create and send emails quite easily. Moreover, it lets you manipulate various email formats including MSG and EML. You can either download the API’s DLL or install it using NuGet.
PM> Install-Package Aspose.Email
Import Contacts from Gmail in C#
To access the contacts from a Gmail account, we need to write some code to handle the user’s information and to perform Gmail authentication. For the Gmail user, we will first create a class named TestUser and then inherit it from GoogleUser class. The following is the complete implementation of both of the classes.
using System; | |
namespace Aspose.Email | |
{ | |
internal enum GrantTypes | |
{ | |
authorization_code, | |
refresh_token | |
} | |
public class TestUser | |
{ | |
internal TestUser(string name, string eMail, string password, string domain) | |
{ | |
Name = name; | |
EMail = eMail; | |
Password = password; | |
Domain = domain; | |
} | |
public readonly string Name; | |
public readonly string EMail; | |
public readonly string Password; | |
public readonly string Domain; | |
public static bool operator ==(TestUser x, TestUser y) | |
{ | |
if ((object)x != null) | |
return x.Equals(y); | |
if ((object)y != null) | |
return y.Equals(x); | |
return true; | |
} | |
public static bool operator !=(TestUser x, TestUser y) | |
{ | |
return !(x == y); | |
} | |
public static implicit operator string(TestUser user) | |
{ | |
return user == null ? null : user.Name; | |
} | |
public override int GetHashCode() | |
{ | |
return ToString().GetHashCode(); | |
} | |
public override bool Equals(object obj) | |
{ | |
return obj != null && obj is TestUser && this.ToString().Equals(obj.ToString(), StringComparison.OrdinalIgnoreCase); | |
} | |
public override string ToString() | |
{ | |
return string.IsNullOrEmpty(Domain) ? Name : string.Format("{0}/{1}", Domain, Name); | |
} | |
} | |
public class GoogleUser : TestUser | |
{ | |
public GoogleUser(string name, string eMail, string password) | |
: this(name, eMail, password, null, null, null) | |
{ } | |
public GoogleUser(string name, string eMail, string password, string clientId, string clientSecret) | |
: this(name, eMail, password, clientId, clientSecret, null) | |
{ } | |
public GoogleUser(string name, string eMail, string password, string clientId, string clientSecret, string refreshToken) | |
: base(name, eMail, password, "gmail.com") | |
{ | |
ClientId = clientId; | |
ClientSecret = clientSecret; | |
RefreshToken = refreshToken; | |
} | |
public readonly string ClientId; | |
public readonly string ClientSecret; | |
public readonly string RefreshToken; | |
} | |
} |
Now, we need to create a helper class that will take care of the authentication of a Gmail account. We will name this class as GoogleOAuthHelper. The following is the complete implementation of this class.
using System; | |
using System.Diagnostics; | |
using System.IO; | |
using System.Net; | |
using System.Text; | |
using System.Threading; | |
using System.Windows.Forms; | |
namespace Aspose.Email | |
{ | |
internal class GoogleOAuthHelper | |
{ | |
public const string TOKEN_REQUEST_URL = "https://accounts.google.com/o/oauth2/token"; | |
public const string SCOPE = "https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcalendar" + "+" + "https%3A%2F%2Fwww.google.com%2Fm8%2Ffeeds%2F" + "+" + "https%3A%2F%2Fmail.google.com%2F"; // IMAP & SMTP | |
public const string REDIRECT_URI = "urn:ietf:wg:oauth:2.0:oob"; | |
public const string REDIRECT_TYPE = "code"; | |
internal static string GetAccessToken(TestUser user) | |
{ | |
return GetAccessToken((GoogleUser)user); | |
} | |
internal static string GetAccessToken(GoogleUser user) | |
{ | |
string access_token; | |
string token_type; | |
int expires_in; | |
GetAccessToken(user, out access_token, out token_type, out expires_in); | |
return access_token; | |
} | |
internal static void GetAccessToken(GoogleUser user, out string access_token, out string token_type, out int expires_in) | |
{ | |
access_token = null; | |
token_type = null; | |
expires_in = 0; | |
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(TOKEN_REQUEST_URL); | |
request.CookieContainer = new CookieContainer(); | |
request.Method = "POST"; | |
request.ContentType = "application/x-www-form-urlencoded"; | |
string encodedParameters = string.Format("client_id={0}&client_secret={1}&refresh_token={2}&grant_type={3}", | |
System.Web.HttpUtility.UrlEncode(user.ClientId), System.Web.HttpUtility.UrlEncode(user.ClientSecret), System.Web.HttpUtility.UrlEncode(user.RefreshToken), System.Web.HttpUtility.UrlEncode(GrantTypes.refresh_token.ToString())); | |
byte[] requestData = Encoding.UTF8.GetBytes(encodedParameters); | |
request.ContentLength = requestData.Length; | |
if (requestData.Length > 0) | |
using (Stream stream = request.GetRequestStream()) | |
stream.Write(requestData, 0, requestData.Length); | |
HttpWebResponse response = (HttpWebResponse)request.GetResponse(); | |
string responseText = null; | |
using (TextReader reader = new StreamReader(response.GetResponseStream(), Encoding.ASCII)) | |
responseText = reader.ReadToEnd(); | |
foreach (string sPair in responseText.Replace("{", "").Replace("}", "").Replace("\"", "").Split(new string[] { ",\n" }, StringSplitOptions.None)) | |
{ | |
string[] pair = sPair.Split(':'); | |
string name = pair[0].Trim().ToLower(); | |
string value = System.Web.HttpUtility.UrlDecode(pair[1].Trim()); | |
switch (name) | |
{ | |
case "access_token": | |
access_token = value; | |
break; | |
case "token_type": | |
token_type = value; | |
break; | |
case "expires_in": | |
expires_in = Convert.ToInt32(value); | |
break; | |
} | |
} | |
Debug.WriteLine(""); | |
Debug.WriteLine("---------------------------------------------------------"); | |
Debug.WriteLine("-----------OAuth 2.0 authorization information-----------"); | |
Debug.WriteLine("---------------------------------------------------------"); | |
Debug.WriteLine(string.Format("Login: '{0}'", user.EMail)); | |
Debug.WriteLine(string.Format("Access token: '{0}'", access_token)); | |
Debug.WriteLine(string.Format("Token type: '{0}'", token_type)); | |
Debug.WriteLine(string.Format("Expires in: '{0}'", expires_in)); | |
Debug.WriteLine("---------------------------------------------------------"); | |
Debug.WriteLine(""); | |
} | |
internal static void GetAccessToken(TestUser user, out string access_token, out string refresh_token) | |
{ | |
GetAccessToken((GoogleUser)user, out access_token, out refresh_token); | |
} | |
internal static void GetAccessToken(GoogleUser user, out string access_token, out string refresh_token) | |
{ | |
string token_type; | |
int expires_in; | |
GoogleOAuthHelper.GetAccessToken(user, out access_token, out refresh_token, out token_type, out expires_in); | |
} | |
internal static void GetAccessToken(TestUser user, out string access_token, out string refresh_token, out string token_type, out int expires_in) | |
{ | |
GetAccessToken((GoogleUser)user, out access_token, out refresh_token, out token_type, out expires_in); | |
} | |
internal static void GetAccessToken(GoogleUser user, out string access_token, out string refresh_token, out string token_type, out int expires_in) | |
{ | |
string authorizationCode = GoogleOAuthHelper.GetAuthorizationCode(user, GoogleOAuthHelper.SCOPE, GoogleOAuthHelper.REDIRECT_URI, GoogleOAuthHelper.REDIRECT_TYPE); | |
GoogleOAuthHelper.GetAccessToken(authorizationCode, user, out access_token, out token_type, out expires_in, out refresh_token); | |
} | |
internal static void GetAccessToken(string authorizationCode, TestUser user, out string access_token, out string token_type, out int expires_in, out string refresh_token) | |
{ | |
GetAccessToken(authorizationCode, (GoogleUser)user, out access_token, out token_type, out expires_in, out refresh_token); | |
} | |
internal static void GetAccessToken(string authorizationCode, GoogleUser user, out string access_token, out string token_type, out int expires_in, out string refresh_token) | |
{ | |
access_token = null; | |
token_type = null; | |
expires_in = 0; | |
refresh_token = null; | |
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(TOKEN_REQUEST_URL); | |
request.CookieContainer = new CookieContainer(); | |
request.Method = "POST"; | |
request.ContentType = "application/x-www-form-urlencoded"; | |
string encodedParameters = string.Format("client_id={0}&code={1}&client_secret={2}&redirect_uri={3}&grant_type={4}", System.Web.HttpUtility.UrlEncode(user.ClientId), System.Web.HttpUtility.UrlEncode(authorizationCode), System.Web.HttpUtility.UrlEncode(user.ClientSecret), System.Web.HttpUtility.UrlEncode(REDIRECT_URI), System.Web.HttpUtility.UrlEncode(GrantTypes.authorization_code.ToString())); | |
byte[] requestData = Encoding.UTF8.GetBytes(encodedParameters); | |
request.ContentLength = requestData.Length; | |
if (requestData.Length > 0) | |
using (Stream stream = request.GetRequestStream()) | |
stream.Write(requestData, 0, requestData.Length); | |
HttpWebResponse response = (HttpWebResponse)request.GetResponse(); | |
string responseText = null; | |
using (TextReader reader = new StreamReader(response.GetResponseStream(), Encoding.ASCII)) | |
responseText = reader.ReadToEnd(); | |
foreach (string sPair in responseText.Replace("{", "").Replace("}", "").Replace("\"", "").Split(new string[] { ",\n" }, StringSplitOptions.None)) | |
{ | |
string[] pair = sPair.Split(':'); | |
string name = pair[0].Trim().ToLower(); | |
string value = System.Web.HttpUtility.UrlDecode(pair[1].Trim()); | |
switch (name) | |
{ | |
case "access_token": | |
access_token = value; | |
break; | |
case "token_type": | |
token_type = value; | |
break; | |
case "expires_in": | |
expires_in = Convert.ToInt32(value); | |
break; | |
case "refresh_token": | |
refresh_token = value; | |
break; | |
} | |
} | |
Debug.WriteLine(string.Format("Authorization code: '{0}'", authorizationCode)); | |
Debug.WriteLine(string.Format("Access token: '{0}'", access_token)); | |
Debug.WriteLine(string.Format("Refresh token: '{0}'", refresh_token)); | |
Debug.WriteLine(string.Format("Token type: '{0}'", token_type)); | |
Debug.WriteLine(string.Format("Expires in: '{0}'", expires_in)); | |
Debug.WriteLine("---------------------------------------------------------"); | |
Debug.WriteLine(""); | |
} | |
internal static string GetAuthorizationCode(TestUser acc, string scope, string redirectUri, string responseType) | |
{ | |
return GetAuthorizationCode((GoogleUser)acc, scope, redirectUri, responseType); | |
} | |
internal static string GetAuthorizationCode(GoogleUser acc, string scope, string redirectUri, string responseType) | |
{ | |
Debug.WriteLine(""); | |
Debug.WriteLine("---------------------------------------------------------"); | |
Debug.WriteLine("-----------OAuth 2.0 authorization information-----------"); | |
Debug.WriteLine("---------------------------------------------------------"); | |
Debug.WriteLine(string.Format("Login: '{0}'", acc.EMail)); | |
string authorizationCode = null; | |
string error = null; | |
string approveUrl = string.Format("https://accounts.google.com/o/oauth2/auth?redirect_uri={0}&response_type={1}&client_id={2}&scope={3}", redirectUri, responseType, acc.ClientId, scope); | |
AutoResetEvent are0 = new AutoResetEvent(false); | |
Thread t = new Thread(delegate () | |
{ | |
bool doEvents = true; | |
WebBrowser browser = new WebBrowser(); | |
browser.AllowNavigation = true; | |
browser.DocumentCompleted += delegate (object sender, WebBrowserDocumentCompletedEventArgs e) { doEvents = false; }; | |
Form f = new Form(); | |
f.FormBorderStyle = FormBorderStyle.FixedToolWindow; | |
f.ShowInTaskbar = false; | |
f.StartPosition = FormStartPosition.Manual; | |
f.Location = new System.Drawing.Point(-2000, -2000); | |
f.Size = new System.Drawing.Size(1, 1); | |
f.Controls.Add(browser); | |
f.Load += delegate (object sender, EventArgs e) | |
{ | |
try | |
{ | |
browser.Navigate("https://accounts.google.com/Logout"); | |
doEvents = true; | |
while (doEvents) Application.DoEvents(); | |
browser.Navigate("https://accounts.google.com/ServiceLogin?sacu=1"); | |
doEvents = true; | |
while (doEvents) Application.DoEvents(); | |
HtmlElement loginForm = browser.Document.Forms["gaia_loginform"]; | |
if (loginForm != null) | |
{ | |
HtmlElement userName = browser.Document.All["Email"]; | |
userName.SetAttribute("value", acc.EMail); | |
loginForm.InvokeMember("submit"); | |
doEvents = true; | |
while (doEvents) | |
Application.DoEvents(); | |
loginForm = browser.Document.Forms["gaia_loginform"]; | |
HtmlElement passwd = browser.Document.All["Passwd"]; | |
passwd.SetAttribute("value", acc.Password); | |
loginForm.InvokeMember("submit"); | |
doEvents = true; | |
while (doEvents) | |
Application.DoEvents(); | |
} | |
else | |
{ | |
error = "Login form is not found in \n" + browser.Document.Body.InnerHtml; | |
return; | |
} | |
browser.Navigate(approveUrl); | |
doEvents = true; | |
while (doEvents) Application.DoEvents(); | |
HtmlElement approveForm = browser.Document.Forms["connect-approve"]; | |
if (approveForm != null) | |
{ | |
HtmlElement submitAccess = browser.Document.All["submit_access"]; | |
submitAccess.SetAttribute("value", "true"); | |
approveForm.InvokeMember("submit"); | |
doEvents = true; | |
while (doEvents) | |
Application.DoEvents(); | |
} | |
else | |
{ | |
error = "Approve form is not found in \n" + browser.Document.Body.InnerHtml; | |
return; | |
} | |
HtmlElement code = browser.Document.All["code"]; | |
if (code != null) | |
authorizationCode = code.GetAttribute("value"); | |
else | |
error = "Authorization code is not found in \n" + browser.Document.Body.InnerHtml; | |
} | |
catch (Exception ex) | |
{ | |
error = ex.Message; | |
} | |
finally | |
{ | |
f.Close(); | |
} | |
}; | |
Application.Run(f); | |
are0.Set(); | |
}); | |
t.SetApartmentState(ApartmentState.STA); | |
t.Start(); | |
are0.WaitOne(); | |
if (error != null) | |
throw new Exception(error); | |
return authorizationCode; | |
} | |
} | |
} |
C# Import Contacts from a Gmail Account
At this stage, we are ready to access contacts in a Gmail account. The following are the steps to import contacts from a Gmail account in C#.
- Create an object of GoogleUser class and initialize it with name, email, password, client ID and client secret.
- Create two string objects to store access token and refresh token.
- Call GoogleOAuthHelper.GetAccessToken(GoogleUser, out string, out string) method to get the access and refresh tokens.
- Get an instance of GmailClient class into an IGmailClient object.
- Create an array of Contact and get all the contacts using IGmailClient.GetAllContacts() method.
- Loop through array to access each contact.
The following code sample shows how to import contacts from a Gmail account in C#.
// Create a Google user | |
GoogleUser User = new GoogleUser("user", "email address", "password", "clientId", "client secret"); | |
string accessToken; | |
string refreshToken; | |
// Get access token | |
GoogleOAuthHelper.GetAccessToken(User, out accessToken, out refreshToken); | |
// Get IGmailclient | |
using (IGmailClient client = GmailClient.GetInstance(accessToken, User.EMail)) | |
{ | |
// Access contacts | |
Contact[] contacts = client.GetAllContacts(); | |
foreach (Contact contact in contacts) | |
Console.WriteLine(contact.DisplayName + ", " + contact.EmailAddresses[0]); | |
} |
Import Gmail Contacts from a Group in C#
You can also access contacts from a specific email group in Gmail. The following are the steps to perform this operation.
- Create an object of GoogleUser class and initialize it with name, email, password, client ID and client secret.
- Create two string objects to store access token and refresh token.
- Call GoogleOAuthHelper.GetAccessToken(GoogleUser, out string, out string) method to get the access token.
- Get an instance of GmailClient class into an IGmailClient object.
- Get all email groups into a ContactGroupCollection object using IGmailClient.GetAllGroups() method.
- Access the desired GoogleContactGroup using its name.
- Create an array of Contact and get all the contacts from group using IGmailClient.GetContactsFromGroup(string) method.
- Loop through array to access each contact.
The following code sample shows how to import contacts from a specific email group in C#.
// Create a Google user | |
GoogleUser User = new GoogleUser("user", "email address", "password", "clientId", "client secret"); | |
string accessToken; | |
string refreshToken; | |
// Get access token | |
GoogleOAuthHelper.GetAccessToken(User, out accessToken, out refreshToken); | |
// Get IGmailclient | |
using (IGmailClient client = GmailClient.GetInstance(accessToken, User.EMail)) | |
{ | |
// Fetch contacts from a specific group | |
ContactGroupCollection groups = client.GetAllGroups(); | |
GoogleContactGroup group = null; | |
foreach (GoogleContactGroup g in groups) | |
switch (g.Title) | |
{ | |
case "TestGroup": | |
group = g; | |
break; | |
} | |
// Retrieve contacts from the Group | |
if (group != null) | |
{ | |
Contact[] contacts2 = client.GetContactsFromGroup(group.Id); | |
foreach (Contact con in contacts2) | |
Console.WriteLine(con.DisplayName + "," + con.EmailAddresses[0].ToString()); | |
} | |
} |
C# API to Import Gmail Contacts - Get a Free License
You can get a free temporary license to use Aspose.Email for .NET without evaluation limitations.
Conclusion
In this article, you have learned how to import Gmail contacts from accounts programmatically in C#. Moreover, you have seen how to access contacts from a particular email group in Gmail. Besides, you can explore other features of Aspose.Email for .NET using the documentation. Also, you can ask your questions via our forum.