Hur skickar jag e-post via Gmail i Python?

Att manuellt distribuera stora mängder e-post är en tidskrävande syssla. Det finns tjänster från tredje part som underlättar massutskick av e-postmeddelanden.

Men tänk om du kunde skapa ett eget, skräddarsytt skript för att hantera e-postutskick?

Låter inte det intressant?

Jo, det är det! I den här guiden ska vi utveckla ett Python-skript för att skicka e-post.

Python erbjuder ett bibliotek vid namn smtplib, specifikt utformat för e-posthantering. Detta bibliotek bygger på SMTP (Simple Mail Transport Protocol), som är standarden för att skicka e-postmeddelanden över internet.

Konfigurera Gmail

Vi kommer att använda Gmail som vår e-posttjänst. Google tillåter inte direktinloggning via skript, vilket kräver att vi ändrar säkerhetsinställningarna för vårt Gmail-konto för att tillåta skriptåtkomst.

Att ändra säkerhetsinställningarna i Gmail kan innebära en säkerhetsrisk. Därför rekommenderas det att skapa ett nytt Gmail-konto. Du kan ändra inställningen Här och aktivera ”Tillåt mindre säkra appar”.

Om du inte känner dig bekväm med att ändra dessa säkerhetsinställningar, kan du istället använda Googles API för att logga in. Skript för autentisering via Google API finns här.

Steg för att skicka e-post

Flera steg krävs för att skicka e-post med smtplib. Låt oss först gå igenom stegen och sedan implementera dem i vårt skript.

#1. Anslutning till SMTP-server

Varje e-postleverantör har ett unikt SMTP-serverdomännamn och port. Dessa uppgifter måste användas i skriptet. För Gmail är SMTP-serverns domännamn smtp.gmail.com och port 465.

Vi kommer att använda SSL-kryptering för anslutningen till SMTP-servern eftersom det ger högre säkerhet än TSL-kryptering. Om du föredrar TSL-kryptering, använd port 587 istället för 465. Observera att SMTP-serverns domännamn varierar beroende på e-postleverantör.

Koden för att ansluta till SMTP-servern ser ut så här:

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

#2. Inloggning

Efter att anslutningen till SMTP-servern är etablerad, kan vi logga in med e-postadress och lösenord via login-metoden hos SMTP-objektet. Koden ser ut så här:

server.login(sender_email, password)

#3. E-postutskick

Efter lyckad inloggning är det dags att skicka e-postmeddelandet med metoden sendmail. Säkerställ att e-postmeddelandet är korrekt formaterat:

Ämne: ditt_ämne_för_nyrad_e-postinnehåll

Mellanslag i ovanstående format är endast för tydlighetens skull. Här är ett exempel på koden:

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

#4. Avslutning

Glöm inte att stänga SMTP-anslutningen när du är klar.

Vi har gått igenom de grundläggande stegen för att skicka e-post via Python. Nu ska vi titta närmare på den kompletta koden.

import smtplib, ssl

class Mail:

    def __init__(self):
        self.port = 465
        self.smtp_server_domain_name = "smtp.gmail.com"
        self.sender_mail = "DIN_EPOST_ADRESS"
        self.password = "DITT_LÖSENORD"

    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("Ange e-postadresser: ").split()
    subject = input("Ange ämne: ")
    content = input("Ange meddelande: ")

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

Vi har skapat en klass som heter Mail med en metod som heter send för att skicka e-postmeddelanden. Användandet av en klass gör koden mer överskådlig. I send-metoden implementerar vi alla steg som vi gått igenom tidigare.

Grattis! Nu har du skickat ett e-postmeddelande med ett Python-skript.

HTML-innehåll

Men vad händer om du vill skicka e-postmeddelanden i HTML-format? Är det möjligt?

Absolut! Med hjälp av email.mime, ett inbyggt bibliotek, kan vi skicka e-post i HTML.

