Hoje esse esquema não existe mais - foi substituído por outros canais com papel similar - mas a ideia da aplicação capaz de monitorar uma caixa postal ainda é válida e pode ser reaproveitada em outros cenários.
A solução adotada por nós é baseada no protocolo chamado POP3 (Post Office Protocol). Com ele é possível recuperar todas as mensagens existentes na caixa de entrada de uma conta de email. A implementação dele que usamos é a do Projeto Indy distribuida junto com o IDE do Delphi;
Da mesma forma que outros protocolos baseados no IP, usar o POP3 exige que se faça a conexão com o servidor antes de realizar qualquer operação. Temos, então, que informar o nome (ou endereço) desse servidor, a porta onde se conectar e um nome de usuário e sua senha, válidos para a operação desejada.
var _IdPOP3 : TIdPOP3;
begin
_IdPOP3 := TIdPOP3.Create (Nil);
_IdPOP3.Host := _ServidorPOP;
_IdPOP3.Port := _PortaPOP;
_IdPOP3.Username := _Username;
_IdPOP3.Password := _Userpwd;
_IdPOP3.AutoLogin := True;
_IdPOP3.Connect ();
begin
_IdPOP3 := TIdPOP3.Create (Nil);
_IdPOP3.Host := _ServidorPOP;
_IdPOP3.Port := _PortaPOP;
_IdPOP3.Username := _Username;
_IdPOP3.Password := _Userpwd;
_IdPOP3.AutoLogin := True;
_IdPOP3.Connect ();
A propriedade AutoLogin ajustada com o valor true indica que o componente tentará automaticamente fazer o login no servidor sempre que isso for necessário, evitando que tenhamos que comandar o login manualmente.
Uma vez que temos a conexão estabelecida, podemos iniciar a recuperação das mensagens da caixa de entrada. Há basicamente dois níveis de informação que conseguimos recuperar sobre uma mensagem. Em ambos os casos, as informações são armazenadas numa variável do tipo TIdMessage. No primeiro nível, são obtidos somente os dados de cabeçalho da mensagem - como o assunto, o remetente e os destinatários -, o que reduz o tráfego na rede. O trecho abaixo recupera o cabeçalho da primeira mensagem da caixa de entrada:
var msg : TidMessage;
begin
msg := TidMessage.Create(self);
_IdPOP3.RetrieveHeader (1, msg);
{ ... }
msg.Free;
begin
msg := TidMessage.Create(self);
_IdPOP3.RetrieveHeader (1, msg);
{ ... }
msg.Free;
O segundo nível permite recuperar a mensagem completa, incluindo todas as informações do nível anterior, bem como o corpo da mensagem e todos os anexos dela. Ao utilizar esse método, a caixa postal marca automaticamente a mensagem como lida:
var msg : TidMessage;
begin msg := TidMessage.Create(self);
_IdPOP3.Retrieve (1, msg);
{ ... }
msg.Free;
begin msg := TidMessage.Create(self);
_IdPOP3.Retrieve (1, msg);
{ ... }
msg.Free;
Com as informações obtidas nesse nível, temos maior flexibilidade para customizar tratamentos para as mensagens. Por exemplo, podemos redirecionar a mensagem para outra pessoa de acordo com o conteúdo ou processar os anexos, salvando-os numa pasta do computador ou num banco de dados.
Não podemos esquecer que o conteúdo de um email pode ser composto de diversas partes distintas, conforme mostrei no post sobre envio de email com Delphi. Então, dependendo de como o email foi composto, recuperar o corpo da mensagem pode ser um simples acesso à propriedade msg.Body.Text ou significará termos que percorrer a lista de partes para determinar qual é o texto contido. Se o texto no corpo está em branco, basta percorrer a lista de partes procurando por uma que seja do tipo texto (TIdText):
var { ... }
parte : TIdMessagePart;
texto : TIdText;
corpo : string;
begin
{ ... }
_IdPOP3.Retrieve(1, msg);
for j := 0 to msg.MessageParts.Count - 1 do begin
parte := msg.MessageParts.Items[j];
{ Verifica se a parte é um texto }
if (parte is TIdText) then begin
texto := parte as TIdText;
corpo := texto.Body.Text;
break;
end;
{ ... }
parte : TIdMessagePart;
texto : TIdText;
corpo : string;
begin
{ ... }
_IdPOP3.Retrieve(1, msg);
for j := 0 to msg.MessageParts.Count - 1 do begin
parte := msg.MessageParts.Items[j];
{ Verifica se a parte é um texto }
if (parte is TIdText) then begin
texto := parte as TIdText;
corpo := texto.Body.Text;
break;
end;
{ ... }
O tipo do texto contido numa parte fica informado na propriedade ContentType. Como é permitido ter mais que uma parte com texto, pode-se testar esse tipo para recuperar o texto que interessa. É comum enviar uma parte com texto HTML e outra com texto TEXT/PLAIN para que o programa leitor de email decida qual exibir, de acordo com a opção feita pelo usuário.
Da mesma forma que recuperamos o texto lendo as partes, podemos salvar os anexos. Para isso, a parte deve ser do tipo TIdAttachment. Também podemos determinar o tipo do conteúdo do anexo lendo a propriedade ContentType da parte em questão. Salvar o arquivo fica fácil :
{ ... }
for j := 0 to msg.MessageParts.Count - 1 do begin
parte := msg.MessageParts.Items[j];
{ Verifica se a parte é um anexo }
if (parte is TIdAttachment) then begin
anexo := parte as TIdAttachment;
anexo.SaveToFile('c:\temp\' + anexo.FileName);
end;
{ ... }
for j := 0 to msg.MessageParts.Count - 1 do begin
parte := msg.MessageParts.Items[j];
{ Verifica se a parte é um anexo }
if (parte is TIdAttachment) then begin
anexo := parte as TIdAttachment;
anexo.SaveToFile('c:\temp\' + anexo.FileName);
end;
{ ... }
Mas, como saber quais mensagens podem ser recuperadas ? A quantidade de mensagens existentes é conseguida através da função CheckMessages; podemos recuperar qualquer uma delas usando um número inteiro entre 1 e essa quantidade. A lista é trazida em ordem cronológica, com as mensagens mais antigas da caixa de entrada possuindo os menores números de identificação.
for i := 1 to _IdPOP3.CheckMessages do
begin
msg := TidMessage.Create(self);
_IdPOP3.RetrieveHeader (i, msg);
if DeveRecuperarMsg (msg.MsgId) then
TrataMsg (Msg);
msg.Free;
end;
begin
msg := TidMessage.Create(self);
_IdPOP3.RetrieveHeader (i, msg);
if DeveRecuperarMsg (msg.MsgId) then
TrataMsg (Msg);
msg.Free;
end;
As mensagens lidas permanecem na caixa até que sejam removidas. O POP3 permite fazer essa remoção mas nem sempre isso é uma opção. Para esses casos, uma sugestão é controlar manualmente as mensagens. Elas possuem uma string de identificação chamada MsgID que é única, como mostra o código acima. A ideia é recuperar apenas o cabeçalho da mensagem, testar se o MsgID atual já foi tratado antes e só então trazer a mensagem completa, se for necessário.
Quando concluir as operações na caixa postal, finalize a conexão com o POP3 usando a função Disconnect.
Como se pode ver pelo exemplo retratado neste post, o protocolo POP3 é bastante simples, limitando-se a poucas funcionalidades básicas. Se for preciso usar recursos mais avançados, tais como restringir as mensagens recuperadas usando filtros ou realizar operações envolvendo "pastas" na caixa postal, teremos que apelar a um protocolo mais completo, como o IMAP4. Mostro em outra oportunidade como usá-lo.

Show de bola! Muito obrigado por compartilhar esta informação!
ResponderExcluircara muito bom , porem to tentando de usar o chekmenssages , mas ele s'o me retorna "0" (zero) mesmo com menssagens na cx de email !
ResponderExcluirtem alguma sugestao ?
Marcelo
ResponderExcluirUma possibilidade é que você tenha feito a conexão com um "servidor / conta de email" diferente daquele que vc imaginou. Revise suas configurações para ver se é esse o caso.
Veja também se as mensagens que você tem estão na caixa postal ou em subpastas. Não tenho certeza mas acredito que o CheckMessages só é capaz de enxergar o que está diretamente na caixa de entrada.
Se você precisa trabalhar com pastas ou quer mais flexibilidade no acesso aos emails, use o IMAP4.
Marcelo :
ResponderExcluirmuito obrigdo pelo retorno ! fiquei surpreso !
bom vamos la !
que esta ocorrendo e que , ao bx a menssagem
ele nao baixa mais , queria saber se tem como mudar o status da menssagem , para que possa baixa quantas vezez quizer ! sera q tem como ?
Marcelo
ResponderExcluirO que vc quer dizer com "a mensagem não baixa mais" ?. Após serem recuperadas com os métodos mostrados no post, as mensagens continuam disponíveis no servidor - a não ser que sejam removidas.
O que pode acontecer é ela ser marcada como "já lida". Se quer marcá-la novamente como "não lida", terá que usar o IMAP4 pois o POP3 não prevê essa alternativa.
Marcelo :
ResponderExcluirok , parti entao para o imap ,
show de bola!!
no seu blog imap4 , tem uma procedure ou funcao de nome
SelecionaCaixaPostal que nao tem seu conteudo no codigo
teria como vc me fornecer esta ? ou me explicar como funciona !
muito obrigado !
Marcelo
ResponderExcluirComo diz o comentário incluído no fonte, a função SelecionaCaixaPostal pega os nomes das caixas postais levantadas pelo ListMailBoxes e os mostra num form separado para que o usuário possa escolher qual deve ser aberta.
A seleção feita pelo usuário é retornada na variável lCaixaSel, que por sua vez é usada em SelectMailBox para efetivamente abrir a caixa escolhida.
[]s
Ola Luis, Gostaria de mandar para lixeira ou até mesmo apagar as mensagens já recebidas, de uma só vez, isso é possivel usando o POP3, desde já agradeço.
ResponderExcluirSouza
ExcluirAté onde eu conheço, você terá que usar a função Delete para remover as mensagens. Só que o jeito que ela trabalha exigirá uma chamada para cada mensagem que queira remover, já que ela aceita como parâmetro a identificação de uma única mensagem.
[]s