Ir para conteúdo


Revista PROGRAMAR – Edição 46 (Setembro 2014): Download já disponível!

- - - - -

Aceder ao GMail por IMAP


  • Por favor inicie sessão para responder
3 respostas a este tópico

#1 mribeiro

mribeiro

    void

  • Membro
  • PipPip
  • 37 mensagens

Publicado 04 de Outubro de 2010 - 11:54

Bons dias!
Ando a tentar ligar-me ao servidor IMAP do GMail para conseguir obter os emails não lidos, no entanto, não consigo sequer passar do Login.
Deixo o código em baixo que obti na daniweb (só não me registo para ver a solução porque querem €€€€ ) e tinha esperança que alguém me podesse ajudar. O erro que dá é que não reconhece o comando USER nem PASS. Ora, por pesquisas que fiz, são esses mesmos os comandos para definir o username e password.
Também não me importo de usar um wrapper ou API que exista por aí desde que seja free e possa distribuir livremente com a aplicação.

Código (C#):
// create an instance of TcpClient
                TcpClient tcpclient = new TcpClient();
                tcpclient.Connect("imap.gmail.com", 993);
                // This is Secure Stream
                SslStream sslstream = new SslStream(tcpclient.GetStream());
                // authenticate as client  
                sslstream.AuthenticateAsClient("imap.gmail.com");
                bool flag = sslstream.IsAuthenticated;   // check flag
                // Asssigned the writer to stream
                System.IO.StreamWriter sw = new StreamWriter(sslstream);
                // Assigned reader to stream
                System.IO.StreamReader reader = new StreamReader(sslstream);
                // refer POP rfc command, there very few around 6-9 command
                sw.WriteLine("USER user@gmail.com");
                // sent to server
                sw.Flush();
                sw.WriteLine("PASS password");
                sw.Flush();
                // this will retrive your first email
                sw.WriteLine("RETR 1");
                sw.Flush();
                // close the connection
                sw.WriteLine("Quit ");
                sw.Flush();
                string str = string.Empty;
                string strTemp = string.Empty;
                try
                {
                    while ((strTemp = reader.ReadLine()) != null)
                    {
                        // find the . character in line
                        if (strTemp == ".")
                        {
                            reader.Close();
                            break;
                        }
                        if (strTemp.IndexOf("-ERR") != -1)
                        {
                            reader.Close();
                            break;
                        }
                        str += strTemp;
                    }
                }
                catch (Exception ex)
                {
                    string s = ex.Message;
                }
                reader.Close();
                Console.WriteLine(str);
                Console.WriteLine("Congratulation.. ....!!! You read your first gmail email ");
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }


#2 IceBrain

IceBrain

    Unsigned User

  • Membro
  • PipPipPipPipPipPip
  • 1241 mensagens

Publicado 04 de Outubro de 2010 - 12:13

Esses comandos são para POP, não para IMAP.

Primeiro, para cada comando que mandas, tens que fornecer uma tag para o identificar. Depois, o comando para login é "login USERNAME PASSWORD".

Isto funciona (testei com o ncat):
Código :
esta_e_a_tag_1 LOGIN icebrain *********
esta_e_a_tag_1 OK icebrain@gmail.com authenticated (Success)

(nota: o nome da tag pode ser o que quiseres, desde que não tenha espaços)
Podes ver mais exemplos aqui: http://networking.ringofsaturn.com/Protocols/imap.php
Ou leres o RFC: http://tools.ietf.org/html/rfc3501#section-2

De qualquer forma, e apesar de não programar em .NET, duvido que não haja uma biblioteca IMAP com licença BSD/MIT.

#3 mribeiro

mribeiro

    void

  • Membro
  • PipPip
  • 37 mensagens

Publicado 04 de Outubro de 2010 - 22:50

Ver MensagemIceBrain, em 04 de Outubro de 2010 - 12:13, disse:

Esses comandos são para POP, não para IMAP.

Primeiro, para cada comando que mandas, tens que fornecer uma tag para o identificar. Depois, o comando para login é "login USERNAME PASSWORD".

(nota: o nome da tag pode ser o que quiseres, desde que não tenha espaços)
Podes ver mais exemplos aqui: http://networking.ringofsaturn.com/Protocols/imap.php
Ou leres o RFC: http://tools.ietf.org/html/rfc3501#section-2

De qualquer forma, e apesar de não programar em .NET, duvido que não haja uma biblioteca IMAP com licença BSD/MIT.

Boa noite e obrigado! Até à parte de login funciona... obtenho uma resposta do GMail com as capabilities e a confirmar o login com sucesso. No entanto, pelo que li do RFC, o comando para examinar uma pasta é "EXAMINE <nomepasta>" . Ora, ao que parece, o nome da caixa de entrada do gmail é inbox pelo que usei o comando da seguinte forma:
Código :
tag2 EXAMINE inbox
e não obtenho nenhuma resposta, isto é, ao ler o stream mostra as respostas até ao login mas depois nao mostra nada, fica à espera de receber alguma coisa para ler.

Deixo o código em baixo:

Código (C#):
try
            {
                // create an instance of TcpClient
                TcpClient tcpclient = new TcpClient();
                // HOST NAME POP SERVER and gmail uses port number 995 for POP  
                //tcpclient.Connect("pop.gmail.com", 995);
                tcpclient.Connect("imap.gmail.com", 993);
                // This is Secure Stream // opened the connection between client and POP Server
                SslStream sslstream = new SslStream(tcpclient.GetStream());
                // authenticate as client  
               
                sslstream.AuthenticateAsClient("imap.gmail.com");
               
                bool flag = sslstream.IsAuthenticated;   // check flag
                // Asssigned the writer to stream
                System.IO.StreamWriter sw = new StreamWriter(sslstream);
                // Assigned reader to stream
                System.IO.StreamReader reader = new StreamReader(sslstream);

                sw.WriteLine("tag LOGIN user@gmail.com pass");
                sw.Flush();

                sw.WriteLine("tag2 EXAMINE inbox");
                sw.Flush();

                sw.WriteLine("tag3 LOGOUT ");
                sw.Flush();

                string str = string.Empty;
                string strTemp = string.Empty;
                try
                {
                    while ((strTemp = reader.ReadLine()) != null)
                    {
                        Console.WriteLine(strTemp);
                        // find the . character in line
                        if (strTemp == ".")
                        {
                            //reader.Close();
                            break;
                        }
                        if (strTemp.IndexOf("-ERR") != -1)
                        {
                            //reader.Close();
                            break;
                        }
                        str += strTemp;
                    }
                }
                catch (Exception ex)
                {
                    string s = ex.Message;
                }
                //reader.Close();
               
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }

Agradeço qualquer ajuda :( Obrigado

#4 IceBrain

IceBrain

    Unsigned User

  • Membro
  • PipPipPipPipPipPip
  • 1241 mensagens

Publicado 06 de Outubro de 2010 - 11:26

Tens que mandar CRLF (\r\n) no fim de cada linha. Pelos vistos o Gmail aceita o login sem isso mas depois já não.

Está no RFC, mas também me tinha escapado:

Citar

All interactions transmitted by client and server are in the form of lines, that is, strings that end with a CRLF.