Reading Atom feed of gmail account from C#

15,101

Solution 1

This is what I used in Vb.net:

objClient.Credentials = New System.Net.NetworkCredential(username, password)

objClient is of type System.Net.WebClient.

You can then get the emails from the feed using something like this:

Dim nodelist As XmlNodeList
Dim node As XmlNode
Dim response As String
Dim xmlDoc As New XmlDocument

'get emails from gmail
response = Encoding.UTF8.GetString(objClient.DownloadData("https://mail.google.com/mail/feed/atom"))
response = response.Replace("<feed version=""0.3"" xmlns=""http://purl.org/atom/ns#"">", "<feed>")

'Get the number of unread emails
xmlDoc.LoadXml(response)
node = xmlDoc.SelectSingleNode("/feed/fullcount")
mailCount = node.InnerText
nodelist = xmlDoc.SelectNodes("/feed/entry")
node = xmlDoc.SelectSingleNode("title")

This should not be very different in C#.

Solution 2

.NET framework 3.5 provides native classes to read feeds. This articles describes how to do it.

I haven't used it tho, but there must be some provision for authentication to a URL. You can check that out. I too will do it, and post the answer back.

If you are not using framework 3.5, then you can try Atom.NET. I have used it once, but its old. You can give it a try if it meets your needs.

EDIT: This is the code for assigning user credentials:

XmlUrlResolver resolver = new XmlUrlResolver();
resolver.Credentials = new NetworkCredential("[email protected]", "password");

XmlReaderSettings settings = new XmlReaderSettings();
settings.XmlResolver = resolver;

XmlReader reader = XmlReader.Create("https://gmail.google.com/gmail/feed/atom", settings);

Solution 3

You use Basic Auth. Basically, you make an initial request, the server replies with 401, and then you send back the password in base64 (in this case over HTTPS).

Note though that:

  1. The feed only allows you to get trivial info about the account (e.g. new mail). It does not allow you to send messages.
  2. POP can not be used to send messages either.
  3. Usually SMTP is used, and it really isn't that hard.

EDIT: Here's an example for authenticating and loading the Atom feed into an XmlDocument. Note though that will only provide read access. Search or ask another question for info on C# and SMTP. The ICertificatePolicy junk was necessary for me as Mono didn't like Google's certificate. It's a quick workaround, not suitable for production.

Okay, since you've clarified you're actually reading mail (and a different component is sending it), I recommend you do use POP. :

using System;
using System.Net;
using System.IO;
using System.Security.Cryptography.X509Certificates;
using System.Xml;

public class GmailFeed
{
    private class IgnoreBadCerts : ICertificatePolicy
    {
        public bool CheckValidationResult (ServicePoint sp, 
                                           X509Certificate certificate, 
                                           WebRequest request, 
                                           int error)
        {
            return true;
        }


    }

    public static void Main(string[] argv)
    {
        if(argv.Length != 2)
        {
            Console.Error.WriteLine("Usage: GmailFeed username password");
            Environment.ExitCode = 1;
            return;
        }
        ServicePointManager.CertificatePolicy = new IgnoreBadCerts();

        NetworkCredential cred = new NetworkCredential();
        cred.UserName = argv[0];
        cred.Password = argv[1];

        WebRequest req = WebRequest.Create("https://gmail.google.com/gmail/feed/atom");
        req.Credentials = cred;
        Stream resp = req.GetResponse().GetResponseStream();

        XmlReader reader = XmlReader.Create(resp);
        XmlDocument doc = new XmlDocument();
        doc.Load(reader);
    }
}

Solution 4

For what its worth, I have never been able to autheniticate via:

https://gmail.google.com/gmail/feed/atom

However I can always authenticate on:

https://mail.google.com/mail/feed/atom

HTH!!

Solution 5

The following method seems to work to check the amount of unread messages. I do not know much about xml at all so I was unable to parse the results other than retrieve the unread count. (Returns -1 on error)

public int GmailUnreadCount(string username, string password)
    {
        XmlUrlResolver resolver = new XmlUrlResolver();
        resolver.Credentials = new NetworkCredential(username, password);
        XmlReaderSettings settings = new XmlReaderSettings();
        settings.XmlResolver = resolver;
        try
        {
            XmlReader reader = XmlReader.Create("https://mail.google.com/mail/feed/atom", settings);
            while (reader.Read())
            {
                switch (reader.NodeType)
                {
                    case XmlNodeType.Element:
                        switch (reader.Name)
                        {
                            case "fullcount":
                                int output;
                                Int32.TryParse(reader.ReadString(), out output);
                                return output;
                        }
                        break;
                }
            }
        }
        catch (Exception a)
        {
            MessageBox.Show(a.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            return -1;
        }
        return -1;
    }
Share:
15,101
Crash893
Author by

Crash893

nonya

Updated on June 04, 2022

Comments

  • Crash893
    Crash893 about 2 years

    I have a project that will send an email with certain data to a gmail account. I think that it will probably be easier to read the Atom feed rather than connect through POP.

    The url that I should be using according to Google is:

    https://gmail.google.com/gmail/feed/atom
    

    The question/problem is: how do I authenticate the email account I want to see? If I do it in Firefox, it uses the cookies.

    I'm also uncertain how exactly to "download" the XML file that this request should return (I believe the proper term is stream).

    Edit 1:

    I am using .Net 3.5.

  • Crash893
    Crash893 about 15 years
    could you post an example I am really in the dark about how to do this
  • Crash893
    Crash893 about 15 years
    this code works well thanks - as stated by Matthew Flaschen it returns a 401 error that i guess i need to then send the authentication some how. Anyone got any ideas on that?
  • Crash893
    Crash893 about 15 years
    the account will only be used as a one way system. basically gps cords are sent in the form of mail. then i need to pick them up and read them Thanks for the code i will give it a try
  • Crash893
    Crash893 about 15 years
    I get the same error again. Im confused that in yoru post you mention sending the password in base64 but in the code i do not see this also how do you ask for a page then respond to the page to give the base64 password?
  • Matthew Flaschen
    Matthew Flaschen about 15 years
    Did you use the full code (including "ServicePointManager.CertificatePolicy = new IgnoreBadCerts();")? Base64 is used, but internally so you don't have to worry about it.
  • Crash893
    Crash893 about 15 years
    Thanks I'll give it a try when I get home
  • ryanulit
    ryanulit over 14 years
    I'm getting a "(407) Proxy Authentication Required" error when I run this code, has anyone else tried?
  • alex
    alex over 14 years
    That's strange. I use that code in an app that I use daily at work. The only way you might get that would be if Google changed something on its end, which I kind of doubt (they haven't changed anything in the year I've used my app).