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.

.

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna.