2009-06-13 7 views
8
lesen

Ich habe ein Projekt, das eine E-Mail mit bestimmten Daten an ein Google Mail-Konto senden wird. Ich denke, dass es wahrscheinlich einfacher ist, den Atom-Feed zu lesen, als über POP zu verbinden.Atom-Feed von Google Mail-Konto von C#

Die URL, die ich nach Google verwenden soll, ist:

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

Die Frage/Problem ist: Wie ich das E-Mail-Konto, das ich sehen wollen authentifizieren? Wenn ich es in Firefox mache, verwendet es die Cookies.

Ich bin auch unsicher, wie genau die XML-Datei, die diese Anfrage zurückgeben soll "herunterzuladen" (ich glaube, der richtige Begriff ist Stream).

Edit 1:

Ich bin mit .NET 3.5.

+0

Der Code, den ich geschrieben habe, muss funktionieren, aber es scheint ein Problem mit Google Authentifizierungsmethode, denke ich. Dieser Typ scheint das gleiche Problem zu haben - http://objectmix.com/xml-soap/336644-problem-reading-gmail-atom-feed-net.html – Kirtan

Antwort

6

Dies ist, was ich in Vb.net verwendet:

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

objClient ist vom Typ System.Net.WebClient.

Sie können dann die E-Mails aus dem Feed mit so etwas wie diese:

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

Dies sollte nicht sehr unterschiedlich sein in C#.

+0

Danke Ich werde es versuchen, wenn ich nach Hause komme – Crash893

+0

Ich erhalte eine "(407) Proxy-Authentifizierung erforderlich" Fehler, wenn ich diesen Code ausführen, hat jemand anderes versucht? – ryanulit

+0

Das ist seltsam. Ich verwende diesen Code in einer App, die ich täglich bei der Arbeit verwende. Der einzige Weg, den du bekommen könntest, wäre, wenn Google am Ende etwas geändert hätte, woran ich zweifle (sie haben nichts an dem Jahr geändert, an dem ich meine App benutzt habe). – alex

6

.NET Framework 3.5 bietet native Klassen zum Lesen von Feeds. This Artikel beschreibt, wie es geht.

Ich habe es nicht verwendet, aber es muss eine Bestimmung für die Authentifizierung zu einer URL geben. Sie können das überprüfen. Ich werde es auch tun und die Antwort zurücksenden.

Wenn Sie nicht Framework 3.5 verwenden, können Sie versuchen Atom.NET. Ich habe es einmal benutzt, aber es ist alt. Sie können es versuchen, wenn es Ihren Bedürfnissen entspricht.

EDIT: Dies ist der Code für Benutzeranmeldeinformationen zuweisen:

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

dieser Code funktioniert gut danke - wie von Matthew Flaschen angegeben, kehrt es zurück Ein 401 Fehler, ich denke, ich muss dann die Authentifizierung einige wie senden. Hat jemand dazu irgendwelche Ideen? – Crash893

2

Sie Grund Auth verwenden. Im Grunde genommen machen Sie eine erste Anfrage, der Server antwortet mit 401, und dann senden Sie das Passwort in base64 (in diesem Fall über HTTPS) zurück.

Beachten Sie aber, dass:

  1. Der Feed können Sie nur triviale Informationen über das Konto (beispielsweise neue E-Mail) erhalten. Sie können keine Nachrichten senden.
  2. POP kann nicht zum Senden von Nachrichten verwendet werden.
  3. Normalerweise wird SMTP verwendet, und es ist wirklich nicht so schwer.

EDIT: Hier ist ein Beispiel für die Authentifizierung und das Laden der Atom-Feed in ein XmlDocument. Beachten Sie jedoch, dass nur Lesezugriff gewährt wird. Suchen oder stellen Sie eine andere Frage, um Informationen zu C# und SMTP zu erhalten. Der ICertificatePolicy-Junk war für mich notwendig, da Mono das Zertifikat von Google nicht mochte. Es ist eine schnelle Abhilfe, nicht für die Produktion geeignet.

Okay, da Sie geklärt haben, dass Sie tatsächlich Mail lesen (und eine andere Komponente sendet), empfehle ich Ihnen, POP zu verwenden. :

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

könnten Sie ein Beispiel posten Ich bin wirklich im Dunkeln darüber, wie dies zu tun – Crash893

+0

das Konto wird nur als ein Einwegsystem verwendet werden. im Grunde werden GPS-Kabel in Form von Post gesendet. dann muss ich sie abholen und sie lesen Danke für den Code Ich werde es versuchen – Crash893

+0

Ich bekomme den gleichen Fehler wieder. Ich bin verwirrt, dass in Ihrer Post erwähnen Sie das Senden des Passworts in base64, aber in dem Code sehe ich nicht auch wie fragen Sie nach einer Seite dann auf die Seite reagieren, um die base64 Passwort geben? – Crash893

1

Für das, was ihren Wert, ich habe nie in der Lage gewesen, über autheniticate:

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

Allerdings kann ich immer authentifizieren auf:

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

HTH !!

0

Hier ist meine lean and mean Lösung:

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

Gibt 401 Fehler zurück – Reynevan

1

Die folgende Methode scheint die Menge der ungelesenen Nachrichten zu überprüfen, um zu arbeiten. Ich weiß überhaupt nicht viel über xml, so konnte ich die Ergebnisse nicht analysieren, außer die ungelesene Anzahl abzurufen. (-1 bei Fehler)

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