15. 8. 2016, 14minutový příspěvek od Deva Mukherjeeho
Většina internetových služeb potřebuje odesílat e-maily svým uživatelům. Sestavení zprávy je oddělená úloha od odeslání e-mailu. Tento příspěvek ukazuje správnou konstrukci zpráv MIME (Multipurpose Internet Mail Extensions) v jazyce Python.
Zprávy MIME mají mnoho podtypů pro zapouzdření různých druhů obsahu. E-mailová knihovna MIME jazyka Python poskytuje obaly pro práci s nimi. Budeme zkoumat následující podtypy, abychom si ukázali, jak zprávy správně zabalit:
-
mixed
slouží k odesílání obsahu různých typů, inline nebo jako přílohy -
alternative
slouží k odesílání alternativních verzí téhož obsahu, např. skupiny prostých textových a HTML verzí těla e-mailu -
related
slouží k zahrnutí souvisejících zdrojů inline nebo jako příloh, např. obrázky použité v obsahu HTML
Emailová zpráva, kterou vytvoříme v tomto příspěvku, bude obsahovat:
- HTML a textovou verzi obsahu těla
- Přiložený soubor (což je v tomto případě vygenerovaný soubor
ICS
) - Případně mít v obsahu HTML obrázek
Začneme vytvořením vícedílné zprávy mixed
MIME, která bude obsahovat různé součásti (tělo e-mailu, obrázky zobrazené inline a přílohy ke stažení) naší zprávy:
from email.mime.multipart import MIMEMultipart# By default the type is set to mixedmessage = MIMEMultipart()message = "Hello World"message = "Anomaly Support <[email protected]>"message = "Anomaly Reception <[email protected]>"# If a Reply-To is explicitly provided then the email client will# use this address when the user hit the reply button message = "Anomaly Support <[email protected]>"
Obsah těla HTML a prostý text
Vytvoříme zprávu alternative
, která bude obsahovat dvě přílohy, nejprve prostou textovou verzi e-mailové zprávy a poté verzi HTML.
HTML a textový obsah by se obvykle vytvářely s pomocí šablonovacího stroje. Pro účely tohoto příspěvku předpokládám, že jste již obsah vygenerovali a je k dispozici jako proměnná Pythonu str
.
Zpráva alternative
se vytvoří instancováním objektu MIMEMultipart
, přičemž tentokrát požádáte konstruktor, aby použil podtyp alternative
.
textual_message = MIMEMultipart('alternative')
Pomocí pomocníka MIMEText
vytvoříte textovou a HTML přílohu.
from email.mime.text import MIMEText# I assume that you have a variable called txt_content# with the textual rendition of the message, this could# have been generated via a templating engineplaintext_part = MIMEText(txt_content, 'plain')textual_message.attach(plaintext_part)# likewise a variable called html_content with the HTMLhtml_part = MIMEText(html_content, 'html')textual_message.attach(html_part)
Připojením zprávy alternative
k nadřazené zprávě mixed
vytvoříte textové tělo e-mailové zprávy.
# Attach this to the mixed type messagemessage.attach(textual_message)
Přílohu ke stažení
Textuální nebo binární soubory lze k e-mailu připojit pomocí pomocníka MIMEApplication
. Jeho instanci tvoří obsah přílohy následovaný typem MIME přílohy, tj. v případě application/pdf
mu dodáte část pdf
.
Ve výchozím nastavení by byl obsah obsažen inline. Chcete-li z něj vytvořit přílohu, použijte metodu add_header
na instanci MIMEApplication
a deklarujte ji jako přílohu. Protože obsah přílohy je nyní součástí zakódované zprávy, musíte explicitně uvést metainformace, jako je název souboru.
from email.mime.application import MIMEApplicationpdf_file = MIMEApplication(pdf_file_data, "pdf")pdf_file.add_header('Content-Disposition', 'attachment', filename='report.pdf')
Pomocník MIMEApplication
automaticky Base64
zakóduje obsah, když je připojen ke zprávě:
message.attach(pdf_file)
Volitelný obrázek pro použití v těle HTML
Zvažte obrázek, který chcete zobrazit v těle e-mailu, ale nechcete ho nabídnout příjemci ke stažení. Potřebovali byste použít zprávu related
k zabalení těla e-mailu obsaženého ve zprávě alternate
, kterou jsme vytvořili dříve, a připojit zprávu related
k původní zprávě mixed
.
Budete také potřebovat použít podtřídu MIMEImage
, abyste zajistili správné kódování obrázku. Nejprve vytvořte zprávu MIMEMultipart
podtypu related
:
related_message = MIMEMultipart('related')
Vytvořte instanci MIMEImage
, která bude obsahovat obsah obrázku:
from email.MIMEImage import MIMEImage# Content of an image that relates to the HTML messageimage = MIMEImage(image_binary_contents)# Lets you reference the image locally in HTMLimage.add_header('Content-ID', '<image1>')
Přidáním hlavičky Content-ID
budete moci odkazovat na obrázek v obsahu HTML jako <img src="cid:image1">
. Připojte původně vytvořenou zprávu alternate
ke zprávě related
, za kterou následuje instance MIMEImage
:
# Attach the alternative textural message to the # related messagerelated_message.attach(textual_message)# Attach the image to the related messagerelated_message.attach(image)
Nakonec připojte zprávu related
ke zprávě mixed
:
# Attach the related message to our parent messagemessage.attach(related_message)
Kódování a odeslání e-mailu
Poté, co jste smíchali a spojili různé typy a podtypy MIME
, můžete zprávu zakódovat voláním funkce as_string
. Ta zase požádá každou dílčí zprávu a přílohu, aby se vykreslily jako jedna souvislá zpráva. Výsledkem je řetězec, který můžete poslat přes SMTP
jako svůj e-mail.
encoded_email = message.as_string()
smtplib
poskytuje klienta SMTP
, který může tuto zprávu doručit za vás. Je to docela jednoduché. V závislosti na nastavení vaší aplikace a serveru se můžete rozhodnout použít místní relé nebo relé přímo na dostupný server SMTP. To ponechám na konkrétních potřebách vašich aplikací.
from smtplib import SMTPsmtp = SMTP("localhost", 25)smtp.sendmail(message, message, encoded_email)smtp.quit()
Poznámka: Směrnice Reply-To
není součástí užitečného zatížení SMTP; to je zpracováno jako součást zprávy MIME
.
.