No começo, os programas leitores de email só conseguiam trabalhar com mensagens assim, onde apenas texto era trocado. É um comportamento básico mas que ainda tem sua utilidade, principalmente quando há questões de segurança envolvidas. Com a evolução da internet, entretanto, praticamente todos os leitores de email conseguem exibir mensagens com formatação rica. Usando HTML podemos compor emails com layouts complexos, usando cores e tipos de fontes diferentes, além da inclusão de imagens, links, tabelas, animações, entre outros. Uma grande vantagem desse formato é que ele já é utilizado para construir os sites da internet. Ou seja, HMTL é uma ferramenta bastante conhecida e amplamente suportada.
Do ponto de vista do envio de email, o que há de diferente em relação ao que foi apresentado no outro post ? Basicamente, apenas dois detalhes. O primeiro é uma propriedade da mensagem que determina o tipo de conteúdo que a mensagem está trafegando. Essa característica é chamada MIME (Multipurpose Internet Mail Extensions, ou Extensões Multipropósito para Correio na Internet). O padrão para essa propriedade no corpo de um email é o valor text/plain, que significa que a mensagem é composta por um texto simples. Como queremos montá-la como um HTML, temos que avisá-la disso:
IdMessage1.ContentType := 'text/html';
IdMessage1.CharSet := 'ISO-8859-1';
IdMessage1.CharSet := 'ISO-8859-1';
Veja que eu também modifiquei o charset da mensagem. Esta propriedade indica qual é o conjunto de caracteres que a mensagem está usando. Como o português usa acentuação, é preferível trocar o padrão americano pelo conjunto latino ('ISO-8859-1').
O outro detalhe é que o corpo da mensagem agora tem que respeitar o MIME configurado. Quero dizer com isso que teremos que montar um HTML para a mensagem:
IdMessage1.Body.Text := '<html><head>' +
'<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">' +
'</head><body>' +
'<p>Essa mensagem é um <b>Teste</b> de email HTML.</p>' +
'</body></html>';
'<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">' +
'</head><body>' +
'<p>Essa mensagem é um <b>Teste</b> de email HTML.</p>' +
'</body></html>';
Embora pareça redundante, é importante informar de novo no cabeçalho do HTML quem é o MIME e o charset. Os leitores de email utilizam as informações desse cabeçalho para renderizar a mensagem recebida via SMTP.
E se quisermos incluir uma imagem em nosso HTML ? Algumas pessoas publicam a imagem na internet e referenciam o link dela no HTML da mensagem. Mas essa solução exige que o destinatário esteja conectado para poder buscar a imagem, coisa que nem sempre é verdade. Numa empresa, por exemplo, as mensagens são recebidas de forma centralizada por um servidor de email, dispensando a necessidade de ter internet local. Muitas delas adotam ainda restrições ao acesso à internet.
Uma maneira melhor de se fazer isso é enviar a imagem junto com o HTML. Ao invés de preencher o campo Body da mensagem, teremos que decompô-la em seus constituintes básicos para podermos identificar de forma separada o MIME de cada um. Isto é, o corpo da mensagem é um HTML enquanto a imagem é um arquivo binário com MIME próprio. O conjunto todo terá um MIME especial (multipart/mixed) que sinaliza que a mensagem está montada como múltiplas partes independentes.
Cada parte deverá ser anexada à mensagem através da propriedade MessageParts. Para o corpo, usamos o tipo TIdText. Para a imagem, o tipo tradicional para anexos (TIdAttachmentFile).
var
text : TIdText;
at : TIdAttachmentFile;
begin
IdMessage1.MessageParts.Clear();
IdMessage1.ContentType := 'multipart/mixed';
text := TIdText.Create (IdMessage1->MessageParts, Nil);
text.ContentType := 'text/html';
text.CharSet := 'ISO-8859-1';
text.Body.Text := PreparaHTML();
at := TIdAttachmentFile.Create (IdMessage1->MessageParts,
'C:\\Inetpub\\wwwroot\\winxp.gif');
at.ContentType := 'image/gif';
at.FileName := 'winxp.gif';
IdSMTP1.Connect();
IdSMTP1.Send(IdMessage1);
{ ... }
text : TIdText;
at : TIdAttachmentFile;
begin
IdMessage1.MessageParts.Clear();
IdMessage1.ContentType := 'multipart/mixed';
text := TIdText.Create (IdMessage1->MessageParts, Nil);
text.ContentType := 'text/html';
text.CharSet := 'ISO-8859-1';
text.Body.Text := PreparaHTML();
at := TIdAttachmentFile.Create (IdMessage1->MessageParts,
'C:\\Inetpub\\wwwroot\\winxp.gif');
at.ContentType := 'image/gif';
at.FileName := 'winxp.gif';
IdSMTP1.Connect();
IdSMTP1.Send(IdMessage1);
{ ... }
O HTML pode, então, fazer referência diretamente ao nome do arquivo anexado, sem precisar estipular um endereço na internet. A única coisa é que o nome do arquivo deve ser exatamente igual àquele informado na propriedade FileName do anexo:
function TForm1.PreparaHTML : String;
begin
{ ... }
Result := Result + '<img style="margin:1px 1px 1px 0px;" src="winxp.gif" />';
{ ... }
end;
begin
{ ... }
Result := Result + '<img style="margin:1px 1px 1px 0px;" src="winxp.gif" />';
{ ... }
end;
Em tese, não há restrição a quantos recursos externos podem ser agregados ao email usando esse tipo de construção. Também não se restringe à inclusão de imagens, podendo ser usado para incorporar animações, scripts, folhas de estilo, etc. - desde que tenham os respectivos MIMEs devidamente configurados.
Estou com a versão 10 do Indy que vem com o Delphi XE mas acredito que os recursos mostrados aqui estejam disponíveis em versões anteriores também.

