Lazarus i synapse - wysyłanie e-mail (temat i treść)

1

Cześć,

ostatnio patrzyłam na przykłady kodów w sieci do wysyłania emaili za pomoca synapse w lazarusie. Stworzyłam pod moje potrzeby poniższy kod. Problem w tym, że nie wiem jak wpisać w niego treść tytułu oraz treść wiadomości. Jak można dodać treść tytułu jako string a wiadomość jako TStringList? Oto poniższy kod:

function SendMail(
  User, Password,
  MailFrom, MailTo,
  SMTPHost, SMTPPort: string
  {MailData: string}): Boolean;
var
  SMTP: TSMTPSend;
  sl:TStringList;
begin
  Result:=False;
  SMTP:=TSMTPSend.Create;
  sl:=TStringList.Create;
  try
    sl.Add('test 1');
    //MailData := sl.Text;
    //sl.text:=Maildata;
    SMTP.UserName:=User;
    SMTP.Password:=Password;
    SMTP.TargetHost:=SMTPHost;
    SMTP.TargetPort:=SMTPPort;
    SMTP.AutoTLS:=true;
    if Trim(SMTPPort)<>'25' then
      SMTP.FullSSL:=true; // if sending to port 25, don't use encryption
    if SMTP.Login then
    begin
      result:=SMTP.MailFrom(MailFrom, Length(sl.text)) and
         SMTP.MailTo(MailTo) and
         SMTP.MailData(sl);
      SMTP.Logout;
    end;
  finally
    SMTP.Free;
    sl.Free;
  end;
end; 
1

W TSMTPSend chyba się nie da ,bo nie ma do tego właściwości. Przekazuje się to jako parametry funkcji wysyłania np. SendTo .

4

Przykład z wysyłką maila html oraz zwykłym tekstem.

    procedure TForm1.Button1Click(Sender: TObject);
    var
      sltext, slhtml: TStringList;
      MimeMsg: TMimeMess;
      SMTPSend: TSMTPSend;
      MIMEPart, MIMEPart2, HTMLPart: TMimePart;
      email, smtp, port, haslo, nazwa, odbiorca: String;
    begin
      nazwa := 'Test'; //sender name
      email := '[email protected]'; //email and login
      smtp := 'example.domain.com';
      port := '587';
      haslo := 'Pass123'; //password
      odbiorca := '[email protected]'; //recipient
      sltext := TStringList.Create;
      sltext.Text := 'Hello world';
      slhtml := TStringList.Create;
      //slhtml.LoadFromFile('d:\message.html');
      slhtml.Text := '<html><body><font size=7><b>Hello</b></font> <i>world</i><br />Zażółć gęślą jaźń</body></html>';
      MimeMsg := TMimeMess.Create;
      SMTPSend := TSMTPSend.Create;
      try
        MimeMsg.Header.From := nazwa + ' <' + email + '>';
        MimeMsg.Header.ToList.Add(odbiorca);
        MimeMsg.Header.Subject := 'Test message';
        MimeMsg.Header.Priority := MP_high;
        MimeMsg.Header.CustomHeaders.Add('Disposition-Notification-To: ' + MimeMsg.Header.From); //read confirmation
        MimeMsg.Header.Date := Now;
        MimeMsg.Header.XMailer := 'lazarus';
        MimeMsg.Header.CharsetCode := UTF_8;
        MimeMsg.Header.ReplyTo := nazwa + ' <' + email + '>';
        MIMEPart := MimeMsg.AddPartMultipart('related', nil);
        MIMEPart.CharsetCode := UTF_8;
        HTMLPart := MimeMsg.AddPart(MIMEPart);
        HTMLPart.ConvertCharset := False;
        with HTMLPart do
        begin
          slhtml.SaveToStream(DecodedLines);
          Primary := 'text';
          Secondary := 'html';
          Description := 'HTML text';
          Disposition := 'inline';
          CharsetCode := UTF_8;
          EncodingCode := ME_QUOTED_PRINTABLE;
          EncodePart;
          EncodePartHeader;
        end;
        MIMEPart2 := MimeMsg.AddPartMultipart('alternative', MIMEPart);
        MIMEPart2.CharsetCode := UTF_8;
        MimeMsg.AddPartTextEx(sltext, MIMEPart2, UTF_8, True, ME_8BIT); //add alternative text message
        MimeMsg.EncodeMessage;
        SMTPSend.TargetHost := smtp;
        SMTPSend.TargetPort := port;
        SMTPSend.UserName := email;
        SMTPSend.Password := haslo;
        if SMTPSend.Login then
        begin
          if SMTPSend.AuthDone then
          begin
            SMTPSend.MailFrom(email, Length(MimeMsg.Lines.Text));
            SMTPSend.MailTo(odbiorca);
            if SMTPSend.MailData(MimeMSg.Lines) then
            begin
              SMTPSend.Logout;
              Caption := 'ok';
            end
            else
              Caption := 'message error: ' + SMTPSend.ResultString;
          end
          else
            Caption := 'auth error: ' + SMTPSend.ResultString;
        end
        else
          Caption := 'login error: ' + SMTPSend.ResultString;
      finally
        FreeAndNil(MimeMsg);
        FreeAndNil(SMTPSend);
      end;
    end; 
