Envio de e-mail com componentes Indy

DAVID CANDIDO DA SILVA

DAVID CANDIDO DA SILVA Publicado 16/11/2017 


Pessoal, para o exemplo apresentado no artigo, utilizarei novamente o servidor do Gmail, no entanto, nada impede o uso de outros servidores, desde que as configurações sejam definidas corretamente (servidor SMTP, porta, tipo de autenticação e protocolos de segurança).
Dessa vez, como estamos codificando a funcionalidade no Delphi XE, trabalharemos com 5 objetos do conjunto Indy, criados em tempo de execução: TIdSMTP, TIdMessage, TIdText, TIdAttachmentFile e TIdSSLIOHandlerSocketOpenSSL. Cada um destes objetos serão instanciados, interligados, utilizados e, após o envio, liberados da memória.

Primeiramente, é importante lembrar que as DLLs ssleay32.dll e libeay32.dll são necessárias para o envio do e-mail e devem ser copiadas para a mesma pasta onde está o executável. É aqui que a galera geralmente se perde. Muitos desenvolvedores copiam as DLLs para a pasta em que o arquivo DPROJ se encontra, já que o Delphi 7, por padrão, cria o arquivo executável na mesma pasta do projeto. Porém, as versões mais recentes do Delphi geram o executável no subdiretório “\plataforma\configuração”, como, por exemplo, “Win32\Debug”. É nesse diretório que as DLLs devem ser copiadas!
Antes que eu me esqueça, uma observação: existem várias versões disponíveis dessas DLLs. Já ajudei desenvolvedores que tentaram utilizar a versão compatível com o Delphi 7 em um projeto no Delphi XE e se depararam com alguns avisos de incompatibilidade. Portanto, para o Delphi XE, clique aqui para baixar a versão correta.

Bom, mãos à obra!
Antes de iniciarmos a codificação, devemos declarar as units das classes do Indy na seção uses do formulário:

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

 

Em seguida, já podemos implementar o código de envio do e-mail (atentem-se aos comentários):

var
  // variáveis e objetos necessários para o envio
  IdSSLIOHandlerSocket: TIdSSLIOHandlerSocketOpenSSL;
  IdSMTP: TIdSMTP;
  IdMessage: TIdMessage;
  IdText: TIdText;
  sAnexo: string;
begin
  // instanciação dos objetos
  IdSSLIOHandlerSocket := TIdSSLIOHandlerSocketOpenSSL.Create(Self);
  IdSMTP := TIdSMTP.Create(Self);
  IdMessage := TIdMessage.Create(Self);
    try
    // Configuração do protocolo SSL (TIdSSLIOHandlerSocketOpenSSL)
    IdSSLIOHandlerSocket.SSLOptions.Method := sslvSSLv23;
    IdSSLIOHandlerSocket.SSLOptions.Mode := sslmClient;
      // Configuração do servidor SMTP (TIdSMTP)
    IdSMTP.IOHandler := IdSSLIOHandlerSocket;
    IdSMTP.UseTLS := utUseImplicitTLS;
    IdSMTP.AuthType := satDefault;
    IdSMTP.Port := 465;
    IdSMTP.Host := 'smtp.gmail.com';
    IdSMTP.Username := 'usuario@gmail.com';
    IdSMTP.Password := 'senha';
      // Configuração da mensagem (TIdMessage)
    IdMessage.From.Address := 'remetente@gmail.com';
    IdMessage.From.Name := 'Nome do Remetente';
    IdMessage.ReplyTo.EMailAddresses := IdMessage.From.Address;
    IdMessage.Recipients.Add.Text := 'destinatario1@email.com';      IdMessage.Recipients.Add.Text := 'destinatario2@email.com'; // opcional
    IdMessage.Recipients.Add.Text := 'destinatario3@email.com'; // opcional
    IdMessage.Subject := 'Assunto do e-mail';
    IdMessage.Encoding := meMIME;
      // Configuração do corpo do email (TIdText)
    IdText := TIdText.Create(IdMessage.MessageParts);
    IdText.Body.Add('Corpo do e-mail');
    IdText.ContentType := 'text/plain; charset=iso-8859-1';
      // Opcional - Anexo da mensagem (TIdAttachmentFile)
    sAnexo := 'C:\Anexo.pdf';
    if FileExists(sAnexo) then
    begin
      TIdAttachmentFile.Create(IdMessage.MessageParts, sAnexo);
    end;
      // Conexão e autenticação
    try
      IdSMTP.Connect;
      IdSMTP.Authenticate;
    except
      on E:Exception do
      begin
        MessageDlg('Erro na conexão ou autenticação: ' +
          E.Message, mtWarning, [mbOK], 0);
        Exit;
      end;
    end;
      // Envio da mensagem
    try
      IdSMTP.Send(IdMessage);
      MessageDlg('Mensagem enviada com sucesso!', mtInformation, [mbOK], 0);
    except
      On E:Exception do
      begin
        MessageDlg('Erro ao enviar a mensagem: ' +
          E.Message, mtWarning, [mbOK], 0);
      end;
    end;
  finally
    // desconecta do servidor
    IdSMTP.Disconnect;
    // liberação da DLL
    UnLoadOpenSSLLibrary;
    // liberação dos objetos da memória
    FreeAndNil(IdMessage);
    FreeAndNil(IdSSLIOHandlerSocket);
    FreeAndNil(IdSMTP);
  end;
