Recent

Author Topic: Sending an email with HTML body  (Read 1021 times)

RedOctober

  • Sr. Member
  • ****
  • Posts: 330
Sending an email with HTML body
« on: August 01, 2019, 09:02:45 pm »
I can successfully send a text email using Lazarus 1.8.4 and FPC 3.0.4 and smtpsend.  Now I want to send an email with HTML in the body, and have it interpreted by the receiver's email app as an HTML document  (like I get pretty looking appointment reminders from my dentist).  However, when I use the code below to send myself an email with a fully valid HTML document as the body, I get all the HTML tags displayed along with the message text.  I use Thunderbird email.  How do I tell the receiver's email app to interpret the email as an HTML document?

Code: Pascal  [Select][+][-]
  1. function DoSendMail(const eml_hst, eml_prt, eml_usr, eml_pwd, eml_frm, eml_to, eml_sbj: String; const eml_lst: TStringList; var err_msg: String): Boolean;
  2. var SMTP: TSMTPSend;  v_hst: String;
  3. begin
  4.   Result := False;
  5.   v_hst := eml_hst + ':' + eml_prt;
  6.  
  7.   // Simplest way to send an email, when no user name or password is required, and port is 25
  8.   //if (Length(usr_nm) = 0) and (StrToInt(prt) = 25) then
  9.   if True then
  10.     begin
  11.       try
  12.         Result := SendToEx(eml_frm, eml_to, eml_sbj, v_hst, eml_lst, eml_usr, eml_pwd);
  13.       except
  14.         on E: Exception do
  15.           begin
  16.             err_msg := E.Message;
  17.           end;
  18.       end;
  19.  
  20.       Exit;
  21.     end;
  22.  
  23. end;

toby

  • Jr. Member
  • **
  • Posts: 66
Re: Sending an email with HTML body
« Reply #1 on: August 01, 2019, 09:28:12 pm »
Hi

