Search code examples
delphihtml-emaildelphi-7email-attachments

Indy9 does not correctly send HTML when attachments are added


We have a windows service that's written in Delphi 7 that sends out emails containing HTML. This was working perfectly before I added attachments. After adding attachments, the HTML no longer shows as HTML but now shows as plain Text.

After some researching, I found that I have to set the mail content type to multipart/mixed however this does not seem change anything. I also found several articles showing that I have to use MessageParts when adding multiple content types like the following:

For the attachments I have the following code that works fine.

for I := 0 to slAttachments.Count -1 do
begin
  with TIdAttachment.Create(MailMessage.MessageParts, slAttachments[I]) do
  begin
    ContentType := 'application/pdf';
  end;
end;

Using TIdText as shown below leaves the body of the email empty after sending. Debugging shows that sMsg contains the correct HTML but it does not get sent with the email.

MailText := TIdText.Create(MailMessage.MessageParts, nil);
MailText.ContentType := 'text/html';
MailText.Body.Text := sMsg;

If I directly set the MailMessage body, the html shows up as plain text.

MailMessage.Body.Text := sMsg;

Full Code:

//setup mail message
MailMessage.From.Address              := msFromAddress;
MailMessage.Recipients.EMailAddresses := sToAddress;
MailMessage.Subject                   := sSubject;
MailMessage.ContentType               := 'multipart/mixed';

// Add Attachments
for I := 0 to slAttachments.Count -1 do
begin
  with TIdAttachment.Create(MailMessage.MessageParts, slAttachments[I]) do
  begin
    ContentType := 'application/pdf';
  end;
end;

// Add HTML
MailText := TIdText.Create(MailMessage.MessageParts, nil);
MailText.ContentType := 'text/html';
MailText.Body.Text := sMsg;

How can I send attachments and have the HTML shown at the same time? The same code works correctly in Delphi 10. I'm not able to upgrade this project to Delphi 10 due to some dependencies. Indy also cannot be upgraded due to breaking changes.


Solution

  • It seems to be a bug in Indy9 where the first TIdText gets ignored when attachments are added. Adding a plain TIdText seems to have fixed this issue.

    1. Add a plain text TIdText.
    2. Add the HTML TIdText you with the html body you require.
    3. Add the attachments.

    Tested and working code below. The first TIdText that contains plain text seems to be ignored however when removing it the html gets ignored.

    // Set content type for the mail message
    MailMessage.ContentType := 'multipart/mixed';
    
    // Plain text body
    With TIdText.Create(MailMessage.MessageParts, nil) do
    begin
      ContentType := 'text/plain';
      Body.Text := 'This gets ignored for some reason'; // Doesn't have to be empty
    end;
    
    // HTML (HTML body to send)
    With TIdText.Create(MailMessage.MessageParts, nil) do
    begin
      ContentType := 'text/html';
      Body.Text := '<h1>Hello World</h1>';
    end;
    
    // Attachments
    for I := 0 to slAttachments.Count -1 do
    begin
      with TIdAttachment.Create(MailMessage.MessageParts, slAttachments[I]) do
      begin
        ContentType := 'application/pdf';
      end;
    end;
    
    // Send the mail
    smtp.Send(MailMessage);