Click here to Skip to main content
15,499,967 members
Articles / Programming Languages / C#
Posted 6 Jul 2004


198 bookmarked

Gmail Agent API v0.5 / Mail Notifier & Address Importer

Rate me:
Please Sign up or sign in to vote.
4.97/5 (64 votes)
6 Jul 20046 min read
Open source Gmail API in C#

Image 1

Image 2

Image 3

What is it?

There are two distinct components here: an open source Gmail API written for the .NET framework, and a proof of concept Windows application built on top of that API that provides basic remote Gmail functions.

I developed these tools in the hopes of encouraging others to create interesting Gmail services. Admittedly, this project may not have a very long shelf life, as Sergey has intimated possible mail forwarding and RSS support, not to mention Gmail's recent listing of upcoming features (Gmail login required) that estimates a slew of features that are listed as “working on it” or “we'll try”. The address book import is currently listed as “sometime soon” but it's actually available now in the Contacts window. As Sergey mentioned, an enterprise version of Gmail would be well received, and I have no doubt that there would an API to go along with that (I recently integrated a Google Search Appliance, and can attest to its extensibility). Whether or not Google is interested in pursuing such features for the public side remains to be seen. Nonetheless, I hope to keep this project going, and wouldn't mind joining the Gmail team — there are lots of features I'd like to see implemented in Gmail.

About the Gmail Agent Applet

I'm sure most of you are more interested in the applet, so here are the features:

  • Multiple account support
  • Balloon notification of new messages with message preview
  • Address book view and import (from tab-delimited text files)

The system requirements are:

  • Windows 2000, or higher
  • Microsoft .NET Framework v1.1

I haven't tried this with Mono — I doubt it works, but if it does, please let me know. If you are interested in POP access to Gmail, check out Pop Goes the Gmail (also a .NET project).

This is a proof of concept application, and there are plenty of idiosyncrasies. It works great for me, but your results may vary. I welcome anyone who wants to contribute to polishing this app.

About the Gmail Agent API

The goal of the API is to provide an extensible foundation for interfacing with Gmail. The objects in this namespace should be abstracted enough to be able to be adapted to any future changes Gmail makes.

Read the documentation for Gmail Agent API 0.5 to see what's available.

The main workhorse of this class is GmailAdapter. It is responsible for communicating with Gmail and maintaining the login and session information through the duration of the application. The GmailSession object holds all the state information for a single Gmail account, including a GmailThreadCollection of GmailThread objects. The GmailContact object represents a single Gmail address book entry. Again, GmailAdapter provides the methods to fill a GmailContact with information from Gmail.

Connection Overview

Image 4

One oddity with the API is that it uses TLS instead of SSL for the encryption layer. For reasons unknown, the SSL provider was extremely intermittent and often failed to establish a secure link so I manually set the ServicePointManager to use TLS 1.0. This seems to be a common problem among .NET developers, and if anyone has a stable solution, I'd love to hear about it.

Here is a bare-bones example of how to establish a connection with Gmail using the API:

// init new adapter
GmailAdapter gmail = new GmailAdapter();

// create new session and assign username and password
GmailSession myAccount = new GmailSession();
myAccount.Username = "googler";
myAccount.Password = "showmethemoney";

// login and retrieve mailbox info
GmailAdapter.RequestResponseType loginResult = gmail.Refresh(myAccount);