MIME är en standard som gör det möjligt att utöka e-postformatet till att inkludera stöd för applikationer, video, bilder, med mera.

Vi behöver två klasser från email.mime-modulen: MIMEText och MIMEMultipart. Låt oss ta en snabb titt på vad de gör.

#1. MIMEText

Klassen MIMEText används för att skapa e-postinnehåll i HTML-format. Vi skapar en instans av klassen MIMEText genom att skicka HTML-innehållet och typen av innehåll. Koden nedan visar ett exempel:

html_content = MIMEText(html_template, 'html')

Eftersom vissa e-posttjänster inte stöder HTML-rendering är det bra att skapa två instanser av klassen MIMEText, en för vanlig text och en för HTML.

#2. MIMEMultipart

Klassen MIMEMultipart används för att förenkla formateringen och inkludera ämne, avsändare, mottagare med mera. Vi lägger till innehållet från MIMEText med hjälp av metoden attach.

När vi skapar instansen av MIMEMultipart, måste vi specificera att alternativ för att rendera antingen vanlig text eller HTML. Låt oss nu skicka ett e-postmeddelande med HTML-innehåll.

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'] = 'adminvista.com Firas'
            mail['From'] = self.sender_mail
            mail['To'] = email

            text_template = """
            adminvista.com

            Hej {0},
            Vi är glada att meddela att vår webbplats har nått 10 miljoner visningar denna månad.
            """
            html_template = """
            <h1>adminvista.com</h1>

            <p>Hej {0},</p>
            <p>Vi är glada att meddela att vår webbplats har nått <b>10 miljoner</b> visningar förra månaden.</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("Ange e-postadresser: ").split()

    mail = Mail()
    mail.send(mails)

Du kan även lägga till blindkopior med attributet Bcc i instansen av MIMEMultipart.

Lägga till bilagor

Bilagor kan vara bilder, PDF-filer, dokument eller andra typer av filer. För bilagor används MIMEBase-klassen i email.mime.

Låt oss lägga till en bilaga i e-postmeddelandet från exemplet ovan.

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):
        ## login...
        
        for email in emails:
            ## MIMEMultipart instance

            ## text and html templates

            ## MIMEText instances

            ## attaching messages to MIMEMultipart

            ## attaching an attachment
            file_path = "adminvista.com-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)

            ## sending mail

        service.quit()


if __name__ == '__main__':
    mails = input("Ange e-postadresser: ").split()

    mail = Mail()
    mail.send(mails)

Massutskick av e-post

Vi har använt en loop för att skicka samma e-post till flera mottagare. Det kan vara lämpligt när du inte vill att mottagarna ska se varandra.

Men om du vill skicka samma e-post till 1000 personer i samma grupp samtidigt, är det inte effektivt att använda en loop. I sådana fall kan du lägga till flera e-postadresser i ”Till”-fältet, precis som i vanliga e-postmeddelanden. Men hur gör vi det i Python-skriptet?

Vi kombinerar helt enkelt listan med e-postadresser till en sträng med kommatecken och mellanslag som avgränsare. Vi kan använda strängens join-metod för att uppnå detta. Så här kombinerar vi e-postadresserna till en sträng:

", ".join(emails)

Ersätt ”Till”-fältet i skriptet ovan med denna sträng. Nu har du skickat ett massutskick av e-post.

Slutsats

Det finns flera tredjepartsbibliotek för att hantera e-postutskick i Python, som Envelopes, Yagmail, Flanker, m.fl. Dessa bibliotek kan underlätta och förkorta kodningen. Vi rekommenderar att utforska dessa också.

Med hjälp av Python-skript kan du nu automatisera din e-posthantering. Beroende på ditt användningsområde kan strukturen för att skicka e-postmeddelanden behöva anpassas. Vi har tittat på ett flertal scenarier för e-postutskick. Du kan enkelt anpassa skripten i den här handledningen till dina egna behov. Delar av informationen kommer från den här artikeln.

Lycka till med kodningen! 🙂