Odesílání mailů přes SMPT za pomocí Synapse

vložil Radek Červinka 12. prosince 2010 23:30

Minule jsem ukazoval, jak se dá poslat mail přes nainstalovaný program za pomocí MAPI (a Pepák v komentářích i přímo přes volání API MAPI), dnes ukáži vytvoření mailu za pomocí Synapse a jeho odeslání přes SMTP.

Synapse je knihovna nevizuálních komponent pro síťovou komunikaci na bázi blokujících soketů podporující kromě Delphi i Kylix a FreePascal. Kromě šikovného zapouzdření soketů obsahuje kvalitní podporu pro různé protokoly a další věci (včetně SSL). Její hlavní autor (Lukáš Gebauer) odvedl skvělou práci a osobně je jeho knihovna pro mne jedním z nejlepších open source kódů (spolu s FastMM4, VirtualTreeView atd.) a pravděpodobně i uzavřených.

Ale zpět k našemu úkolu. Celý úkol se skládá v podstatě ze dvou částí:

  • vytvoření MIME zprávy obsahující data mailu
  • odeslání vytvořené zprávy přes SMTP

Naštěstí Synapse má podporu pro obě části.

Vytvoření MIME zprávy

MIME je internetový standard, který umožňuje přenášet v mailu (a nejen v mailu) znaky s diakritikou nebo soubory (a další).

Podpora pro MIME je v Synapsi implementována (převážně) v jednotkách mimepart a mimemess.

Úplně na začátku je třeba se rozhodnou co bude mail obsahovat (zda jen čistý text, html nebo i soubory). Podle toho je třeba vytvářet strukturu MIME. MIME se skládá z částí, ale které části bude obsahovat záleží jen na nás.

Pokud mail bude obsahovat jen text nebo html, stačí jen jedna část. Pokud přidáme i soubor, musí MIME nejprve obsahovat část mixed, na kterou je navázán text mailu (čistý neboli plain nebo html) a vlastní soubor.

Relativně nejkomplikovanější je situace, kdy chceme přidat soubor, ale k základnímu textu přidat i alternativní text. Toto je celkem častá situace, kdy vytváříme HTML mail s přílohou, ale pro klienta, který neumí HTML chceme zobrazit alternativní zprávu (ať už jen informaci o tom, že je třeba HTML zobrazení, nebo zjednodušené zobrazení HTML zprávy). V takové případě musíme ještě přidat část alternate.

Ukázka kódu s alternate.

uses
  smtpsend, mimepart, mimemess;

procedure TForm1.btn1Click(Sender: TObject);
var
  oMessage : TMimeMess;
  p, oMultiPartAlt: TMimePart;
begin
  oMessage := TMimeMess.Create;
  with oMessage do
  try
    Header.From := 'radek.cervinka@technodat.cz';
    Header.ToList.Clear;
    Header.ToList.Add('radekc@delphi.cz');
    Header.CcList.Clear;
    Header.Subject := 'Novy mail';
//%
    p := AddPartMultipart('mixed', nil);
    oMultiPartAlt := AddPartMultipart('alternative', p);

    AddPartText(mem1.Lines, oMultiPartAlt);
    AddPartBinaryFromFile('c:\test.pdf', p);
    AddPartHTML(mem2.Lines, oMultiPartAlt);
//%
    Header.XMailer := 'Muj program';

    Header.Date := Now;
    EncodeMessage;
    if SendToRaw(Header.From, Header.ToList.CommaText, 'smtp.server.net', Lines, 'user', 'heslo') then
      ShowMessage('Mail byl úspěšně odeslán!')
    else
      ShowMessage('Mail se nepodařilo odeslat.');
  finally
    Free;
  end;
end;

v případě zprávy bez alternate bude část mezi % následující:

    p := AddPartMultipart('mixed', nil);

    AddPartText(mem1.Lines, p);
    AddPartBinaryFromFile('c:\test.pdf', p);

Samozřejmě metod je tam spousta (včetně přidávání streamů atd). Navíc nic nebrání tomu si nějakou přidělat.

