Enviar Email com Anexo pelo Delphi 2009!

Assim como eu, muitos encontraram dificuldades com a rotina de envio de email através de componetes do Indy. Aquela rotina que todo mundo utilizava no Delphi 6, Delphi 7, Delphi 2005, Delphi 2006 e outros não funciona para o Delphi 2009. Não é bug! São alterações existentes no Indy 10 da versão Delphi 2009, pois nas versões anteriores utilizava-se o Indy 9. Você também pode ao invés de utilizar o Indy 10, instalar o Indy 9 no Delphi 2009, mas isto é outra conversa.

Acontece que o Indy 10 veio muito diferente do Indy 9. Não há como pensar que esta diferença possa ser pior, muito pelo contrário. O Delphi 2009 veio muito mais estável que as versões anteriores e as aplicações ficam um pouco mais rápidas.

Quando eu migrei do Delphi 6 para o Delphi 2006, e na mesa época migrei de MS-SQL para Firebird, eu levei 3 (três) árduos meses para modificar inúmeras rotinas em meus sistemas. Deu um trabalhão, mas eu consegui atualizar todos os sistemas e todos os bancos de dados de meus clientes ao final de quase dois anos!

Motivo para tal? Eu precisa ganhar tempo com as futuras programações, melhorar a manutenção e torná-la mais rápidas e eficazes, e também, eu precisava baratear os custos de meus clientes com licenças e outros recursos das plataformas “não free”.

Hoje, eu trabalho bem mais descansado, pois o Banco de Dados Firebird (ligado com ADO) me oferece a simplicidade e a robustez que eu preciso para instalar e manter os recursos nos clientes. Sem contar que o Firebird pode ir embutido na aplicação, ocupando pouco espaço, e eu nem preciso estar no cliente para o Sistema ser instalado e ao mesmo tempo criar o Banco de Dados pela primeira vez.

Agora, quando eu passei do Delphi 2006 para o Delphi 2009, fiquei surpreso. uma das coisas que mais me chamou a atenção e eu achei maravilhoso foi o Help! o Help está incrivelmente mais organizado, muito mais completo, com explanação das bilbiotecas de terceiros, acesso ao Help Web e alguns bons exemplos de códigos.

O Debug do Delphi 2009 fiou muito pesado. Em um computador com 2 GB de RAM, processador de 3,6 GHz consegue sentir o peso do “bicho”, mas roda bem.

Mas, voltando ao assunto, Indy 10. Não há como negar as diferenças e elas estão dando um trabalhão para os programadores! Acontece que o Indy 10 é o recurso do futuro! Ou melhor, já é do presente e a cada dia não haverá como fugir dele (para quem utiliza Delphi). O Indy 10 veio “abarrotado” de novos recursos e instruções, e muitas delas completamente diferentes das versões anteriores. Você pode achar ruim do ponto de vista que no Indy 9 tudo era bem mais fácil, porém, o Indy 10 é mais seguro, é mais preciso nas relações “aplicativo—Web—aplicativo”, ou seja, você poderá fazer muitas coisas e avaliar muitas situações que antes não saberia como. O problema é que você terá que estudar o Indy 10 como se estuda o Delphi. Não dá mais para encarar o Indy como uma simples biblioteca com componentes. O Indy 10 agora vai mais além e, desse jeito pode acabar virando uma Linguagem Web com todos os recursos que precisamos para criar gestores de Email, IntraWeb, Aplicativos Web e outros recursos voltados para a Internet.

Bem, a rotina de envio de email pelo Delphi 2009 está postada logo abaixo. Mas é básico, você deverá fazer suas implementações como checagem de email, verificar se o provedor destino está ativo etc. Vale alertar que a rotina não é exatamente genérica, pois foi elaborada exclusivamente para um sistema que eu desenvolvi na área de saúde.

O MAIS IMPORTANTE: Você não precisará adicionar nenhuma biblioteca externa se o SMTP utilizado de seu provedor não exige autenticação! Como eu havia dito, o Indy 10 é completíssimo e é parte integrante do Delphi, portanto, não faz sentido algum utilizar-se de blilbiotecas externas para fazer o que o Delphi faz! Não caia nessa de ficar incorporando bilbliotecas (DLLs) externas ao Delphi fazendo sua aplicação ficar mais pesada e mais periogosa na manutenção!

Caso você utilize SMTP de um provedor que exija autenticação, como no caso do GMAIL, você deverá acrescentar as bibliotecas SSLeay32.dll e LIBeay32.dll na mesma pasta do seu Sistema!

Atenção: Não vamos dar esta rotina como encerrada! Dependendo de como a utilize você terá que fazer suas modificações e isto poderá implicar em novos problemas. Ainda não vi na Internet ninguém disponibilizar rotina de “envio de email” pelo Delphi 2009 que funcione corretamente. Todas (mas todas!) que eu testei tiveram problemas e nenhuma delas enviou devidamente os anexos!