use sendtoraw (which can send headers) instead of sendtoex (which doesn't)

put the following header (and the other headers - at least Subject) at the top of the html message file

Content-Type: text/html; charset="utf8"

then a blank line between the headers and the <html>

---

and then you can send them an email or phone call and tell ^h^h^h ask them if they' could please uncheck the box in their client that reads

Render HTML messages as text
« Last Edit: August 03, 2019, 02:38:13 am by toby »

RedOctober

  • Sr. Member
  • ****
  • Posts: 330
Re: Sending an email with HTML body
« Reply #2 on: August 01, 2019, 10:12:17 pm »
I get HTML messages all the time from random email addresses.  They render correctly in Thunderbird.  Just wondering if there is a switch or parameter in the sending function that needs adjusting.

lucamar

  • Hero Member
  • *****
  • Posts: 3017
Re: Sending an email with HTML body
« Reply #3 on: August 01, 2019, 10:16:44 pm »
That example, IIRC, sends a normal *text-only*  message, so the mail client interprets it as such. To send HTML you have to build a multipart MIME mail1 and set the content-type header of the HTML part to text/html.

Get the mesage you test-sent and another "normal" HTML message and compare them (in a text editor!) to se the differences.

I dont know exactly how to do it, though. Sorry  :-[
Is that Synapse you're using? If so, there should be examples in their wiki at synapse.ararat.cz


Note 1: Just remembered: Building a multipart message is needed only if you're also sending along a text-only version or if the HTML references other embeded resources. If not, just setting the content-type for the whole message should suffice.
« Last Edit: August 01, 2019, 10:34:15 pm by lucamar »
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus 2.0.8/FPC 3.0.4 - 32/64 bits on:
(K|L|X)Ubuntu 12..18, Windows XP, 7, 10 and various DOSes.

RedOctober

  • Sr. Member
  • ****
  • Posts: 330
Re: Sending an email with HTML body
« Reply #4 on: August 01, 2019, 11:46:56 pm »
Thank you lucamar, I'm on the right track now.

lucamar

  • Hero Member
  • *****
  • Posts: 3017
Re: Sending an email with HTML body
« Reply #5 on: August 02, 2019, 12:07:39 am »
When you solve it, would you mind posting the solution here? Just for reference, in case someone else has the same problem. :)
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus 2.0.8/FPC 3.0.4 - 32/64 bits on:
(K|L|X)Ubuntu 12..18, Windows XP, 7, 10 and various DOSes.

paweld

  • Full Member
  • ***
  • Posts: 241
Re: Sending an email with HTML body
« Reply #6 on: August 02, 2019, 07:15:39 am »
Code: Pascal  [Select][+][-]
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. var
  3.   sltext, slhtml: TStringList;
  4.   MimeMsg: TMimeMess;
  5.   SMTPSend: TSMTPSend;
  6.   MIMEPart, MIMEPart2: TMimePart;
  7.   email, smtp, port, haslo, nazwa, odbiorca: String;
  8. begin
  9.   nazwa:='Test'; //sender name
  10.   email:='test@example.domain.com'; //email and login
  11.   smtp:='example.domain.com';
  12.   port:='587';
  13.   haslo:='Pass123'; //password
  14.   odbiorca:='test2@example.domain.com'; //recipient
  15.   sltext:=TStringList.Create;
  16.   sltext.Text:='Hello world';
  17.   slhtml:=TStringList.Create;
  18.   //slhtml.LoadFromFile('d:\message.html');
  19.   slhtml.Text:='<html><body><font size=7><b>Hello</b></font> <i>world</i></body></html>';
  20.   MimeMsg:=TMimeMess.Create;
  21.   SMTPSend:=TSMTPSend.Create;
  22.   try
  23.     MimeMsg.Header.From:=nazwa+' <'+email+'>';
  24.     MimeMsg.Header.ToList.Add(odbiorca);
  25.     MimeMsg.Header.Subject:='Test message';
  26.     MimeMsg.Header.Priority:=MP_high;
  27.     MimeMsg.Header.CustomHeaders.Add('Disposition-Notification-To: '+MimeMsg.Header.From); //read confirmation
  28.     MimeMsg.Header.Date:=Now;
  29.     MimeMsg.Header.XMailer:='lazarus';
  30.     MimeMsg.Header.CharsetCode:=UTF_8;
  31.     MimeMsg.Header.ReplyTo:=nazwa+' <'+email+'>';
  32.     MIMEPart:=MimeMsg.AddPartMultipart('related', nil);
  33.     MIMEPart.CharsetCode:=UTF_8;
  34.     MimeMsg.AddPartHTML(slhtml, MIMEPart);
  35.     MIMEPart2:=MimeMsg.AddPartMultipart('alternative', MIMEPart);
  36.     MIMEPart2.CharsetCode:=UTF_8;
  37.     MimeMsg.AddPartTextEx(sltext, MIMEPart2, UTF_8, True, ME_8BIT); //add alternative text message
  38.     MimeMsg.EncodeMessage;
  39.     SMTPSend.TargetHost:=smtp;
  40.     SMTPSend.TargetPort:=port;
  41.     SMTPSend.UserName:=email;
  42.     SMTPSend.Password:=haslo;
  43.     if SMTPSend.Login then
  44.     begin
  45.       if SMTPSend.AuthDone then
  46.       begin
  47.         SMTPSend.MailFrom(email, Length(MimeMsg.Lines.Text));
  48.         SMTPSend.MailTo(odbiorca);
  49.         if SMTPSend.MailData(MimeMSg.Lines) then
  50.         begin
  51.           SMTPSend.Logout;
  52.           Caption:='ok';
  53.         end
  54.         else
  55.         Caption:='message error: '+SMTPSend.ResultString;
  56.       end
  57.       else
  58.       Caption:='auth error: '+SMTPSend.ResultString;
  59.     end
  60.     else
  61.     Caption:='login error: '+SMTPSend.ResultString;
  62.   finally
  63.     FreeAndNil(MimeMsg);
  64.     FreeAndNil(SMTPSend);
  65.   end;
  66. end;
Best regards
paweld

krzynio

  • Jr. Member
  • **
  • Posts: 80
    • Krzynio's home page
Re: Sending an email with HTML body
« Reply #7 on: September 16, 2020, 02:07:47 pm »
Hi!
It works but is the html part encoded second time by the procedure?
When I save to file may prepared html message from the string list and open it in the browser the message looks fine,
but when I send it by SendToRaw procedure national characters are displayed incorrectly.
Can you help, please.
Debian Testing x64 with XFCE 4.14 - Lazarus trunk, FPC 3.0.4
Windows 10 x64 - Lazarus 2.0.10, FPC 3.2.0

paweld

  • Full Member
  • ***
  • Posts: 241
Re: Sending an email with HTML body
« Reply #8 on: September 16, 2020, 03:26:55 pm »
Code: Pascal  [Select][+][-]
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. var
  3.   sltext, slhtml: TStringList;
  4.   MimeMsg: TMimeMess;
  5.   SMTPSend: TSMTPSend;
  6.   MIMEPart, MIMEPart2, HTMLPart: TMimePart;
  7.   email, smtp, port, haslo, nazwa, odbiorca: String;
  8. begin
  9.   nazwa := 'Test'; //sender name
  10.   email := 'test@example.domain.com'; //email and login
  11.   smtp := 'example.domain.com';
  12.   port := '587';
  13.   haslo := 'Pass123'; //password
  14.   odbiorca := 'test2@example.domain.com'; //recipient
  15.   sltext := TStringList.Create;
  16.   sltext.Text := 'Hello world';
  17.   slhtml := TStringList.Create;
  18.   //slhtml.LoadFromFile('d:\message.html');
  19.   slhtml.Text := '<html><body><font size=7><b>Hello</b></font> <i>world</i><br />Zażółć gęślą jaźń</body></html>';
  20.   MimeMsg := TMimeMess.Create;
  21.   SMTPSend := TSMTPSend.Create;
  22.   try
  23.     MimeMsg.Header.From := nazwa + ' <' + email + '>';
  24.     MimeMsg.Header.ToList.Add(odbiorca);
  25.     MimeMsg.Header.Subject := 'Test message';
  26.     MimeMsg.Header.Priority := MP_high;
  27.     MimeMsg.Header.CustomHeaders.Add('Disposition-Notification-To: ' + MimeMsg.Header.From); //read confirmation
  28.     MimeMsg.Header.Date := Now;
  29.     MimeMsg.Header.XMailer := 'lazarus';
  30.     MimeMsg.Header.CharsetCode := UTF_8;
  31.     MimeMsg.Header.ReplyTo := nazwa + ' <' + email + '>';
  32.     MIMEPart := MimeMsg.AddPartMultipart('related', nil);
  33.     MIMEPart.CharsetCode := UTF_8;
  34.     HTMLPart := MimeMsg.AddPart(MIMEPart);
  35.     HTMLPart.ConvertCharset := False;
  36.     with HTMLPart do
  37.     begin
  38.       slhtml.SaveToStream(DecodedLines);
  39.       Primary := 'text';
  40.       Secondary := 'html';
  41.       Description := 'HTML text';
  42.       Disposition := 'inline';
  43.       CharsetCode := UTF_8;
  44.       EncodingCode := ME_QUOTED_PRINTABLE;
  45.       EncodePart;
  46.       EncodePartHeader;
  47.     end;
  48.     MIMEPart2 := MimeMsg.AddPartMultipart('alternative', MIMEPart);
  49.     MIMEPart2.CharsetCode := UTF_8;
  50.     MimeMsg.AddPartTextEx(sltext, MIMEPart2, UTF_8, True, ME_8BIT); //add alternative text message
  51.     MimeMsg.EncodeMessage;
  52.     SMTPSend.TargetHost := smtp;
  53.     SMTPSend.TargetPort := port;
  54.     SMTPSend.UserName := email;
  55.     SMTPSend.Password := haslo;
  56.     if SMTPSend.Login then
  57.     begin
  58.       if SMTPSend.AuthDone then
  59.       begin
  60.         SMTPSend.MailFrom(email, Length(MimeMsg.Lines.Text));
  61.         SMTPSend.MailTo(odbiorca);
  62.         if SMTPSend.MailData(MimeMSg.Lines) then
  63.         begin
  64.           SMTPSend.Logout;
  65.           Caption := 'ok';
  66.         end
  67.         else
  68.           Caption := 'message error: ' + SMTPSend.ResultString;
  69.       end
  70.       else
  71.         Caption := 'auth error: ' + SMTPSend.ResultString;
  72.     end
  73.     else
  74.       Caption := 'login error: ' + SMTPSend.ResultString;
  75.   finally
  76.     FreeAndNil(MimeMsg);
  77.     FreeAndNil(SMTPSend);
  78.   end;
  79. end;
Best regards
paweld

 

TinyPortal © 2005-2018