TIdText não é reconhecido no delphi 2010, o que faço para substituir ?
ResponderExcluirSou especialista em SI pela UFLA gostaria de fazer uma indicação para sua equipe, tenho um colega na petrobrás que é um gênio em ti, seria interessante aproveitar o conhecimento de todos para melhorar a tecnologia em ti do nosso país.
ResponderExcluirum abraço.
Fábio
ResponderExcluirO que exatamente quer dizer com "indicação pra minha equipe" ? Na verdade, o blog hj é apoiado pela ABC71 mas mantido apenas por mim...
Se a ideia é submeter posts ao blog, toda ajuda é bem-vinda ! Pode remeter o texto ao email do blog e, se for o caso, o publicarei com os devidos créditos.
[]s
Vicente
ResponderExcluirO TidText mudou de lugar. No Indy9, ele estava junto com a unit IdMessage enquanto no Indy10 ele foi deslocado para uma unit própria.
Isto quer dizer que basta adicionar a unit IdText na cláusula uses do seu fonte para que ele encontre o TIdText.
[]
Saudações Luís Gustavo.
ResponderExcluirParabéns pelos post's.
Estou com um probleminha no envio de e-mail.
Desenvolvi um software em Delphi 2010 com MySql. Nesse software, o cliente deve efetuar um login.
Acontece que estou tentando implementar uma opção para o cliente de reenvio de senha, caso esse não a lembre.
Fiz alguns testes com a dupla IdSMTP e TIdMessage. O procedimento é bem simples, pois o servidor tem a opção sem o protocolo SSL. Entretanto quando envio um e-mail, esse e-mail não chega no destino. Também não ocorre nenhuma mensagem de erro ao enviá-lo.
A porta sugerida pelo site de hospedagem, sem o protocolo SSL, é a 26.
Através do Outlook 2007 consigo enviar os e-mails normalmente.
Se você puder me ajudar com alguma ideia, agradeço.
João
ExcluirVocê pode criar um log inteceptando a comunicação do idSMTP com o servidor pra ver onde está falhando. Inclua um TIdLogDebug ou um TIdLogFile (ambos estão na guia Indy Intercepts)em seu projeto, vinculando-o à propriedade Intercept do idSMTP.
[]s
Caro Luís Gustavo.
ResponderExcluirObrigado pela dica.
Gerei o log, como você sugeriu.
Parece que tudo correu bem. Mas, de qualquer forma vou postar a mensagem.
Por questões éticas não coloquei o nome do provedor e dos e-mail's. o que estiver em parêntesis foi alterado.
Stat Connected.
Recv 10/02/2012 22:45:28: 220-br54.(PROVEDOR) ESMTP Exim 4.69 #1 Fri, 10 Feb 2012 22:45:31 -0200 220-We do not authorize the use of this system to transport unsolicited, 220 and/or bulk e-mail.
Sent 10/02/2012 22:45:28: EHLO TeCMaisComptud
Recv 10/02/2012 22:45:28: 250-br54.(PROVEDOR) Hello TeCMaisComptud [(IP)]250-SIZE 52428800250-PIPELINING250-AUTH PLAIN LOGIN250-STARTTLS250 HELP
Sent 10/02/2012 22:45:28: AUTH LOGIN
Recv 10/02/2012 22:45:28: 334 VXNlcm5hbWU6
Sent 10/02/2012 22:45:28: c2VkaW1AZGF0YWxvZ3VlLmNvbS5icg==
Recv 10/02/2012 22:45:28: 334 UGFzc3dvcmQ6
Sent 10/02/2012 22:45:28: NjU3MjMyNDM5ODk=
Recv 10/02/2012 22:45:29: 235 Authentication succeeded
Sent 10/02/2012 22:45:29: RSET
Recv 10/02/2012 22:45:29: 250 Reset OK
Sent 10/02/2012 22:45:29: MAIL FROM: <(E-MAIL)>
Recv 10/02/2012 22:45:29: 250 OK
Sent 10/02/2012 22:45:29: RCPT TO:<(E-MAIL)>
Recv 10/02/2012 22:45:29: 250 Accepted
Sent 10/02/2012 22:45:29: DATA
Recv 10/02/2012 22:45:29: 354 Enter message, ending with "." on a line by itself
Sent 10/02/2012 22:45:29: From: "(E-MAIL)" <(E-MAIL)>Subject: TesteTo: (E-MAIL)MIME-Version: 1.0Date: Fri, 10 Feb 2012 22:45:29 -0200
Sent 10/02/2012 22:45:29: Content-Type: text/html
Sent 10/02/2012 22:45:29:
Sent 10/02/2012 22:45:29: Content-Transfer-Encoding: quoted-printable
Sent 10/02/2012 22:45:29: Content-Disposition: inline
Sent 10/02/2012 22:45:29:
Sent 10/02/2012 22:45:29:
Sent 10/02/2012 22:45:29: teste
Sent 10/02/2012 22:45:29:
Sent 10/02/2012 22:45:29: .
Recv 10/02/2012 22:45:30: 250 OK id=1Rw15p-0006j5-Hd
Sent 10/02/2012 22:45:30: QUIT
Recv 10/02/2012 22:45:30: 221 br54.(PROVEDOR) closing connection
Stat Disconnected.
João
ExcluirAparentemente o envio foi mesmo feito corretamente. Não conheço muito do gerenciamento do servidor de email mas creio que seja possível incluir nele regras que podem estar redirecionando ou barrando seu email.
Verifique se não há regras estipulando, por exemplo, que apenas emails de remementes confiáveis são entregues. Por causa disso, suas mensagens podem ter sido incluídas na caixa de spam.
[]s
Olá Luís Gustavo, estava já há algum tempo procurando uma solução para montar e-mails com imagens e agora encontrei a solução com as suas dicas. Obrigado e parabéns !!!
ResponderExcluirEduardo Flaeschen
Olá Luís Gustavo, estava procurando já há algum tempo uma solução para o envio de e-mails com imagens e encontrei nessa sua publicação, muito simples e eficiente. Parabéns e obrigado.
ResponderExcluir