Link to home
Start Free TrialLog in
Avatar of Stef Merlijn
Stef MerlijnFlag for Netherlands

asked on

Indy - E-mail with embedded images

Hi,

I'm trying to sent an HTML-based E-mail with embedded images and also some attachments using INDY.
By now I can sent the E-mail and the HTML-format is shown in Outlook Express. But the embedded images aren't. I just see a mark with a red cross. After pressing the bar to show images they still aren't shown. The image is however added as an attachment to the E-mail.
I've tried multiple ContentTypes, but no luck.

Can anybody have a look at my code and see where it is going wrong?
I you need more information, please feel free to ask.
Thank you very much for any help.
procedure TFEmailVerzenden.SendEmailMessage(HTMLBestand : string; Attachments : TStringList);
var emptybody, textbody, htmlbody : TIdText;
    InhoudHTML : TStrings;
    i : Integer;
begin
  emptybody := TIdText.Create(MailMessage.MessageParts, nil);
  emptybody.ContentType                 := 'multipart/alternative';
  emptybody.ParentPart                  := -1;
 
  textbody := TIdText.Create(MailMessage.MessageParts, nil);
  textbody.Body.Text                    := '';
  textbody.ContentType                  := 'text/plain';
  textbody.ParentPart                   := 0;
 
  InhoudHTML := TStringList.Create();
  InhoudHTML.LoadFromFile(HTMLBestand);
 
  htmlbody := TIdText.Create(MailMessage.MessageParts, InhoudHTML);
  htmlbody.ContentType                  := 'text/html';
  htmlbody.ParentPart                   := 0;
 
  MailMessage.ContentType               := 'multipart/related';
  MailMessage.CharSet                   := 'iso-8859-1';
  MailMessage.Encoding                  := meMIME;
  MailMessage.From.Address              := 'info@mydomain.nl';
  MailMessage.From.Name                 := 'My Name';
  MailMessage.Recipients.EMailAddresses := 'info@mydomain2.nl';
  MailMessage.Subject                   := IOnderwerp.Text;
  MailMessage.Body.Assign(InhoudHTML);
 
  for i := 0 to Attachments.Count-1 do
  begin
    ShowMessage(Attachments.Strings[i]);
    If ExtractFileExt(Attachments.Strings[i]) <> '.htm' then
    begin
      with TIdAttachmentFile.Create(MailMessage.MessageParts, Attachments.Strings[i]) do
      begin
        ContentID                   := '<'+IntToStr(i+54320)+'>';
        FileIsTempFile              := True;  // Bestand verwijderen na verzending.
        ContentDisposition          := 'inline';
        ContentType                 := 'image/jpeg';
        ExtraHeaders.Values['content-id'] := ExtractFileName(Attachments.Strings[i]);
        DisplayName                 := ExtractFileName(Attachments.Strings[i]);
        ParentPart                  := -1;
      end;
    end;
  end;
 
  Mail.Username := 'info@mydomain.nl';
  Mail.Password := 'testpass';
  Mail.Host     := 'mail.mydomain.nl';
  Mail.Port     := 25;
 
  try
    Mail.Connect();
    try
      Mail.Send(MailMessage);
      showmessage('E-mail is succesvol verstuurd!');
    except
      ShowMessage('Fout bij het versturen van E-mail.');
    end;
  finally
    MailMessage.MessageParts.Clear;
    MailMessage.Headers.Clear;
    Mail.Disconnect;
  end;
end;

Open in new window

ASKER CERTIFIED SOLUTION
Avatar of 2266180
2266180
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Stef Merlijn

ASKER

Adding the images is done in the code below (with small change).
The images are earlier assigned to a TStringList and passed to the procedure in var Attachments.

Basically when the HTML-file contained images, then they the number of attachments > 1 (as the HTML-file itself is also passed here.

In line 7 of the previous codesnippet it indeed says:
  emptybody.ContentType                 := 'multipart/alternative';
This is supposed to be needed for the empty messagepart to satisfy clients like Outlook Express?
In line 22 however it says:
  MailMessage.ContentType               := 'multipart/related';

Maybe it is also important to look at the content-ID of the images. I read that if the content-ID connot be found the image in the E-mail will not be available. This might explain why there is a red cross (X-mark), but NO image in the E-mail. I just don't know what is wrong.
  for i := 0 to Attachments.Count-1 do
  begin
    ShowMessage(Attachments.Strings[i]);
// SMALL CHANGE HERE
    If ExtractFileExt(Attachments.Strings[i]) = '.jpg' then
    begin
      with TIdAttachmentFile.Create(MailMessage.MessageParts, Attachments.Strings[i]) do
      begin
        ContentID                   := '<'+IntToStr(i+54320)+'>';
        FileIsTempFile              := True;  // Bestand verwijderen na verzending.
        ContentDisposition          := 'inline';
        ContentType                 := 'image/jpeg';
        ExtraHeaders.Values['content-id'] := ExtractFileName(Attachments.Strings[i]);
        DisplayName                 := ExtractFileName(Attachments.Strings[i]);
        ParentPart                  := -1;
      end;
    end;
  end;

Open in new window

Avatar of TheRealLoki
If you don't solve this, I'll dig up my old code on the weekend, and paste it
From memory, the only trouble I ran into was making sure the inline image name matched.
Thank you I'll keep you informed when I get it working before the weekend.
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Thank you all.
If you are not satisfied with the answer, why are you accepting it? you think we are very happy to receive a medium grade? we WANT to do our best in order to get a A grade. I was willing to work on your demo, but you didn't make it available. it's your fault you didn't get the best answer not mine. you cannot except one person to always have all teh free time in the world to make you a demo from scratch or explain everything in detail.

well, have it your way: you don't give us (me) the chance to get an A grade, I won't give you the chance to ever getting an aswer from me. you've made it 11th on my blacklist.

no need to answer: I unsubscribed from this question.
Avatar of Limbeck
Limbeck

your welcome; out of curiosity; what is the code that you did end up with? can you post it so others may use this in the future?
I've used some new function TIdMessageBuilder (available in latest Indy snapshot). This takes automatically care of the messageparts.
procedure TFEmailVerzenden.SendEmailMessage(HTMLBestand : string; Attachments : TStringList);
var i : Integer;
begin
  with TIdMessageBuilderHtml.Create do
  try
    Subject := IOnderwerp.Text;
    PlainText.Text := 'text';
    Html.LoadFromFile(HTMLBestand);
    // Adding the images that are part of the HTML
    for i := 0 to EmailFiles.Count-1 do
    begin
      If (EmailFiles.Strings[i] <> HTMLBestand) then
      begin
        HtmlFiles.Add(EmailFiles.Strings[i]);
      end;
    end;
    // Adding an attachment
    Attachments.Add('c:\folder\archive.zip');
    FillMessage(MailMessage);
  finally
    Free;
  end;
 
  // Here you would send the E-mail
end;

Open in new window