A pokud chceme poslat jen text nebo jen html tak jen pro úplnost:


   AddPartText(mem1.Lines, nil); // text
//nebo
   AddPartHTML(mem2.Lines, nil); // html

Vždy ten druhý parametr odkazuje na nadřazený MimePart, nil znamená kořen.

Odeslání MIME zprávy

Pokud nemáme zvláštní požadavky tak si vystačíme s procedurou SendToRaw jako v příkladu. Parametry jsou od koho, komu, SMTP server, Mime, uživatel a heslo pro připojení k SMTP.

Pokud chceme větší kontrolu nad odesíláním (jako chybové kódy nebo podporu SSL) je třeba implementovat vlastní proceduru - ale v podstatě stačí minimálně upravit uvedenou (odstranění komentářů atd). Snad jen dvě věci:

Podpora SSL a chybový stav

Pro podporu SSL je třeba přidat jednotky implementující SSL, nejčastěji jsou to knihovny OpenSSL a jednotky ssl_openssl, ssl_openssl_lib. Následně pak knihovně Synapse naznačit, že je třeba je použít.

Pro získání chybového stavu je třeba volat metodu EnhCodeString třídy TSMTPSend

Následující procedura otestuje připojení k SMTP serveru, kdy pokud SMTP server podporuje povýšení komunikace na šifrovanou je toto použito (SMTP.AutoTLS := true) a vrátí případnou chybu. Jedná se o upravenou SendToRaw, ale bez odesílání.

function mbTestSmtp(const sSMTPHost, sUser, sPwd:string; iPort:Integer; var sProblem:string):Boolean;
var
  SMTP: TSMTPSend;
begin
  Result := False;
  sProblem := '';
  SMTP := TSMTPSend.Create;
  try
// if you need support for upgrade session to TSL/SSL, uncomment next lines:
   SMTP.AutoTLS := True;
// if you need support for TSL/SSL tunnel, uncomment next lines:
//      SMTP.FullSSL := True;
    SMTP.TargetHost := sSMTPHost;
    SMTP.TargetPort := IntToStr(iPort);
    SMTP.Username := sUser;
    SMTP.Password := sPwd;
    if SMTP.Login then
    begin
      Result := True;
      SMTP.Logout;
    end
    else
    begin
      sProblem := SMTP.EnhCodeString;
    end;
  finally
    SMTP.Free;
  end;
end;

Ohledně podporu SSL: nejsem žádný odborník, ale v podstatě AutoTLS značí, že se Synapse pokusí převést nešifrovanou komunikaci na šifrovanou na stejném portu, kdežto FullSSL předpokládá šifrovanou komunikaci od začátku a používá dva porty.

Poznámky

Aplikace pro použití SSL musí mít k dispozici knihovny OpenSSL, ke stažení třeba zde. Konkrétně stačí ssleay32.dll a libeay32.dll. Pokud je budete mít v adresáři aplikace, vyhnete se spoustě problémů.

Jelikož je Synapse hodně oblíbená, často je i zneužívána. Proto některé antispam řešení pravděpodobně kontrolují výskyt řetězce synapse, takže zvažte, zda ho něčím nenahradíte.

Tagy: , ,

Praxe

Komentáře

13.12.2010 2:10:12 #

pingback

Pingback from topsy.com

Twitter Trackbacks for
        
        Delphi.cz | OdesĂ­lánĂ­ mailĹŻ pĹ™es SMPT za pomocĂ­ Synapse
        [delphi.cz]
        on Topsy.com

topsy.com

13.12.2010 8:49:24 #

pepak

Řešení používající SMTP má bohužel proti MAPI jednu zásadní nevýhodu: právě to SMTP, resp. nutnost znát jeho parametry. U MAPI to není třeba řešit, protože tam ty parametry zná mailovací aplikace a můj program ji jenom využije k poslání zprávy, ale u socketového řešení se tomu nevyhnu. Zkušenost mi říká, že nemám šanci tyhle údaje od uživatele získat.

Druhý problém je v tom, že různých nastavení SMTP je spousta (někde se neautentizuje vůbec, někde jménem a heslem, někde tím, že se napřed přihlásím přes POP3/IMAP atd.) a já bych je musel implementovat všechny (nebo si od uživatele vyžádat informaci o tom, jak je autentizace prováděna - a to je stejný problém jako v prvním odstavci).

Z těchto důvodů jsem poměrně skeptický k možnosti používat maily přes Synapsi v obecné aplikaci. Když si budu psát vlastního spamovacího robota, tak ano, není s tím žádný problém. Když budu psát aplikaci, kterou pak budeme ve firmě používat interně, taky to půjde. Ještě je to myslitelné, když budu psát aplikaci pro geeky. Ale do aplikace určené běžným uživatelům se mi to jako řešení moc nelíbí.

pepak

13.12.2010 10:25:29 #

radekc

Synapse většinu situací ohledně autentizace atd. řeší za mne.

Navíc jsi zapomněl jsi na situaci, kdy píši program pro více uživatelů ve firmě. Tam je to naopak vhodné. Všichni používají stejný SMTP server a konfigurace k němu je uložena na serveru.

>nebo si od uživatele vyžádat informaci o tom, jak je autentizace prováděna - a to je stejný problém jako v prvním odstavci

stačí si nechat poslat kopii obrazovky nastavení poštovního klienta co používají - tak to řeším já

radekc

13.12.2010 11:10:41 #

radekc

Naopak řešení s MAPI má tu nevýhodu, že musí být nakonfigurován mailový klient. Kdežto v případě pěkného řešení se SMTP jsou všechny informace o konfiguraci uloženy třeba v DB a klienta si uživatel může pustit i třeba z flesky (extremní případ)

radekc

13.12.2010 13:05:47 #

<z>

hezke ... ja jsem zastance Indy ;) se SMTP jsem nikdy moc nepracoval, ale urcite to maj hezky implementovany ... mrknu na to :)

<z>

13.12.2010 13:17:49 #

radekc

Mimochodem INDY jsou komponenty, a pro SSL podle všeho potřebují speciální verzi OpenSSL tak u mne je jednoznačně vítězem Synapse. Navíc je podle mne mnohem lépe naprogramovaná.

radekc

13.12.2010 21:28:50 #

<z>

komponenty to jsou, ale to na uplne stejne funkcnosti nic nemeni ;)

nevim, co presne na jejich OpenSSL je specialniho, ale dostupne je maj dobre na strankach

synapse jsou jiste vyborne naprogramovane, Indy se ale stale zlepsuji - a jelikoz maj bezkonkurencne uzivatelsky lepsi implementaci HTTP, tak synapse nepouzivam
(zde mluvim o odesilani pomoci multipart/form-data, kde pridani streamu/objektu lze pridat jednim radkem, samo se to vybuduje a soubor to cte jako TFileStream a nepotrebuju ho naloadovat cely do pameti
- teda je pravda, ze uz jsem se synapse dlouho nepracoval, ale nepredpokladam, ze by se tam neco zmenilo)

kez by si dokazali od sebe vzit to nejlepsi ;)

<z>

15.12.2010 12:19:56 #

<z>

tak jsem to vyzkoumal,
starsi Indy (9) zrejme potrebovaly upravene OpenSSL,
nove Indy 10 si vystaci s beznymi ;)

<z>

Komentování ukončeno

Naše nabídka

MVP
Ing. Radek Červinka - Embarcadero MVP
profil na linkedin, Twitter:@delphicz

Nabízím placené poradenství a konzultace v oblasti programování a vývoje SW.
Dále nabízíme i vývoj speciálního software na zakázku.

Neváhejte nás kontaktovat (i ohledně reklamy).

love Delphi

O Delphi.cz

Delphi je moderní RAD nástroj podporující tvorbu nativních aplikací pro platformu Win32, Win64, Mac OSX, Linux a na iPhone a Android.

Delphi.cz je nezávislý portál pro uživatele Delphi. Portál není koncipován pro úplné začátečníky, i když i ti se zde nebudou nudit, ale spíše na programátory, kteří již něco znají a chtějí své znalosti dále rozvíjet a sledovat novinky.

Poslední komentáře

Comment RSS

Dle měsíců