The original article can be found here

Introduction
This article will show you how to create a Gmail Notifier kind of application that checks the new mails using the recently introduced Gmail Atom Feeds and speaks out the details of the mail using Microsoft Agent.
Background
Did you ever day-dream that one morning when you wake up and say aloud "Hey, check my Inbox", a reply comes up asking "You have 12 new mails...Should I read them"? When you say "Yes", the mail reading begins. As you get ready for the office/college/school, you interact with the voice and if required, dictate a few replies. When you are about to leave, the voice reminds you of the tasks that have to be done today with a pleasant good bye. Don't you think that a part of these are regular chores that are usually performed by your room-partner, wife or mom? Well, what was that "Voice"..guess? Yes, that's your PC.
There are many computer geeks like me who want to check the mail every hour even when in the bed. No matter if they are important to me or not. How about checking a mail without lifting a finger or opening your eyes?
Certainly, this does feel like a sci-fi dream. The current article does not do all that. But I developed it for my personal use and felt like sharing with you all. You can call it as a by-product of my involvement in a comparatively larger HCI project.
I usually have 10-15 mails in the mail box every morning; it would be very useful if I don't have to perform those few clicks for the un-important mails.
I would like to remind you that there are many such products available online but most of us use free email accounts, which means no SMTP/POP3 access. With Gmail having free POP access, these problems seem to disappear. If time permits, I would be using POP code to access mails instead of Atom feeds.
With Google Talk following open communication standards, there are limitless possibilities for developers. How about speaking to your Home PC from your office PC or phone.. "Hey, I am coming. Start the AC and keep the coffee ready in 20 minutes". Is it feasible? Yes. My way of doing it: Use a Speech SDK, Google Talk XMPP (or SIP in future) and some hardware interface (make it or purchase it).
Using Google Atom feeds
Google has recently introduced a feature that allows you to get an abstract of the mails using Atom feed reader. We use the WebRequest
object to get the Atom feeds. We can connect to the GMail site at this location. This site requires basic authorization that we send in the request headers.
The following code shows you how to send the request and receive the Atom feed. You may have to connect through a proxy. (The code for the proxy usage is not explained here.)
wrGETURL =
WebRequest.Create("https://mail.google.com/mail/feed/atom");
if(clsMain.g_UseProxy)
{
wrGETURL.Proxy = clsMain.GetProxy();
}
bytes = Encoding.ASCII.GetBytes(txtUserName.Text.Trim() + ":"
+ txtUserPassword.Text.Trim());
wrGETURL.Headers.Add("Authorization",
"Basic " + Convert.ToBase64String(bytes));
Stream feedStream =
wrGETURL.GetResponse().GetResponseStream();
Note: The site stated by Google is different from the site stated above. I was not able to connect to this using this code. May be this requires some other kind of authorization.
The response that you get is in XML format as shown below:
="1.0" ="UTF-8"
<feed version="0.3" xmlns="http://purl.org/atom/ns#">
<title>Gmail - Inbox for anupshinde</title>
<tagline>New messages in your Gmail Inbox</tagline>
<fullcount>38</fullcount>
<link rel="alternate"
href="http://mail.google.com/mail"
type="text/html"/>
<modified>2005-09-11T14:01:39Z</modified>
<entry>
<title>New result arrived</title>
<summary>Dear Sir, A new result has arrived
for the following candidate:
Name: Anup Shinde RemoteIP …
</summary>
<link rel="alternate"
href="http://mail.google.com/mail"
type="text/html"/>
<modified>2005-09-11T13:58:15Z</modified>
<issued>2005-09-11T13:58:15Z</issued>
<id>
tag:gmail.google.com,2004:1181165390179818642
</id>
<author>
<name>anup</name>
<email>anup@micromacs.com</email>
</author>
</entry>
.....
.....
.....
</feed>
In the response, you get a maximum of 20 entries. These entries are those of the unread mails only.
Parsing the Atom feeds
Atom feeds can be parsed by yourself, or you can use a ready made Atom feed parser. I have used "Atom.NET" libraries available in the open-source library at sourceforge.
Just download "Atom.NET.dll" and add a reference to the project. If we are not using proxy, we need not create the web-request as Atom.NET libraries will automatically create it for us. Unfortunately, Atom.Net libraries don't have support for proxy. So, we need to get the response by ourselves and send this response stream to the Atom.NET library. Once we create an instance of the Atom feed, we can loop through the entries as shown below:
Stream feedStream =
wrGETURL.GetResponse().GetResponseStream();
Atom.Core.AtomFeed myFeed;
myFeed = Atom.Core.AtomFeed.Load(feedStream);
strFeedTime = myFeed.Modified.DateTime.Day.ToString() + "-"
+ myFeed.Modified.DateTime.ToString("MMM") + "-"
+ myFeed.Modified.DateTime.Year.ToString() + " "
+ myFeed.Modified.DateTime.TimeOfDay.ToString();
feedTime= DateTime.Parse(strFeedTime);
Atom.Core.Collections.AtomEntryCollection ents =
myFeed.Entries;
foreach(Atom.Core.AtomEntry ent in ents)
{ {
FromName = ent.Author.Name;
Title = ent.Title.Content;
Content = ent.Summary.Content;
}
Using Microsoft Agent 2.0
Once the feeds have been downloaded and parsed, you can do literally anything with it. Our purpose is to speak out these feeds for the user using Microsoft Agent 2.0. Most probably you will have Microsoft Agent installed in your machine. Stating the requirements is out of the scope of this article. Please see the Microsoft Agent sites given here. Developers, please see the home page. The end user downloads can be found here. I found an interesting site that offers Microsoft Agent Character downloads. Please see this site.
We will receive feeds in the text format, which needs to be converted to speech. Don't worry. Microsoft Agent has a simple Speak(text)
method, which can be used for this purpose. MS-Agent works using SAPI 4.0. Therefore, you will have to download SAPI 4.0 runtime from the links given above. Windows XP/2000 users will already have these. Without SAPI 4, you will not be able to hear the voice.
Note: SAPI 5.0 TTS is much better than SAPI4 TTS. It is possible to connect MS-Agent with SAPI5.0 TTS, but that is out of the scope of this article.
To use Microsoft Agent in your project, go to the Toolbox and open "Add/Remove Items". Select "Microsoft Agent Control 2.0"(AgentCtl.dll) from COM components and click OK. You can see a component with a "Spy" like icon in the toolbox. You need to place this on the form.
The code for using the character is shown below:
agentMain.Characters.Load("agentAssistant",
"merlin.acs");
agentRef =
agentMain.Characters.Character("agentAssistant");
agentRef.Left = (short)(this.Left + this.Width + 10);
agentRef.Top = (short)(this.Top + this.Height + 10);
agentRef.Show(false);
agentRef.Play("Greet");
agentRef.Play("Explain");
agentRef.Speak(
"Hi. I will be fetching your Google Mails","");
agentRef.Play("Acknowledge");
agentRef.Speak(
"You can activate me whenever you want.","");
agentRef.Speak("Bye bye.","");
agentRef.Play("Wave");
agentRef.Hide(false);
The attached code
In the attached project, there is a method LoadAgent(String AgentFileName)
which takes the file name from which the agent has to be loaded. This makes it easier to load multiple agents. To login to the GMail server, I have used a Windows form "frmMain" that also asks for saving the username and password. The entire configuration is stored in a file "vals.conf". Since, it is insecure to save un-encrypted username and password; I have converted both of them to Base64 strings before saving it to the .conf file. (But that is not enough).
There are two methods for reading and writing configurations, namely "WriteOptions()
" and "ReadOptions()
". This is not a hi-fi coding, but a very basic one. I am planning to implement "Application Configuration Blocks" from the Enterprise Library - Patterns and Practices for this application.
There is a timer whose interval is hard-coded to 5 minutes. Every 5 minutes, the application will check for any new mails. To distinguish new mails from the previously "spoken" mails, the last accessed/checked time is stored. Only those mails that come after the "last accessed time" are spoken out. This is demonstrated in the code below:
myFeed = Atom.Core.AtomFeed.Load(feedStream);
strFeedTime = myFeed.Modified.DateTime.Day.ToString() + "-"
+ myFeed.Modified.DateTime.ToString("MMM") + "-"
+ myFeed.Modified.DateTime.Year.ToString() + " "
+ myFeed.Modified.DateTime.TimeOfDay.ToString();
feedTime= DateTime.Parse(strFeedTime);
if( feedTime <= DateTime.Parse(last_accessed_DateTime))
{
return;
}
foreach(Atom.Core.AtomEntry ent in ents)
{
if(i>=max_reads) break;
FromName = ent.Author.Name;
Title = ent.Title.Content;
Content = ent.Summary.Content;
strFeedTime = ent.Modified.DateTime.Day.ToString() + "-"
+ ent.Modified.DateTime.ToString("MMM") + "-"
+ ent.Modified.DateTime.Year.ToString() + " "
+ ent.Modified.DateTime.TimeOfDay.ToString();
entfeedTime= DateTime.Parse(strFeedTime);
if(entfeedTime <= DateTime.Parse(last_accessed_DateTime))
{
i++;
continue;
}
i++;
}
last_accessed_DateTime = feedTime.Day.ToString() + "-"
+ feedTime.ToString("MMM") + "-"
+ feedTime.Year.ToString() + " "
+ feedTime.TimeOfDay.ToString();
The number of mails spoken out is also hard-coded to 10. Gmail returns 20 feeds at maximum.
Enhancements
This time I have tried to make it as user-friendly as possible. There are a lot of enhancements that I can think of and I am definitely looking forward to make this agent more user-interactive. I think it is better to keep it as a project instead of an article.
The original article can be found here