end;

 

Ao realizar o envio, haverá uma pausa de alguns segundos durante a conexão, autenticação e envio da mensagem. Nesse meio tempo, teremos a impressão de que a aplicação não estará respondendo. Para evitar este efeito, eu sugiro implementar uma tela de espera (com um GIF animado, por exemplo), exibir uma mensagem de processamento ou utilizar uma Thread para que o envio seja feito em um fluxo paralelo de processamento.

Embora as propriedades no exemplo acima tenham sido atribuídas em tempo de execução, elas também podem, opcionalmente, ser definidas em tempo de projeto, utilizando o Object Inspector. Se o e-mail possui valores fixos (conta de e-mail, servidor, assunto), talvez essa possa ser a melhor opção devido à redução das linhas de código. Do mesmo modo, alguns valores podem ser definidos em tempo de projeto e outros valores informados em tempo de execução, como o destinatário e o corpo da mensagem, digitados pelo usuário em caixas de texto.

Só a título de conhecimento, caso a aplicação não esteja conseguindo se conectar ao servidor, talvez seja necessário alterar algumas configurações na conta do Gmail, conforme as orientações dispostas neste link.

 

Bônus 1: Para enviar um e-mail formatado em HTML, basta utilizar o objeto TIdText no exemplo acima e inserir as tags da linguagem:

IdText := TIdText.Create(IdMessage.MessageParts);
IdText.Body.Add('<html>');
IdText.Body.Add('<body>');
IdText.Body.Add('<h1><font color="red"> Teste Formatação em HTML </font></h1>');
IdText.Body.Add('</body>');
IdText.Body.Add('</html>');
IdText.ContentType := 'text/html; charset=iso-8859-1';

 

Bônus 2: Caso esteja utilizando o servidor do Terra, utilize as configurações a seguir (colaboração do leitor Ricardo Silva):

// Configuração do SMTP
IdSMTP.AuthenticationType := atLogin;
IdSMTP.Port := 587;
IdSMTP.Host := 'smtp.sao.terra.com.br';
IdSMTP.Username := 'usuario@terra.com.br';
IdSMTP.Password := 'senha';

 

Bônus 3: Aproveitando a dica acima, confira também as configurações do servidor do Office365:

// Configuração do SSL
IdSSLIOHandlerSocket.SSLOptions.Method := sslvTLSv1;
IdSSLIOHandlerSocket.PassThrough := True;
IdSSLIOHandlerSocket.SSLOptions.Mode := sslmServer;
 
// Configuração do SMTP
IdSMTP.IOHandler := IdSSLIOHandlerSocket;
IdSMTP.AuthenticationType := atLogin;
IdSMTP.Port := 587;
IdSMTP.Host := 'smtp.office365.com';
IdSMTP.Username := 'usuario';
IdSMTP.Password := 'senha';


Grande abraço, leitores! Até mais!

David Candido

 

Voltar ao topo