// display mailbox info
if(loginResult == GmailAdapter.RequestResponseType.Success) {

    // show new inbox count
    Console.WriteLine("New Threads: " + myAccount.DefaultSearchCounts["Inbox"]);

    // if new threads exist, show the subject of the first one
    if(myAccount.UnreadThreads.Count > 0) {
        GmailThread newThread = (GmailThread)myAccount.UnreadThreads[0];
        Console.WriteLine("Latest thread subject: " + newThread.SubjectHtml);

About the Gmail engine and protocol

You've probably noticed that Gmail's interface is extremely fast when compared to other web-based email systems like Yahoo! Mail and Hotmail. This is a result of Gmail's placement of the UI engine on the client-side as a JavaScript module. Whenever you log in to Gmail, a copy of the UI engine is loaded into one of the HTML page frames and remains there for the duration of your session (credit has to be given to Oddpost for being the first ones who perfected this idea). Subsequent actions from the Gmail interface are then routed through the Gmail UI engine in your browser, which in turn makes HTTP requests (via the XmlHttpRequest object) to the Gmail server, interprets the DataPack (more on this later), and updates the UI dynamically. In contrast, Hotmail and Yahoo! Mail follow traditional web application models and reload the entire UI after almost every action.

The item most relevant to this project is what I refer to as the “DataPack”, a base HTML file that contains only JavaScript array declarations that the UI engine parses and then uses to determine what to update. The advantages of this should be immediately obvious: reduced traffic load, and increased functionality — especially for developers who no longer have to resort to crude “screen scraping” techniques to interface with web applications. Although the ideal situation for external developers would be an XML-based DataPack, the JavaScript version is sufficient (and I suspect it was chosen for performance reasons as well).

The DataPack format consists of individual “DataItems”, or JavaScript arrays wrapped in a envelope function. An example:


The function D() references a runtime evaluator within the Gmail engine, which then interprets the attached array parameters. The "ts" element indicates that this is a threadlist summary item, and the subsequent elements denote start index, threads per page, estimated total, threadlist title, threadlist timestamp, and total threads. This is the same format that is applied to all array parameters sent through the DataPack:


The mappings to all the DataItems can be found in the engine code source (/gmail?view=page&name=js). For instance, qu contains quota information, while ct contains category (a.k.a. labels) definitions. Read through that file if you really want to get everything you can out of Gmail.

Determining the right URL to retrieve the DataPack is pretty straightforward, as most requests will return the same basic information, such as quota, category count, and inbox count. The main thing that changes is the threadlist summary, which depends on what page you're looking at. All the main folders — inbox, starred, trash, spam, etc. — are all really just pre-defined searches within Gmail. For example, the inbox DataPack URL is:


The search query for all unread threads is:


The main parameters are search= and q=, which define what set of threads the user is requesting. The zx= parameter is a proxy cache defeater, and I've omitted it here for brevity. See GmailAdapter.MakeUniqueUrl() for more information.

Gmail exploits another advantage of the DataPack model to increase efficiency by allowing for an empty document. This is employed by the 2-minute auto-refresh request. The inbox URL adds a few more parameters:


The tlt= parameter is the thread list timestamp, which is treated like a checksum in determining the state of the client versus the mailbox state on the server. If the client timestamp is older than the one on the server, then a full DataPack is sent. Otherwise, Gmail sends an essentially empty DataPack.


Feel free to contact me with any questions. Or, you can just leave a comment over here.


This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Written By
Web Developer
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

QuestionUnable to find GV cookie value !!? Pin
AbuSaloum11-Jun-13 6:41
MemberAbuSaloum11-Jun-13 6:41 
QuestionException in GMailAdapter Pin
Member 834084929-Oct-11 0:35
MemberMember 834084929-Oct-11 0:35 
GeneralCross-thread operation not valid: Control '' accessed from a thread other than the thread it was created on. Pin
varbace27-Apr-11 1:37
Membervarbace27-Apr-11 1:37 
Generalsame here...not getting access to account Pin
sawantprashant6-Jul-10 21:20
Membersawantprashant6-Jul-10 21:20 
GeneralLogin Failed Even after giving the valid credentials. Pin
Madhukar Mudunuru11-Sep-07 4:40
MemberMadhukar Mudunuru11-Sep-07 4:40 
GeneralCode is not working Pin
kulvinder_200026-Jul-07 2:49
Memberkulvinder_200026-Jul-07 2:49 
Generalimport contacts from any mail Pin
neerubee11-Jul-07 1:11
Memberneerubee11-Jul-07 1:11 
GeneralRe: import contacts from any mail Pin
Rahana A27-Jul-09 1:14
MemberRahana A27-Jul-09 1:14 
GeneralSample for gmail contact Pin
wailoon.ho30-May-07 20:16
Memberwailoon.ho30-May-07 20:16 
GeneralRe: Sample for gmail contact Pin
Johnvey Hwang30-May-07 21:18
MemberJohnvey Hwang30-May-07 21:18 
GeneralRe: Sample for gmail contact Pin
wailoon.ho30-May-07 21:39
Memberwailoon.ho30-May-07 21:39 
QuestionIt's not working Pin
H. S. Masud22-May-06 2:32
MemberH. S. Masud22-May-06 2:32 
I tried to use it. I setup my account. But I'm getting an exception while I check the address book. Here is the exception....

See the end of this message for details on invoking
just-in-time (JIT) debugging instead of this dialog box.

************** Exception Text **************
System.ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection.
Parameter name: startIndex
at System.Globalization.CompareInfo.IndexOfString(Void* pSortingTable, Int32 win32LCID, String source, String value, Int32 startIndex, Int32 count, Int32 options)
at System.Globalization.CompareInfo.IndexOf(String source, String value, Int32 startIndex)
at Johnvey.GmailAgent.GmailAdapter.GetContacts()
at Johnvey.GmailAgent.Applet.Contacts.UpdateGmailContacts(GmailSession workingSession)
at Johnvey.GmailAgent.Applet.Contacts.accountsList_onChange(Object sender, EventArgs e)
at System.Windows.Forms.ComboBox.OnSelectedIndexChanged(EventArgs e)
at System.Windows.Forms.ComboBox.WmReflectCommand(Message& m)
at System.Windows.Forms.ComboBox.WndProc(Message& m)
at System.Windows.Forms.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

************** Loaded Assemblies **************
Assembly Version: 1.0.5000.0
Win32 Version: 1.1.4322.573
CodeBase: file:///c:/windows/
Assembly Version:
Win32 Version:
CodeBase: file:///C:/Program%20Files/Gmail%20Agent/GmailAgent.exe
Assembly Version: 1.0.5000.0
Win32 Version: 1.1.4322.573
CodeBase: file:///c:/windows/assembly/gac/
Assembly Version: 1.0.5000.0
Win32 Version: 1.1.4322.573
CodeBase: file:///c:/windows/assembly/gac/system/1.0.5000.0__b77a5c561934e089/system.dll
Assembly Version: 0.5.1647.25991
Win32 Version: 0.5.1647.25991
CodeBase: file:///C:/Program%20Files/Gmail%20Agent/Johnvey.GmailAgent.DLL
Assembly Version: 1.0.5000.0
Win32 Version: 1.1.4322.573
CodeBase: file:///c:/windows/assembly/gac/system.drawing/1.0.5000.0__b03f5f7f11d50a3a/system.drawing.dll
Assembly Version: 1.0.5000.0
Win32 Version: 1.1.4322.573
CodeBase: file:///c:/windows/assembly/gac/system.xml/1.0.5000.0__b77a5c561934e089/system.xml.dll
Assembly Version: 1.0.5000.0
Win32 Version: 1.1.4322.573
CodeBase: file:///c:/windows/assembly/gac/system.web/1.0.5000.0__b03f5f7f11d50a3a/system.web.dll
Assembly Version: 1.0.5000.0
Win32 Version: 1.1.4322.573
CodeBase: file:///c:/windows/assembly/gac/
Assembly Version:
Win32 Version: n/a

************** JIT Debugging **************
To enable just in time (JIT) debugging, the config file for this
application or machine (machine.config) must have the
jitDebugging value set in the section.
The application must also be compiled with debugging

For example:

< jitdebugging="true">

When JIT debugging is enabled, any unhandled exception
will be sent to the JIT debugger registered on the machine
rather than being handled by this dialog.

Hasan Shahriar Masud
Senior Software Engineer
Kaz Software limited
Dhaka, Bangladesh
AnswerRe: It's not working Pin
teleolog3-Jul-06 8:33
Memberteleolog3-Jul-06 8:33 
AnswerRe: It's not working Pin
H. S. Masud4-Jul-06 0:24
MemberH. S. Masud4-Jul-06 0:24 
GeneralVery Good,But..... Pin
Trance Junkie14-Aug-05 23:22
MemberTrance Junkie14-Aug-05 23:22 
GeneralGmail login parser changed sometime early Feb 2005 Pin
Zhefu Zhang18-Feb-05 14:38
MemberZhefu Zhang18-Feb-05 14:38 
GeneralRe: Gmail login parser changed sometime early Feb 2005 Pin
jsanjosem26-May-05 3:18
Memberjsanjosem26-May-05 3:18 
GeneralRe: Gmail login parser changed sometime early Feb 2005 Pin
Zhefu Zhang26-May-05 7:15
MemberZhefu Zhang26-May-05 7:15 
GeneralRe: Gmail login parser changed sometime early Feb 2005 Pin
Arunag16-Feb-06 23:02
MemberArunag16-Feb-06 23:02 
GeneralActive discussion thread elsewhere Pin
Anonymous3-Nov-04 20:29
MemberAnonymous3-Nov-04 20:29 
Tom Archer13-Sep-04 16:55
MemberTom Archer13-Sep-04 16:55 
GeneralRe: BEWARE OF SCAM!! Pin
Christian Graus13-Sep-04 17:26
mveChristian Graus13-Sep-04 17:26 
GeneralRe: BEWARE OF SCAM!! Pin
Tom Archer13-Sep-04 17:43
MemberTom Archer13-Sep-04 17:43 
GeneralRe: BEWARE OF SCAM!! Pin
Zhefu Zhang18-Feb-05 13:42
MemberZhefu Zhang18-Feb-05 13:42 
GeneralDoesn't appear to work Pin
Tom Archer3-Sep-04 17:32
MemberTom Archer3-Sep-04 17:32 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.