O Corpo da Mensagem pode ir em HTML por que fica muito mais elegante! Enviar em HTML é bom por que você pode apontar uma URL de imagem no corpo da mensagem e o destinatário ao abir o email vai ver a imagem abrir direto, e, isto vai acontecer para a maioria dos provedores, inclusive outlook. Ou seja, não vai ficar “aquele negócio” de pedir para baixar ou abrir imagens.

Não vou comentar a rotina, pois não se trata de um tutorial. Vou dar apenas algumas dicas.

Na Cláusula USES coloque:

IdSMTP, IdMessage, IdText, IdAttachmentFile, IdSSLOpenSSL,
IdExplicitTLSClientServerBase, IdIOHandler;

Explicando a chamada a função EnviarEmail( … );

EnviarEmail( ‘Domínio=email origem’, ‘Porta’, ‘SuaContaAutenticação’, ‘SuaSenhaAutenticação’,
‘Nome Origem’, ‘Email Origem’, ‘Para=Email Destino’, ‘Assunto’, ‘Corpo da Mensagem’,
‘Mime do Corpo’, ‘Mime do Anexo’, ‘AutoResposta (s/n)’,
‘StringList com o(s) Anexo(s)’ );

// Lembre-se que alguns provedores a autenticação é só o user name e outros o email completo.

Funções:

//————————————————–
// Enviar E-mail via SMTP.
//————————————————–
function EnviarEmail( Dominio, Porta, Usuario, Senha,
DeNome, DeEmail, Para, Assunto, Corpo : String;
CorpoMIME, AnexoMIME : Integer; AutoResposta : Boolean;
Anexo : TStringList) : Boolean;
var i : Integer;
IdSMTP1 : TIdSMTP;
IdMessage : TIdMessage;
IdCorpo : TIdText;
IdAnexo : TIdAttachmentFile;
IdSSL : TIdSSLIOHandlerSocketOpenSSL;
begin
try
IdMessage := TIdMessage.Create(nil);
try
//——————————————————————————-
// Cria a Estrutura da Mensagem:
//——————————————————————————-
IdMessage.Clear;
IdMessage.IsEncoded := True;
IdMessage.AttachmentEncoding := ‘MIME';
IdMessage.Encoding := meMIME; // meDefault;
IdMessage.ConvertPreamble := True;
IdMessage.Priority := mpNormal;
IdMessage.ContentType := ‘multipart/mixed'; // obrigatoriamente!
IdMessage.CharSet := ‘ISO-8859-1′;
IdMessage.Date := Now;
//——————————————————————————-
// Define o Remetente e Destinatário:
//——————————————————————————-
IdMessage.From.Address := DeEmail; // ou ‘[EMAIL PROTECTED]‘
IdMessage.From.Text := DeNome+”;
// IdMessage.CCList.EMailAddresses := lista de com cópia
// IdMessage.BccList.EMailAddresses := lista de com cópia oculta
IdMessage.ReplyTo.EMailAddresses := DeEmail;
IdMessage.Recipients.EMailAddresses := Trim(Para);
if AutoResposta then
IdMessage.ReceiptRecipient.Text := DeEmail; // auto-resposta (confirmação de leitura!)
IdMessage.Subject := Trim( Assunto );
//——————————————————————————-
// Adiciona o CORPO da Mensagem:
//——————————————————————————-
IdCorpo := TIdText.Create(IdMessage.MessageParts,nil);
IdCorpo.ContentType := EmailTipoMIME( CorpoMIME );
IdCorpo.ContentDescription := ‘multipart-1′;
IdCorpo.CharSet := ‘ISO-8859-1′; // NOSSA LINGUAGEM PT-BR (Latin-1)!!!!
IdCorpo.ContentTransfer := ’16bit'; // para SAIR ACENTUADO !!!! Pois, 8bit SAI SEM ACENTO !!!!
IdCorpo.ContentDescription := ‘Corpo da Mensagem';
IdCorpo.Body.Clear;
IdCorpo.Body.Add( Corpo );
//——————————————————————————-
// Define o ANEXO: (pode haver looping para vários anexos)
//——————————————————————————-
for i := 0 to Pred(Anexo.Count) do
begin
if FileExists(Anexo.Strings[i]) then
begin
try
IdAnexo := TIdAttachmentFile.Create(IdMessage.MessageParts, Anexo.Strings[i]);
IdAnexo.ContentType := EmailTipoMIME(AnexoMIME)+'; ‘+
‘name=’+ExtractFileName( Anexo.Strings[i] );
IdAnexo.ContentDescription := ‘Arquivo Anexo: ‘+ExtractFileName( Anexo.Strings[i] );
except
end;
end;
end;
//
IdSMTP1 := TIdSMTP.Create(nil);
//——————————————————————————-
// Se a porta for diferente de 25 então abre o SSL para autenticação segura!
//——————————————————————————-
// Gmail e Globo usam a porta 465 (smtp) e 995 (pop3) com SSL!!!
// Hotmail usam a porta 25 (smpt.live.com) e 995 (pop3.live.com) sem SSL!
// Bol usa a porta 25 (smtp.bol.com.br) e 110 (pop3.bol.com.br) sem SSL!
//——————————————————————————-
if Porta ’25’ then ( Se Porta DIFERENTE de ’25’… o sinal de diferente está sumido aqui)
begin
With IdSMTP1 Do
try
IdSSL := TIdSSLIOHandlerSocketOpenSSL.Create( nil );
IdSMTP1.IOHandler := IdSSL;
UseTLS := utUseImplicitTLS;
except
on E: Exception do
begin
IOHandler := TIdIOHandler.MakeDefaultIOHandler( nil );
UseTLS := utNoTLSSupport;
ShowMessage(‘SSL da Autenticação Segura Falhou.’+#13+”+#13+
‘Pode ser uma instabilidade temporária na ‘+#13+
‘conexão de sua Internet.’+#13+”+#13+
‘Tente de novo agora ou mais tarde.’);
result := False;
end;
end;
IdSSL.SSLOptions.Method := sslvSSLv2;
IdSSL.SSLOptions.Mode := sslmClient;
end;

