6 rad, jak správně odesílat e-maily z webové stránky

Martin Taraba   14. 6. 2021


Nastavení správného odesílání e‑mailových zpráv z webové stránky není nic jednoduchého. Rozebereme si nejčastější chyby a ukážu vám, jak zařídit, aby zprávy nepadaly příjemcům do spamu.

V minulosti bylo odesílání e‑mailů daleko jednodušší. Dalo se poslat téměř cokoliv a odkudkoliv. Kvůli boji proti spamu se ale celý proces značně zkomplikoval. Pokud má dnes e‑mailová zpráva úspěšně dorazit do příchozí pošty, musíme dát pozor na spoustu věcí. Šest nejdůležitějších si projdeme v článku.

1) Neodesílejte zprávy přímo z webového serveru

Zdánlivě jednoduchou volbou je v případě PHP hostingu použití funkce mail(). Bohužel, narazíme u ní na řadu komplikací. Jestli se chcete vyhnout padání e‑mailů do spamu, musíte do zpráv ručně přidat další hlavičky a nastavit správné kódování.

Některé problémy zvládne vyřešit nástavba mb_send_mail(). Magicky přidává další potřebné hlavičky a částečně si poradí i s kódováním. Na potíže s ověřením odesílatele je ale marná. Do SPF záznamu domény proto musíte přidat webový server a DKIM klíče, kterými webserver zprávy podepisuje (pokud to vůbec umí). Pro aplikaci na vlastním serveru může být tento způsob nejjednodušší cesta, ale na sdíleném hostingu je takové nastavení velmi nezodpovědné.

2) Používejte SMTP server pro vaší doménu

Výše popsané trable mají poměrně jednoduché řešení. Místo odesílání zpráv přímo z webového serveru využijte ve své aplikaci SMTP server, který běžně k doméně používáte. Nastavení bude stejné jako v e‑mailovém klientovi a odpadne tím celé martyrium ohledně správného ověření webového serveru pro odesílání.

Do svého PHP kódu odesílání jednoduše doplníte např. pomoci knihovny PHPMailer. Jak ji nastavit vám ukážu dále v článku.

3) Mějte přehled o tom, co posíláte

Nejčastěji se webové e‑maily posílají z kontaktních formulářů. Pro ty platí jednoduché pravidlo:

Když je formulář vystavený na internetu, dřív nebo později do něj začne nějaký robot úspěšně zadávat spam.

Je přitom úplně jedno, jak dobrou ochranu máte. Jestli formulář zvládne vyplnit člověk, pro robota je prolomení jen otázka času.

Pokud z takového formuláře posíláte zprávy jen na svou e‑mailovou adresu, tak se v případě prolomení ochrany nic moc neděje. Jestli však tazateli na právě vyplněný e‑mail posíláte potvrzení, robot získá ultimativní nástroj na spamování, a je třeba okamžitě jednat.

Zprávy z formulářů proto posílejte (např. ve skryté kopii) i na nějakou vlastní adresu, ať máte přehled o všem, co se z webu odešle. Určitě si u ní nastavte antispamovou výjimku, jinak se vůbec nemusíte dozvědět, že vaše stránky začaly posílat nevyžádanou poštu.

Dále doporučuji zprávy před odesláním na webu ukládat (například do jeho databáze). Zjednodušíte si tím řešení případů, kdy nějaký e‑mail příjemci nedorazí. Navíc budete mít na jednom místě přehled o tom, co a kam web rozesílá.

4) Do odesílatele uvádějte funkční adresu

Při sestavování e‑mailu hraje zásadní roli adresa odesílatele. Nezapomeňte ji nastavit, jinak vám do ní webový server může vyplnit například www-data@brain.igloonet.cz. A to je problém. Doméně brain.igloonet.czchybí MX záznam, poštovní server příjemce tedy jednoduše pozná, že taková adresa odesílatele nemůže existovat. Zřejmě jí označí jako spam.

Další špatnou praxí je používání e‑mailových adres, na které není možné odpovědět (viz různé varianty noreply@). Příjemce jakékoliv zprávy by měl mít vždy možnost jednoduše reagovat pomocí tlačítka „odpovědět”. noreply@ v podstatě říká, že vám na uživateli nezáleží. A nejen to – pokud dojde k nějaké chybě v rozesílce nebo někomu omylem pošlete cizí data, příjemce vám dá obvykle obratem vědět. Když nemá jak, v lepším případě se na vás vykašle a v horším to půjde řešit na sociální sítě.

Do odesílatele proto vkládejte adresu, na kterou lze bez problémů odpovědět. Nejlépe takovou, kterou máte veřejně vystavenou na webu. Mail tak bude působit mnohem důvěryhodněji.

5) Nepoužívejte k odesílání běžný účet

