Search code examples
delphismtpindyindy10

Send email with memorystream attached


I am trying to send email with memorystream attached but I always got this message in the email I received and no attachment "This is a multi-part message in MIME format..."

Code:

var
  MemStrm : TMemoryStream;
begin
  MemStrm := TMemoryStream.Create;
  Str1.SaveToStream(MemStrm);
  MemStrm.Position := 0;

  try
  with IdSSLIOHandlerSocketOpenSSL1 do
  begin
    Destination            := 'smtp.mail.yahoo.com' + ':' + IntToStr(465);
    Host                   := 'smtp.mail.yahoo.com';
    MaxLineAction          := maException;
    Port                   := 465;
    SSLOptions.Method      := sslvTLSv1;
    SSLOptions.Mode        := sslmUnassigned;
    SSLOptions.VerifyMode  := [];
    SSLOptions.VerifyDepth := 0;
  end;
  with IdSMTP1 do
  begin
    IOHandler          := IdSSLIOHandlerSocketOpenSSL1;
    Host               := 'smtp.mail.yahoo.com';
    Port               := 465;
    AuthType           := satDefault;
    Password           := 'password';
    Username           := 'sender@yahoo.com';
    UseTLS             := utUseImplicitTLS;
  end;
  with IdMessage1 do
  begin

    From.Address              := 'sender@yahoo.com';

    List:= Recipients.Add;
    List.Address:=  'receiver@yahoo.com';
    Recipients.EMailAddresses := 'receiver@yahoo.com';
    Subject                   := 'test';
    Body.Text                 := 'test';
    ContentType               := 'text/plain';

    IdAttachment := TIdAttachmentMemory.Create(IdMessage1.MessageParts,MemStrm);
    IdAttachment.ContentType := 'text/plain';
    IdAttachment.FileName := 'attached.txt';
  end;
  finally
    idsmtp1.Connect;
    idsmtp1.Send(idmessage1);
    idsmtp1.Disconnect;
    MemStrm.Free;
  end;
end

I do not want to save it as file first then attach it, how do I attach the sample memorystream to my email?

EDIT: It didn't work even with TIdAttachmentFile, i'm using Indy10 version 10.6.0.5049 on delphi 7


Solution

  • You are setting the top-level TIdMessage.ContentType to text/plain, which tells the reader to interpret the entire email as plain text. You need to set that property to multipart/mixed instead, then the reader will interpret the attachment:

    with IdMessage1 do
    begin
      ...
      ContentType := 'multipart/mixed';
    end;
    

    I would also suggest you add a TIdText object to let the reader know what the email is about, eg:

    IdText := TIdText.Create(IdMessage1.MessageParts, nil);
    IdText.ContentType := 'text/plain';
    IdText.Body.Text := 'here is an attachment for you.';
    
    IdAttachment := TIdAttachmentMemory.Create(IdMessage1.MessageParts,MemStrm);
    IdAttachment.ContentType := 'text/plain';
    IdAttachment.FileName := 'attached.txt';
    

    Also, you are filling in the Recipients property twice. Use either Recipients.Add.Address or Recipients.EMailAddresses, do not use both:

    with IdMessage1 do
    begin
      ...
      List:= Recipients.Add;
      List.Address := 'receiver@yahoo.com';
      ...
    end;
    

    with IdMessage1 do
    begin
      ...
      Recipients.EMailAddresses := 'receiver@yahoo.com';
      ...
    end;