With IdSMTP1 Do
try
AuthType := SatDefault;
ReadTimeout := 10000; // Leitura da Conexão em 10 segundos!
Host := Dominio; // ‘smtp.dominio.com.br';
Port := StrToInt(Porta); // padrão seria 25 ou autenticada 465;
UserName := Usuario; // ‘usuario';
Password := Senha; // ‘senha';

try
Connect;
Authenticate;
except
on E: Exception do
begin
ShowMessage(‘Autenticação Falhou.’+#13+”+#13+
‘Verifique seu Nome de Usuário e Senha ou ‘+#13+
‘Tente de novo agora ou mais tarde.’);
result := False;
end;
end;

if Connected then
begin
Send( IdMessage );
result := True;
end else
begin
raise Exception.Create(‘A conexão com o Provedor foi interrompida.’+#13+”+#13+
‘Verifique se a sua Internet está ativa.’);
result := False;
end;
finally
Disconnect;
end;
except
result := false;
end;
finally
FreeAndNil( IdMessage );
FreeAndNil( IdSMTP1 );
end;

end;

//———————————————————-
// Função que Retorna o Tipo MIME para Cabeçalho do Email:
//———————————————————-
function EmailTipoMIME( TipoMIME : Integer ) : String;
begin
case TipoMIME of
0 : result := ‘text/plain';
1 : result := ‘text/html';
2 : result := ‘text/richtext';
3 : result := ‘text/x-aiff';
4 : result := ‘audio/basic';
5 : result := ‘audio/wav';
6 : result := ‘image/gif';
7 : result := ‘image/jpeg';
8 : result := ‘image/pjpeg';
9 : result := ‘image/tiff';
10 : result := ‘image/x-png';
11 : result := ‘image/x-xbitmap';
12 : result := ‘image/bmp';
13 : result := ‘image/x-jg';
14 : result := ‘image/x-emf';
15 : result := ‘image/x-wmf';
16 : result := ‘video/avi';
17 : result := ‘video/mpeg';
18 : result := ‘application/postscript';
19 : result := ‘application/base64′;
20 : result := ‘application/macbinhex40′;
21 : result := ‘application/pdf'; // arquivos PDF !!!
22 : result := ‘application/x-compressed';
23 : result := ‘application/x-zip-compressed';
24 : result := ‘application/x-gzip-compressed';
25 : result := ‘application/java';
26 : result := ‘application/x-msdownload';
27 : result := ‘application/octet-stream'; // arquivos .dat !!!!
28 : result := ‘multipart/mixed';
29 : result := ‘multipart/relative';
30 : result := ‘multipart/digest';
31 : result := ‘multipart/alternative';
32 : result := ‘multipart/related';
33 : result := ‘multipart/report';
34 : result := ‘multipart/signed';
35 : result := ‘multipart/encrypted';
end;
end;

Pronto. Aqui está uma rotina bem simples e básica de como enviar Email com anexo para Delphi 2009.

Porém, o provedor BOL não está indicando os anexos na mensagem, e isto eu ainda estou averiguando o motivo. No caso do Bol, vemos que os anexos certamente vão junto com a mensagem (basta ver o tamanho dos emails enviados), mas não está mostrando os nomes dos anexos para que o usuário baixe. Mas se a pessoa incluir o email do Bol no Outlook ela consegue ver os anexos.

Demais provedores (Gmail, Hotmail, Globo etc.) e inclusive o Outlook mostram os anexos perfeitamente!

Abraço a todos!

About these ads