2009-06-13 9 views
8

J'ai un projet qui enverra un email avec certaines données à un compte Gmail. Je pense qu'il sera probablement plus facile de lire le flux Atom plutôt que de se connecter via POP.Lecture flux Atom du compte gmail à partir de C#

L'URL que je devrais utiliser selon Google est:

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

La question/problème est: comment puis-je authentifier le compte e-mail que je veux voir? Si je le fais dans Firefox, il utilise les cookies.

Je suis aussi incertain exactement comment « télécharger » le fichier XML que cette demande devrait revenir (je crois que le terme approprié est courant).

Edit 1:

J'utilise .Net 3.5.

+0

Le code que j'ai écrit doit fonctionner idéalement, mais il semble y avoir un problème avec la méthode d'authentification de Google, je suppose. Ce gars semble avoir le même problème - http://objectmix.com/xml-soap/336644-problem-reading-gmail-atom-feed-net.html – Kirtan

Répondre

6

C'est ce que je en Vb.net:

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

objClient est de type System.Net.WebClient.

Vous pouvez alors obtenir les e-mails à partir de l'alimentation en utilisant quelque chose comme ceci:

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") 

Cela ne devrait pas être très différent en C#.

+0

Merci je vais essayer quand je rentre à la maison – Crash893

+0

Je reçois une erreur "(407) Authentification Proxy Requise" lorsque j'exécute ce code, quelqu'un d'autre a-t-il essayé? – ryanulit

+0

C'est étrange. J'utilise ce code dans une application que j'utilise quotidiennement au travail. La seule façon dont vous pourriez obtenir ce serait si Google a changé quelque chose sur sa fin, dont je doute (ils n'ont rien changé dans l'année où j'ai utilisé mon application). – alex

6

.NET Framework 3.5 fournit des classes natives pour lire les flux. This articles décrit comment le faire.

Je ne l'ai pas utilisé, mais il doit y avoir une provision pour l'authentification à une URL. Vous pouvez vérifier cela. Moi aussi, je le ferai et posterai la réponse.

Si vous n'utilisez pas Framework 3.5, vous pouvez essayer Atom.NET. Je l'ai utilisé une fois, mais c'est vieux. Vous pouvez essayer si cela répond à vos besoins.

EDIT: Voici le code pour attribuer des informations d'identification de l'utilisateur:

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); 
+0

ce code fonctionne bien merci - comme indiqué par Matthew Flaschen, il revient une erreur 401 que je suppose que je dois ensuite envoyer l'authentification un peu comment. Quelqu'un a-t-il des idées à ce sujet? – Crash893

2

Vous utilisez Basic Auth. Fondamentalement, vous faites une demande initiale, le serveur répond avec 401, puis vous renvoyez le mot de passe dans base64 (dans ce cas sur HTTPS).

Notez bien que:

  1. L'alimentation ne vous permet d'obtenir des informations triviales sur le compte (par exemple nouveau mail). Cela ne vous permet pas d'envoyer des messages. POP ne peut pas être utilisé pour envoyer des messages non plus.
  2. Habituellement SMTP est utilisé, et ce n'est vraiment pas si difficile.

EDIT: Voici un exemple d'authentification et de chargement du flux Atom dans un XmlDocument. Notez cependant que cela fournira seulement l'accès en lecture. Recherchez ou demandez une autre question pour plus d'informations sur C# et SMTP. L'indésirable ICertificatePolicy était nécessaire pour moi car Mono n'aimait pas le certificat de Google. C'est une solution de contournement rapide, pas adapté à la production.

D'accord, puisque vous avez précisé que vous lisez réellement mail (et un autre composant envoie), je vous recommande de faire utiliser 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); 
    } 
} 
+0

pourriez-vous poster un exemple Je suis vraiment dans le noir sur la façon de le faire – Crash893

+0

le compte sera utilisé uniquement comme un système à sens unique. essentiellement les cordons GPS sont envoyés sous la forme de courrier. alors je dois les ramasser et les lire Merci pour le code je vais essayer – Crash893

+0

Je reçois la même erreur encore. Im confus que dans yoru post vous mentionnez l'envoi du mot de passe dans base64 mais dans le code je ne vois pas ce aussi comment demandez-vous une page, puis répondre à la page pour donner le mot de passe base64? – Crash893

1

Pour ce que ça vaut, je n'ai jamais pu autheniticate via:

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

Cependant, je peux toujours authentifier sur:

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

HTH !!

0

Voici ma solution simple et léger:

public static string TextToBase64(string sAscii) 
    { 
     System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding(); 
     byte[] bytes = encoding.GetBytes(sAscii); 
     return System.Convert.ToBase64String(bytes, 0, bytes.Length); 
    } 

    public static void foobar() 
    { 
     var url = @"https://gmail.google.com/gmail/feed/atom"; 

     var USER = "userName"; 
     var PASS = "password"; 

     var encoded = TextToBase64(USER + ":" + PASS); 

     var myWebRequest = HttpWebRequest.Create(url); 
     myWebRequest.Method = "POST"; 
     myWebRequest.ContentLength = 0; 
     myWebRequest.Headers.Add("Authorization", "Basic " + encoded); 

     var response = myWebRequest.GetResponse(); 
     var stream = response.GetResponseStream(); 

     // Parse the stream using your favorite parsing library or using XmlDocument ... 
    } 
+1

Retourne l'erreur 401 – Reynevan

1

La méthode suivante semble fonctionner pour vérifier le nombre de messages non lus. Je ne connais pas du tout xml du tout, donc j'étais incapable d'analyser les résultats autrement que de récupérer le nombre non lu. (Renvoie -1 en erreur)

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; 
    } 
Questions connexes