Mezi lidmi je bohužel stále rozšířený mýtus, že když chceme do odesílatele uvést třeba podpora@igloonet.cz, musíme použít stejný e‑mailový účet (tedy podpora@igloonet.cz). E‑mail však na takovém principu nefunguje.

Z bezpečnostních důvodů nikdy nepoužívejte pro odesílání z webu běžné e‑mailové schránky, které máte pro příchozí poštu. Proč? Do webové aplikace totiž musíte uložit přihlašovací údaje ke schránce včetně hesla v čitelné podobě. K nim má automaticky přístup každý, kdo se dostane k nastavení webu. Pokud vám tedy web nedejbože někdo napadne, získá přístup ke všem e-mailům a může za vás velmi snadno vystupovat.

K odesílání e‑mailů z webu si proto vytvořte samostatnou schránku, kterou nepoužívejte k ničemu jinému a nikde ji nezveřejňujte. Například si vytvořím ucet-pro-web@igloonet.cz, který používám jen pro přihlášení k SMTP serveru. Jako odesílatele ale uvádím jinou adresu, například podpora@igloonet.cz. V kódu webu tak budou jen přihlašovací údaje k prázdné schránce ucet-pro-web@igloonet.cza případný útočník se k žádným citlivým údajům nedostane.

6) Odesílání pravidelně kontrolujte

Na závěr doporučuju všechno pečlivě zkontrolovat. Nejjednodušší je si poslat z webu zprávu a sledovat, jestli v pořádku dorazí. Pro pořádnou kontrolu nicméně doporučuji výborný nástroj mail-tester.com. Vygeneruje vám e‑mailovou adresu, na kterou pošlete zkušební zprávu. Vzápětí získáte podrobný přehled výsledků a případných chyb.

Tuto kontrolu minimálně jednou za půl roku zopakujte. Vždycky je lepší odhalit problém dřív, než na něj upozorní uživatelé.

Nastavení odesílání e‑mailů přes PHPMailer

Na konkrétním případu vám ukážu nastavení knihovny PHPMailer pro odesílání z PHP aplikace.

Stažení a instalace PHPMailer

Autoři PHPMailer doporučují instalaci pomocí Composeru. Ten je na našem webhostingu dostupný, takže mi stačí vytvořit adresář pro aplikaci na naší testovací doméně igloonet.net:

❯ cd ~/igloonet.net
❯ mkdir -p apps/posilator
❯ cd apps/posilator

V adresáři spustím instalaci přes Composer:

❯ composer require phpmailer/phpmailer

Pokud vše proběhne v pořádku, zobrazí se:

Using version ^6.4 for phpmailer/phpmailer
./composer.json has been created
Running composer update phpmailer/phpmailer
Loading composer repositories with package information
Updating dependencies
Lock file operations: 1 install, 0 updates, 0 removals
- Locking phpmailer/phpmailer (v6.4.1)
Writing lock file
Installing dependencies from lock file (including require-dev)
Package operations: 1 install, 0 updates, 0 removals
- Downloading phpmailer/phpmailer (v6.4.1)
- Installing phpmailer/phpmailer (v6.4.1): Extracting archive
5 package suggestions were added by new dependencies, use `composer suggest` to see details.
Generating autoload files
1 package you are using is looking for funding.
Use the `composer fund` command to find out more!

Konfigurace PHPMaileru

Samotný PHPMailer mám díky Composeru už stažený a nainstalovaný. Teď stačí vytvořit zkušební PHP skript, kterým si odeslání otestuji. Jako jeho základ použiji příklad přímo z repozitáře PHPMailer na GitHub.

Pro přihlášení k našemu SMTP serveru jsem si vytvořil adresu ucet-pro-web@igloonet.net, kterou nebudu používat k ničemu jinému. Do odesílatele vyplním info@igloonet.net a na mail-tester.com si všechno otestuju odesláním zprávy na vygenerovanou adresu.  Do skryté kopie přidám info@igloonet.net, ať mám přehled o všem, co se posílá

<?php

//import tříd PHPMaileru
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\SMTP;

//načtení autoloadu Composeru
require '../vendor/autoload.php';

//vytvoření nové PHPMailer instance
$mail = new PHPMailer();

//nastavení serveru
$mail->isSMTP();                               //budeme používat SMTP
$mail->SMTPDebug = SMTP::DEBUG_SERVER;         //zapneme debug výstup
$mail->Host = 'smtp.igloonet.cz';              //adresa SMTP serveru
$mail->Port = 587;                             //číslo portu
$mail->SMTPAuth = true;                        //zapnutí autorizace
$mail->Username = 'ucet-pro-web@igloonet.net'; //uživatelské jméno pro přihlášení k SMTP
$mail->Password = 'LfEHMCv9k6jvosRZwX5fin';    //heslo k účtu

//nastavení příjemců
$mail->setFrom('info@igloonet.net', 'igloonet');          //adresa odesílatele
$mail->addAddress('test-gqvuuwj52@srv1.mail-tester.com'); //adresa příjemce
$mail->addBCC('info@igloonet.net');                       //skrytá kopie

// zpráva
$mail->Subject = 'PHPMailer SMTP test';   //předmět
$mail->Body = 'Toto je test PHPMaileru.'; //tělo zprávy

//odeslání zprávy nebo vrácení chyby
if (!$mail->send()) {
echo 'Mailer Error: ' . $mail->ErrorInfo;
} else {
echo 'Message sent!';
}

Pro skript si vytvořím adresář publica uložím ho do souboru phpmailer_smtp_test.php:

mkdir public
cd public
vim phpmailer_smtp_test.php

V případě našeho hostingu bude celá cesta k mému skriptu:
~/igloonet.net/apps/posilator/public/phpmailer_smtp_test.php

Zkušební odeslání

Skript mám připravený, teď mi ho stačí spustit. K serveru jsem připojený přes SSH a na našem webhostingu mám k dispozici PHP-CLI. Nemusím tedy soubor se skriptem složitě zpřístupňovat a spouštět přes web. Stačí mi k tomu příkaz:

php phpmailer_smtp_test.php

V nastavení PHPMaileru jsem zapnul debug výstup, skript mi díky tomu vypíše přehledně celou komunikaci se SMTP serverem. Hned tedy uvidím, když se něco nepovede. V ostrém provozu je samozřejmě potřeba tento výstup vypnout. Už se stačí jen podívat na výsledek testu na mail-tester.com:

10/10 výsledek testu na mail-tester.com

mail-tester.com

Zpráva v pořádku dorazila a dostala maximum možných bodů. Vše funguje zřejmě správně.

Toto je jen ukázka toho nejjednoduššího použití PHPMaileru. Pro napojení do reálného PHP webu je potřeba provést ještě další kroky. Dosti užitečné můžou být příklady na už zmíněném repozitáři PHPMaileru na GitHubu. Najdete je v adresáři examples.

Nastavení odesílání e-mailů ve WordPress

Čistá instalace WordPress neumožňuje jakkoliv nastavit odesílání e-mailů (květen 2021, verze 5.7.2). V základu WordPress spoléhá na odesílání přes funkci mail(), což má spoustu problémů, které jsme si už rozebrali. Paradoxně k tomu využívá knihovny PHPMailer, která má u sebe i třídu pro odesílání přes SMTP. V čisté instalaci WordPress tedy máme vše potřebné pro odesílání přes SMTP, jen to nemůžeme jednoduše nastavit.

Řešením jsou naštěstí pluginy. Po zadání „SMTP” do vyhledávání jich najdeme celou řadu. Ty nejstahovanější mají tendenci řešit odesílání dost kreativně a přidávají neuvěřitelné množství funkcí navíc.

Po krátkém průzkumu doporučuji plugin SMTP Mailer, který se docela úzce zaměřuje jen na nastavení do už vestavěné WordPress knihovny PHPMailer. Nepřidává balastní funkce, které mohou mít vliv na výkon, a hlavně na bezpečnost.

Nastavení pluginu SMTP Mailer pro WordPress

SMTP Mailer nainstalujete do WordPressu jako každý jiný plugin a v menu Nastavení > SMTP Mailer vyplňte údaje SMTP server. V mém případě jde o stejné údaje jako u předešlé zkoušky knihovny PHPMailer. akorát jako odchozí adresu použiji wp@igloonet.net. Z této adresy bude WordPress posílat relační zprávy (například odkaz se změnou hesla nebo třeba upozornění na komentář). V případě, že nějaká příjemci nedorazí, na adresu přijde upozornění o nedoručení. V administraci hostingu si ji proto přesměruji na svoji adresu.

igloonet nastavení pluginu SMTP Mailer pro WordPress

SMTP Mailer

Po uložení nastavení si odesílání otestujte v záložce Test Email. Opět je vhodné použít testovací adresu z mail-tester.com. Po odeslání se ukáže podrobný výpis komunikace s SMTP, stejně jako u nastavení PHPMaileru.

Odesílání přes API specializované služby

Popsané řešení je vhodné pro menší weby. U e-shopu může nedoručený e-mail znamenat ztrátu objednávky (tedy peněz), zvažte proto raději nasazení specializované služby pro odesílání těchto zpráv.

Například na e-shopech, které spravujeme pro naše klienty, využíváme pro rozesílání relačních e-mailů Mailkit. E-shop si přes API jednoduše říká, co a kam se má poslat a Mailkit řeší veškeré odeslání u sebe. Když se nějakou zprávu nepovede doručit, tak je vždy k dispozici podrobný report s vysvětlením, proč se to nepovedlo. Klientům navíc přes Mailkit spravujeme e-mail marketing, takže máme vše pod jednou střechou.