Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Internet (https://www.clubdelphi.com/foros/forumdisplay.php?f=3)
-   -   Error en envío de mail con adjunto + Indy 10 (https://www.clubdelphi.com/foros/showthread.php?t=68256)

agustibaldo 03-06-2010 16:24:50

Error en envío de mail con adjunto + Indy 10
 
Amigos de ClubDelphi, tengo el siguiente problema.
Resulta que necesito enviar un archivo adjunto desde mi aplicación y que además incluya un texto muy cortito en el cuerpo del mensaje.

Para ello, encontré en este foro que la forma era la siguiente: TIdAttachmentFile.Create(MailMessage.MessageParts, AdjuntoEmail);
Pues bien, el problema se me presenta en varios casos.

Caso 1: Adjunto sin texto en cuerpo.
Al probar mandar el adjunto sin incluir un texto en el cuerpo del mensaje funcionaba correctamente.

Caso 2: Adjunto con texto en el cuerpo.
Ahora incluyendo el texto deseado en el cuerpo, al recibir el correo muestra una serie kilométrica de caracteres extraños y no recibo el adjunto.

Caso 3: Texto sin adjunto.
Probando comente las líneas donde adjunta e incluí un texto para el cuerpo del mensaje y lo recibí correctamente.

Alguien me puede dar una mano con esto.
Cualquier cosa que no entiendan me avisan y trato de explicarme mejor. :o

erickahr 04-06-2010 18:04:17

Saludos
 
mira yo batalle un poco con ese asunto de los Mails, principalmente mi problema era para los correos de GMail por el asunto de SSL, aki te dejo ati y a quien le pueda servir este fuente, es una DLL que hice a basandome en un codigo de Roman. Espero sea de utilidad, al menos como guia o pauta, para sacar su propio codigo.

Código Delphi [-]
library SendgMail;
{ Important note about DLL memory management: ShareMem must be the
  first unit in your library's USES clause AND your project's (select
  Project-View Source) USES clause if your DLL exports any procedures or
  functions that pass strings as parameters or function results. This
  applies to all strings passed to and from your DLL--even those that
  are nested in records and classes. ShareMem is the interface unit to
  the BORLNDMM.DLL shared memory manager, which must be deployed along
  with your DLL. To avoid using BORLNDMM.DLL, pass string information
  using PChar or ShortString parameters. }
uses
  ShareMem,
  SysUtils, IdAttachment, IdAttachmentFile, IdMessage, IdIOHandler,
  IdIOHandlerSocket, IdIOHandlerStack, IdSSL, IdSSLOpenSSL, IdBaseComponent,
  IdComponent, IdTCPConnection, IdTCPClient, IdExplicitTLSClientServerBase,
  IdMessageClient, IdSMTPBase, IdSMTP, Classes;

var
  SMTP:         TIdSMTP;
  ManejadorSSL: TIdSSLIOHandlerSocketOpenSSL;
  Mensaje:      TIdMessage;
{$R *.res}
 
Procedure InitSMTP(smtpHost,smtpContra,smtpPuerto,smtpUser: String); stdCall;
begin
SMTP        := TidSMTP.Create;
ManejadorSSL:= TIdSSLIOHandlerSocketOpenSSL.Create;
Mensaje     := TIdMessage.Create;
  with SMTP do
    begin
    AuthType:=atDefault;
    Host:=smtpHost;
    IOHandler:=ManejadorSSL;
    MailAgent:='Email 6.1';
    Password:=smtpContra;
    PipeLine:=False;
    Port:=StrToInt(smtpPuerto);
    UseEhlo:=True;
    UserName:=smtpUser;
    UseTLS:=utUseExplicitTLS;
    end;
  with  ManejadorSSL do
    begin
    RecvBufferSize:=65000;
    SendBufferSize:=65000;
    SSLOptions.Method:=sslvSSLv3;
    SSLOptions.Mode:=sslmUnassigned;
    SSLOptions.VerifyDepth:=0;
    SSLOptions.VerifyMode:=[];
    UseNagle:=False;
    end;
end;

procedure MandaAdjunto(sArchivo, FAddress, TAddress, xMensaje, xAsunto: String); stdCall;
begin
  With Mensaje do
    begin
    From.Address              := FAddress;
    Recipients.EMailAddresses := TAddress;
    Subject                   := xAsunto
    Body.Text                 := xMensaje;
    TIdAttachmentFile.Create(MessageParts, sArchivo);
    end;
  With SMTP do
    begin
    try
      Connect;
    except
      raise Exception.Create( 'Error al conectar con el servidor.' );
    end;
    if Connected then
      begin
      try
        Send(Mensaje);
        Enviado := True;
      except
        raise Exception.Create( 'Error al enviar el mensaje.' );
      end;
    end;
      try
        Disconnect;
      except
        raise Exception.Create( 'Error al desconectar del servidor.' );
      end;
    end;
    End
end;
exports InitSMTP;
exports MandaAdjunto;

begin
end.


Esto te genera una dll llamada SendGMail.dll.
Una vez publecada la DLL la pones en el directorio de tu aplicacion, y puedes llamar los procedimientos de la siguiente forma, por ejemplo:

Primero llamamos a los procedimientos desde el exterior:
Código Delphi [-]
procedure InitSMTP(smtpHost,smtpContra,smtpPuerto,smtpUser: String); stdcall external 'SendgMail.dll';
procedure MandaAdjunto(sArchivo, FAddress, TAddress: String; Fecha: TDateTime); stdcall external 'SendgMail.dll';

Despues en un boton podemos poner lo siguiente para ejecutar el envio del mail.

Código Delphi [-]
 InitSMTP(smtp.gmail.com,******,587,erickahr86); 
 MandaAdjunto('C:\Archivo.rar',remitente@gmail.com , destinatario@gmail.com, Memo1.text, Edit1.text); stdCall;


Espero les sea de ayuda compañeros, y trato de devolver a la cumunidad una minimaparte de todo lo que me ha dado. :D

agustibaldo 04-06-2010 18:17:50

erickahr muchas gracias por tu respuesta. tu implementación me pareció útil para aplicarla en formato de DLL.

Mirando el código no noto algo distinto a los que estoy haciendo yo. Con respecto a SSL que mencionas, el servidor de donde salen los correos no utiliza esta tecnología de autenticación.

Nuevamente gracias por tu respuesta.

erickahr 04-06-2010 18:20:51

Nada que agradecer hermano, espero te sea de utilidad a ti y a muchos otros compañeros, que como yo vamos iniciando en este asunto de delphi/internet.

gustavosv 27-07-2011 20:50:45

Hola agustibaldo, quisiera preguntarte si pudiste solucionar el inconveniente, el asunto es que me está sucediendo igual.

He intentado con servidores de terra.es y gmail.com pero me sucede lo mismo, cuando escribo algo como parte del cuerpo del mensaje, el archivo adjunto se decodifica como parte del mensaje y no aparecen sino números y letras raras.

Te agradezco si me puedes orientar ...

GustavoSV

agustibaldo 27-07-2011 20:59:30

gustavosv te copio el link a un hilo donde preguntaba algo parecido. Respuesta

Espero que te ayude.
Saludos

kurono 05-08-2011 02:30:09

esta muy bueno la dll pero siempre que veo este tipo de hilo mayormente siempre los envio que se hacen es para Gmail que pasa con Hotmail y Yahoo pues me gustaria agregar esos codigo a la dll

defcon1_es 04-06-2013 18:13:54

Hola.
Revivo este hilo porque me ha sucedido lo mismo que a agustibaldo y la solución es bien simple:

Código Delphi [-]
IdMessage1.ContentType := 'multipart/mixed';

sacado de aquí: http://forums2.atozed.com/viewtopic.php?f=7&t=18308

esto soluciona el problema del caso 2:

Caso 2: Adjunto con texto en el cuerpo.
Ahora incluyendo el texto deseado en el cuerpo, al recibir el correo muestra una serie kilométrica de caracteres extraños y no recibo el adjunto.

Salu2.

F3niX 23-01-2015 21:23:31

Cita:

Empezado por erickahr (Mensaje 366212)
mira yo batalle un poco con ese asunto de los Mails, principalmente mi problema era para los correos de GMail por el asunto de SSL, aki te dejo ati y a quien le pueda servir este fuente, es una DLL que hice a basandome en un codigo de Roman. Espero sea de utilidad, al menos como guia o pauta, para sacar su propio codigo.

Código Delphi [-]
library SendgMail;
{ Important note about DLL memory management: ShareMem must be the
  first unit in your library's USES clause AND your project's (select
  Project-View Source) USES clause if your DLL exports any procedures or
  functions that pass strings as parameters or function results. This
  applies to all strings passed to and from your DLL--even those that
  are nested in records and classes. ShareMem is the interface unit to
  the BORLNDMM.DLL shared memory manager, which must be deployed along
  with your DLL. To avoid using BORLNDMM.DLL, pass string information
  using PChar or ShortString parameters. }
uses
  ShareMem,
  SysUtils, IdAttachment, IdAttachmentFile, IdMessage, IdIOHandler,
  IdIOHandlerSocket, IdIOHandlerStack, IdSSL, IdSSLOpenSSL, IdBaseComponent,
  IdComponent, IdTCPConnection, IdTCPClient, IdExplicitTLSClientServerBase,
  IdMessageClient, IdSMTPBase, IdSMTP, Classes;

var
  SMTP:         TIdSMTP;
  ManejadorSSL: TIdSSLIOHandlerSocketOpenSSL;
  Mensaje:      TIdMessage;
{$R *.res}
 
Procedure InitSMTP(smtpHost,smtpContra,smtpPuerto,smtpUser: String); stdCall;
begin
SMTP        := TidSMTP.Create;
ManejadorSSL:= TIdSSLIOHandlerSocketOpenSSL.Create;
Mensaje     := TIdMessage.Create;
  with SMTP do
    begin
    AuthType:=atDefault;
    Host:=smtpHost;
    IOHandler:=ManejadorSSL;
    MailAgent:='Email 6.1';
    Password:=smtpContra;
    PipeLine:=False;
    Port:=StrToInt(smtpPuerto);
    UseEhlo:=True;
    UserName:=smtpUser;
    UseTLS:=utUseExplicitTLS;
    end;
  with  ManejadorSSL do
    begin
    RecvBufferSize:=65000;
    SendBufferSize:=65000;
    SSLOptions.Method:=sslvSSLv3;
    SSLOptions.Mode:=sslmUnassigned;
    SSLOptions.VerifyDepth:=0;
    SSLOptions.VerifyMode:=[];
    UseNagle:=False;
    end;
end;

procedure MandaAdjunto(sArchivo, FAddress, TAddress, xMensaje, xAsunto: String); stdCall;
begin
  With Mensaje do
    begin
    From.Address              := FAddress;
    Recipients.EMailAddresses := TAddress;
    Subject                   := xAsunto
    Body.Text                 := xMensaje;
    TIdAttachmentFile.Create(MessageParts, sArchivo);
    end;
  With SMTP do
    begin
    try
      Connect;
    except
      raise Exception.Create( 'Error al conectar con el servidor.' );
    end;
    if Connected then
      begin
      try
        Send(Mensaje);
        Enviado := True;
      except
        raise Exception.Create( 'Error al enviar el mensaje.' );
      end;
    end;
      try
        Disconnect;
      except
        raise Exception.Create( 'Error al desconectar del servidor.' );
      end;
    end;
    End
end;
exports InitSMTP;
exports MandaAdjunto;

begin
end.


Esto te genera una dll llamada SendGMail.dll.
Una vez publecada la DLL la pones en el directorio de tu aplicacion, y puedes llamar los procedimientos de la siguiente forma, por ejemplo:

Primero llamamos a los procedimientos desde el exterior:
Código Delphi [-]
procedure InitSMTP(smtpHost,smtpContra,smtpPuerto,smtpUser: String); stdcall external 'SendgMail.dll';
procedure MandaAdjunto(sArchivo, FAddress, TAddress: String; Fecha: TDateTime); stdcall external 'SendgMail.dll';

Despues en un boton podemos poner lo siguiente para ejecutar el envio del mail.

Código Delphi [-]
 InitSMTP(smtp.gmail.com,******,587,erickahr86); 
 MandaAdjunto('C:\Archivo.rar',remitente@gmail.com , destinatario@gmail.com, Memo1.text, Edit1.text); stdCall;


Espero les sea de ayuda compañeros, y trato de devolver a la cumunidad una minimaparte de todo lo que me ha dado. :D

Veo esto mucho despues pero excelente codigo, Muchas gracias.


La franja horaria es GMT +2. Ahora son las 13:31:58.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi