Jak odesílat e-maily prostřednictvím Gmailu v Pythonu?

Rozesílání velkého množství e-mailů manuálně je zdlouhavá činnost. Pro hromadné rozesílání emailů můžete využít externí služby.

Co takhle si vytvořit vlastní, specifický skript pro posílání e-mailů?

Nezní to skvěle?

Samozřejmě že ano. Ukážeme si, jak napsat skript v Pythonu pro rozesílání e-mailů.

Python nabízí knihovnu s názvem `smtplib`, která se používá k odesílání e-mailů. Tato knihovna je založena na protokolu SMTP (Simple Mail Transfer Protocol). SMTP slouží k doručování e-mailů.

Konfigurace Gmailu

V našem případě budeme používat Gmail jako poskytovatele e-mailu. Google standardně neumožňuje přihlašování skriptů. Proto musíme upravit zabezpečení našeho Gmail účtu, aby se skripty mohly k němu přihlásit.

Změna bezpečnostních nastavení vašeho Gmail účtu není příliš bezpečná, protože to usnadňuje přístup k účtu i ostatním. Proto doporučujeme vytvořit si nový Gmail účet. Přejděte do nastavení zde a aktivujte možnost „Povolit méně zabezpečené aplikace“.

Pokud vám zapnutí výše uvedeného nastavení nevyhovuje, můžete se k Gmail účtu přihlásit pomocí Google API. Skript pro použití Google API pro autentizaci najdete zde.

Postup odeslání e-mailu

Pro odeslání e-mailu pomocí knihovny `smtplib` je nutné provést několik kroků. Nejprve se na tyto kroky podíváme a poté napíšeme skript.

#1. Připojení k SMTP serveru

Každý poskytovatel e-mailových služeb má odlišné jméno domény a port SMTP serveru. Proto musíme ve skriptu použít správné jméno domény a port podle poskytovatele. Pro Gmail je název domény SMTP serveru `smtp.gmail.com` a port `465`.

Pro připojení k SMTP serveru použijeme šifrování SSL, jelikož je bezpečnější než šifrování TLS. Pokud chcete použít TLS šifrování, použijte port 587 namísto 465. Jméno domény SMTP serveru se liší podle poskytovatele e-mailových služeb.

Kód pro připojení k SMTP serveru vypadá takto:

server = smtplib.SMTP_SSL(smtp_server_domain_name, port, context=ssl_context)

#2. Přihlášení

Po úspěšném připojení k SMTP serveru se můžeme přihlásit pomocí e-mailové adresy a hesla s metodou `login` SMTP objektu. Kód vypadá takto:

server.login(sender_email, password)

#3. Odeslání e-mailu

Po přihlášení můžeme odeslat e-mail pomocí metody `sendmail`. E-mail by měl být ve formátu:

Předmět: váš_předmět_pro_nový_řádek obsah_e-mailu

Mezery nejsou povinné. Jsou uvedeny pouze pro lepší přehlednost formátu. Zde je ukázkový kód:

server.sendmail(sender_mail, email, f"Subject: {subject}n{content}")

#4. Ukončení spojení

Nezapomeňte ukončit spojení s SMTP serverem:

Probrali jsme si kroky pro odeslání e-mailu pomocí Pythonu. Nicméně jsme se ještě nepodívali na celý kód. Nyní si jej rychle projdeme:

import smtplib, ssl

class Mail:

    def __init__(self):
        self.port = 465
        self.smtp_server_domain_name = "smtp.gmail.com"
        self.sender_mail = "VASE_EMAILOVA_ADRESA"
        self.password = "VASE_BEZPECNE_HESLO"

    def send(self, emails, subject, content):
        ssl_context = ssl.create_default_context()
        service = smtplib.SMTP_SSL(self.smtp_server_domain_name, self.port, context=ssl_context)
        service.login(self.sender_mail, self.password)
        
        for email in emails:
            result = service.sendmail(self.sender_mail, email, f"Subject: {subject}n{content}")

        service.quit()


if __name__ == '__main__':
    mails = input("Zadejte e-maily: ").split()
    subject = input("Zadejte předmět: ")
    content = input("Zadejte obsah: ")

    mail = Mail()
    mail.send(mails, subject, content)

Vytvořili jsme třídu s názvem `Mail`. Ta obsahuje metodu `send` pro odesílání e-mailů. Použití třídy je volitelné, ale činí kód čitelnějším. V metodě `send` jsme implementovali všechny výše popsané kroky.

Výborně! Právě jste odeslali e-mail pomocí skriptu v Pythonu.

HTML obsah

Co když chcete poslat e-mail ve formátu HTML? Je to možné?

Ano, samozřejmě. E-mail můžeme poslat v HTML pomocí knihovny `email.mime`. Jedná se o vestavěnou knihovnu.

MIME je standard sloužící k rozšíření formátu e-mailů o podporu aplikací, videí, obrázků, atd.

Z modulu `email.mime` potřebujeme dvě třídy: `MIMEText` a `MIMEMultipart`. Nyní si je stručně představíme.

#1. MIMEText

Třída `MIMEText` se používá k vytvoření obsahu e-mailu ve formátu HTML. Instanci třídy `MIMEText` vytvoříme předáním HTML obsahu a typu obsahu. Zde je ukázkový kód:

html_content = MIMEText(html_template, 'html')

Některé e-mailové služby nemusí podporovat vykreslování HTML. Proto je dobré vytvořit dvě instance třídy `MIMEText` – pro prostý text a HTML.

#2. MIMEMultipart

Třída `MIMEMultipart` se používá pro zjednodušení formátování a nastavení předmětu, adresy odesílatele, adresy příjemce, atd. Obsah vytvořený pomocí třídy `MIMEText` přidáme do objektu `MIMEMultipart` pomocí metody `attach`.

Musíme se ujistit, že instance `MIMEMultipart` je vytvořena s argumentem `alternative` pro vykreslení prostého textu nebo HTML. Nyní odešleme e-mail s HTML obsahem.

import smtplib, ssl
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart


class Mail:

    def __init__(self):
        ...

    def send(self, emails):
        ssl_context = ssl.create_default_context()
        service = smtplib.SMTP_SSL(self.smtp_server_domain_name, self.port, context=ssl_context)
        service.login(self.sender_mail, self.password)
        
        for email in emails:
            mail = MIMEMultipart('alternative')
            mail['Subject'] = 'etechblog.cz Oslavy'
            mail['From'] = self.sender_mail
            mail['To'] = email

            text_template = """
            etechblog.cz

            Ahoj {0},
            S radostí oznamujeme, že naše webové stránky tento měsíc dosáhly 10 milionů zobrazení.
            """
            html_template = """
            <h1>etechblog.cz</h1>

            <p>Ahoj {0},</p>
            <p>S radostí oznamujeme, že naše webové stránky dosáhly <b>10 milionů</b> zobrazení minulý měsíc.</p>
            """

            html_content = MIMEText(html_template.format(email.split("@")[0]), 'html')
            text_content = MIMEText(text_template.format(email.split("@")[0]), 'plain')

            mail.attach(text_content)
            mail.attach(html_content)

            service.sendmail(self.sender_mail, email, mail.as_string())

        service.quit()


if __name__ == '__main__':
    mails = input("Zadejte e-maily: ").split()

    mail = Mail()
    mail.send(mails)

Můžete také přidat skrytou kopii (BCC) pomocí příslušného atributu v instanci `MIMEMultipart`.

Přidávání příloh

Přílohami mohou být obrázky, PDF soubory, dokumenty, tabulky, atd. V modulu `email.mime` se pro přidávání příloh používá třída `MIMEBase`.

Nyní přidáme přílohu do výše uvedeného e-mailu.

import smtplib, ssl
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from email import encoders
from pathlib import Path


class Mail:

    def __init__(self):
        ...

    def send(self, emails):
        ## přihlášení...
        
        for email in emails:
            ## instance MIMEMultipart

            ## šablony textu a HTML

            ## instance MIMEText

            ## připojení zpráv k MIMEMultipart

            ## připojení přílohy
            file_path = "etechblog.cz-logo.png"
            mimeBase = MIMEBase("application", "octet-stream")
            with open(file_path, "rb") as file:
                mimeBase.set_payload(file.read())
            encoders.encode_base64(mimeBase)
            mimeBase.add_header("Content-Disposition", f"attachment; filename={Path(file_path).name}")
            mail.attach(mimeBase)

            ## odeslání e-mailu

        service.quit()


if __name__ == '__main__':
    mails = input("Zadejte e-maily: ").split()

    mail = Mail()
    mail.send(mails)

Hromadné odesílání e-mailů najednou

Použili jsme cyklus pro odeslání stejného e-mailu více uživatelům. To je vhodné v případě, kdy nechcete, aby příjemci věděli o ostatních příjemcích.

Předpokládejme, že chcete poslat stejný e-mail 1000 uživatelům stejné skupiny najednou. V takových případech není použití cyklu vhodné. Při běžném odesílání e-mailu můžeme do pole „Komu“ přidat více e-mailů. Jak to udělat ve skriptu v Pythonu?

Musíme zkombinovat seznam e-mailů do jednoho řetězce odděleného čárkou a mezerou. K vytvoření řetězce ze seznamu e-mailů můžeme použít metodu `join`. Zde je kód pro spojení e-mailů do řetězce:

", ".join(emails)

Nahraďte pole „Komu“ ve výše uvedeném skriptu tímto řetězcem. To je vše, odeslali jste e-mail na hromadné e-maily najednou.

Závěr

Existuje několik externích knihoven pro odesílání e-mailů v Pythonu. Některé z nich jsou Envelopes, Yagmail, Flanker, atd. Tyto knihovny vám pomohou psát skripty s menším množstvím kódu. Můžete je také prozkoumat.

Nyní můžete automatizovat odesílání e-mailů pomocí Python skriptů. Struktura pro odesílání e-mailů se bude lišit podle konkrétního případu použití. Představili jsme si různé scénáře pro odesílání e-mailů. Skripty, které jsme si ukázali v tomto návodu, můžete snadno přizpůsobit vašim potřebám. Čerpal jsem z tohoto článku.

Příjemné kódování 🙂