0

Hej @Paweł Dmitruk: dostaję komunikat:

project1.lpr(52,39) Error: Identifier not found "UTF_8"

w linii kodu:

MimeMsg.Header.CharsetCode := UTF_8;
4

do sekcji uses musisz dodać moduł synachar

0

@Paweł Dmitruk: Dzięki, zadziałało :)

Dostaję natomiast cały czas komunikat "Login error" choć wiem, że parametry logowania są poprawne. Domyślam się, że problemem może być logowanie SSL. Czy w kodzie można to w jakiś sposób ustawić (parametr który trzeba podać)?

4

do sekcji uses dodajesz moduły ssl_openssl, ssl_openssl_lib
a w kodzie, jeszcze przed logowaniem dodajesz:

if szyfrowanie = 'Auto' then
begin
  SMTP.AutoTLS := True;
  SMTP.FullSSL := False;  
end
else if szyfrowanie = 'SSL' then
begin
  SMTP.AutoTLS := False;
  SMTP.FullSSL := True;  
end
else //brak szyfrowania
begin
  SMTP.AutoTLS := False;
  SMTP.FullSSL := False;  
end;

pod Windows w katalogu z programem musisz umieścić biblioteki OpenSSL: libeay32.dll oraz ssleay32.dll, które pobierzesz z https://indy.fulgan.com/SSL/
pod Linux musisz zainstalować pakiet libssl-dev

0

@Paweł Dmitruk: Dziękuję, zadzialało :)

Mam tylko pytanko - po wysłaniu e-maila na pocztę otrzymuję komunikat że nadawca chce potwierdzenia odczytania poczty. Nie zauważyłam w kodzie takiej właściwości. Jak można to wyłączyć?

Pozdrawiam!

4

Na moje oko to będzie ta linijka:

MimeMsg.Header.CustomHeaders.Add('Disposition-Notification-To: ' + MimeMsg.Header.From); //read confirmation
0

Super, dzięki @Clarc :)
Mam jeszcze jedno pytanko - ten sposób wysyłania wiadomości ma formę HTML. Czy można w ten sposób także wysyłać e-maile czystym tekstem?

Pozdrawiam!

1

Tak, w tamtym kodzie oprócz wiadomości w html wysyłka też alternatywnie wiadomość czystym tekstem.
Wysyłanie samej wysokości tekstowej wygląda mniej-więcej tak

procedure TForm1.Button1Click(Sender: TObject);
    var
      sltext: TStringList;
      MimeMsg: TMimeMess;
      SMTPSend: TSMTPSend;
      MIMEPart: TMimePart;
      email, smtp, port, haslo, nazwa, odbiorca: String;
    begin
      nazwa := 'Test'; //sender name
      email := '[email protected]'; //email and login
      smtp := 'example.domain.com';
      port := '587';
      haslo := 'Pass123'; //password
      odbiorca := '[email protected]'; //recipient
      sltext := TStringList.Create;
      sltext.Text := 'Hello world';
      MimeMsg := TMimeMess.Create;
      SMTPSend := TSMTPSend.Create;
      try
        MimeMsg.Header.From := nazwa + ' <' + email + '>';
        MimeMsg.Header.ToList.Add(odbiorca);
        MimeMsg.Header.Subject := 'Test message';
        MimeMsg.Header.Priority := MP_high;
        MimeMsg.Header.Date := Now;
        MimeMsg.Header.XMailer := 'lazarus';
        MimeMsg.Header.CharsetCode := UTF_8;
        MimeMsg.Header.ReplyTo := nazwa + ' <' + email + '>';
        MIMEPart := MimeMsg.AddPartMultipart('mixed', nil);
        MIMEPart.CharsetCode := UTF_8;
        MimeMsg.AddPartTextEx(sltext, MIMEPart, UTF_8, True, ME_8BIT); //add text message
        MimeMsg.EncodeMessage;
        SMTPSend.TargetHost := smtp;
        SMTPSend.TargetPort := port;
        SMTPSend.UserName := email;
        SMTPSend.Password := haslo;
        if SMTPSend.Login then
        begin
          if SMTPSend.AuthDone then
          begin
            SMTPSend.MailFrom(email, Length(MimeMsg.Lines.Text));
            SMTPSend.MailTo(odbiorca);
            if SMTPSend.MailData(MimeMSg.Lines) then
            begin
              SMTPSend.Logout;
              Caption := 'ok';
            end
            else
              Caption := 'message error: ' + SMTPSend.ResultString;
          end
          else
            Caption := 'auth error: ' + SMTPSend.ResultString;
        end
        else
          Caption := 'login error: ' + SMTPSend.ResultString;
      finally
        FreeAndNil(MimeMsg);
        FreeAndNil(SMTPSend);
      end;
    end; 
