2009-06-13 17 views
8

Tengo un proyecto que enviará un correo electrónico con ciertos datos a una cuenta de gmail. Creo que probablemente sea más fácil leer el feed Atom en lugar de conectarse a través de POP.Reading Atom feed of gmail account from C#

La url que yo debería usar según Google es:

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

La pregunta/problema es: ¿cómo autenticar la cuenta de correo electrónico que quiero ver? Si lo hago en Firefox, usa las cookies.

Tampoco estoy seguro de cómo exactamente "descargar" el archivo XML que esta solicitud debe devolver (creo que el término correcto es transmisión).

Edición 1:

estoy usando .Net 3.5.

+0

El código que he escrito debe funcionar de manera ideal, pero parece haber algún problema con el método de autenticación de Google, supongo. Parece que este tipo tiene el mismo problema: http://objectmix.com/xml-soap/336644-problem-reading-gmail-atom-feed-net.html – Kirtan

Respuesta

6

Esto es lo que he usado en Vb.net:

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

objClient es de tipo System.Net.WebClient.

entonces se puede obtener los correos electrónicos de la alimentación usando algo como esto:

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

Esto no debería ser muy diferente en C#.

+0

Gracias, lo intentaré cuando llegue a casa – Crash893

+0

Recibo un error "(407) Autenticación de proxy necesaria" cuando ejecuto este código, ¿alguien más lo intentó? – ryanulit

+0

Eso es extraño. Uso ese código en una aplicación que uso a diario en el trabajo. La única forma en que podrías obtener eso sería si Google cambia algo, lo que dudo (no han cambiado nada en el año que utilicé mi aplicación). – alex

6

.NET framework 3.5 proporciona clases nativas para leer feeds. This artículos describe cómo hacerlo.

No lo he usado, pero debe haber alguna disposición para la autenticación a una URL. Puedes verificarlo. Yo también lo haré y devolveré la respuesta.

Si no está utilizando Framework 3.5, puede intentar Atom.NET. Lo he usado una vez, pero es viejo. Puede intentarlo si satisface sus necesidades.

EDIT: Este es el código para la asignación de credenciales de usuario:

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

este código funciona bien, gracias, como dice Matthew Flaschen. un error 401 que supongo que necesito para luego enviar la autenticación de alguna forma. Alguien tiene alguna idea sobre eso? – Crash893

2

Se utiliza autenticación básica. Básicamente, realiza una solicitud inicial, el servidor responde con 401 y luego devuelve la contraseña en base64 (en este caso a través de HTTPS).

Nota sin embargo que:

  1. La alimentación sólo se le permite obtener información trivial sobre la cuenta (por ejemplo, el correo nuevo). No te permite enviar mensajes.
  2. POP tampoco se puede utilizar para enviar mensajes.
  3. Normalmente se usa SMTP, y realmente no es tan difícil.

EDITAR: Aquí hay un ejemplo para autenticar y cargar la información de Atom en un XmlDocument. Sin embargo, tenga en cuenta que solo proporcionará acceso de lectura. Busque o haga otra pregunta para obtener información sobre C# y SMTP. La basura ICertificatePolicy fue necesaria para mí ya que a Mono no le gustó el certificado de Google. Es una solución rápida, no adecuada para producción.

De acuerdo, ya que ha aclarado que en realidad está leyendo el correo (y un componente diferente lo está enviando), le recomiendo que 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); 
    } 
} 
+0

podría publicar un ejemplo Estoy realmente en la oscuridad acerca de cómo hacer esto – Crash893

+0

la cuenta solo se utilizará como un sistema unidireccional. Básicamente, los cables gps se envían en forma de correo. entonces necesito recogerlos y leerlos Gracias por el código lo probaré – Crash893

+0

Me sale el mismo error otra vez. Estoy confundido porque en la publicación Yoru mencionas que envías la contraseña en base64, pero en el código no veo esto ¿también cómo pides una página y luego respondes a la página para dar la contraseña de base64? – Crash893

1

Por lo que su valor, que nunca han sido capaces de autheniticate a través de:

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

Sin embargo siempre se puede autenticar en:

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

HTH !!

0

Aquí está mi solución clara y directa:

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

Devuelve el error 401 – Reynevan

1

El siguiente método parece funcionar para comprobar la cantidad de mensajes no leídos. No sé mucho sobre xml en absoluto así que no pude analizar los resultados que no sean recuperar el recuento no leído. (Devuelve -1 en caso de 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; 
    }