0

Dziękuję ślicznie :)

A żeby nie tworzyć już osobnego tematu - czy da się odebrać taką wiadomość to zmiennych typu string (jako temat) oraz TStringList jako treść? Mam tylko na myśli normalną treść, nawet jak przychodzi w formacie HTML abym nie miała jej w postaci tagów HTML tylko normalny tekst?

3

Tak, da się. Nie potrzebowałem tego na razie, a tylko testowałem, więc ma różne niedociągnięcia - główne to brak polskich znaków

uses
  imapsend, mimemess, ssl_openssl, ssl_openssl_lib, synacode, mimepart, synachar, regexpr; 

procedure TForm1.Button1Click(Sender: TObject);
var
  ImapClient: TIMAPSend;
  MimeMess: TMimeMess;
  MsgsList, Msg: TStringList;
  i: Integer;
begin
  MimeMess := TMimeMess.Create;
  MsgsList := TStringList.Create;
  Msg := TStringList.Create;
  ImapClient := TIMAPSend.Create;
  ImapClient.TargetHost := 'mail8.mydevil.net';
  ImapClient.TargetPort := '993';
  ImapClient.UserName := maillogin;
  ImapClient.Password := mailpasswd;
  ImapClient.AutoTLS := False;
  ImapClient.FullSSL := True;
  ImapClient.Login;
  ImapClient.SelectFolder('INBOX');  //foder, z którego ma czytać maile, tutaj skrzynka odbiorcza
  if ImapClient.SearchMess('ALL', MsgsList) then
    //ALL - wszystkie, UNSEEN - tylko nieprzeczytane (nieprzeczytane automatycznie po pobraniu ustawiane są jako preczytane)
  begin
    for i := 0 to MsgsList.Count - 1 do
    begin
      Msg.Clear;
      ImapClient.FetchMess(StrToInt(MsgsList[i]), Msg);
      MimeMess.Lines.Text := Msg.Text;
      MimeMess.DecodeMessage;
      Memo1.Lines.Add(MimeMess.Header.From); //nadawca
      Memo1.Lines.Add(MimeMess.Header.Subject); //temat
      memo1.Lines.Add('------------');
      DecodePart(MimeMess.MessagePart); //wiadomość
      memo1.Lines.Add('============');
      Msg.SaveToFile('D:\' + MsgsList[i] + '.eml'); //zapisz wiadomość do pliku eml
    end;
  end;
  MsgsList.Free;
  Msg.Free;
end;       

procedure TForm1.DecodePart(Part: TMimePart);
var
  i: Integer;
  s, pp, ps: String;
begin
  Part.DecomposeParts; //decode subparts
  Part.DecodePart;
  pp := UpperCase(Part.Primary);
  ps := UpperCase(Part.Secondary);
  if pp <> 'MULTIPART' then //If Multipart, go next level
  begin
    Part.DecodedLines.Seek(0, soFromBeginning);
    if pp = 'TEXT' then
    begin
      if (ps = 'PLAIN') then
      begin
        SetLength(s, Part.DecodedLines.Size);
        Part.DecodedLines.Read(s[1], Length(s));
        Memo1.Lines.Add('Wiadomość tekstowa: ' + s);
      end;
      if (ps = 'HTML') then
      begin
        SetLength(s, Part.DecodedLines.Size);
        Part.DecodedLines.Read(s[1], Length(s));
        s := ReplaceRegExpr('<(script|style).*?</\1>', s, '', false); //usuń znaczniki script i style
        s := ReplaceRegExpr('<.*?>', s, '', False); //usuń resztę tagów
        Memo1.Lines.Add('Wiadomość HTML: ' + s);
      end;
    end
    else
    begin
      if Part.FileName <> '' then
      begin
        Part.DecodedLines.SaveToFile('D:\' + Part.Filename);  //zapisz załącznik
      end;
    end;
  end;
  for i := 0 to Part.GetSubPartCount - 1 do
  begin
    DecodePart(Part.GetSubPart(i));
  end;
end;       
0

Wstępnie widzę, że robisz to IMAP-em. Czy jest możliwość odczytu za pomocą POP3?

1 użytkowników online, w tym zalogowanych: 0, gości: 1