Wysyłanie wielu wiadomości e-mail pojedynczo może być nużące i czasochłonne. Na rynku dostępne są różne rozwiązania firm zewnętrznych, umożliwiające zbiorcze rozsyłanie korespondencji.
A gdyby tak stworzyć własny, dedykowany skrypt do automatyzacji tego procesu?
Brzmi interesująco, prawda?
Oczywiście! W dalszej części artykułu pokażemy, jak napisać skrypt w języku Python, który pozwoli na wysyłkę e-maili.
Python oferuje bibliotekę o nazwie `smtplib`, która jest wykorzystywana do obsługi wysyłania wiadomości. Działa ona w oparciu o protokół SMTP (Simple Mail Transport Protocol), który jest standardem wykorzystywanym do przesyłania e-maili.
Konfiguracja konta Gmail
W tym przykładzie użyjemy Gmaila jako dostawcy usług poczty elektronicznej. Google domyślnie blokuje możliwość logowania się do konta za pomocą skryptów. Aby umożliwić skryptom dostęp do naszego konta Gmail, musimy zmienić pewne ustawienia bezpieczeństwa.
Zmiana ustawień bezpieczeństwa konta Gmail może stwarzać potencjalne zagrożenie, ponieważ ułatwia dostęp do konta osobom trzecim. Dlatego zalecamy utworzenie nowego konta Gmail. Następnie, należy przejść do ustawień i aktywować opcję „Zezwalaj na mniej bezpieczne aplikacje”.
Jeżeli nie chcesz korzystać z powyższej opcji, możesz użyć API Google do uwierzytelniania konta Gmail. Szczegóły dotyczące korzystania z Google API znajdziesz tutaj.
Kroki niezbędne do wysłania wiadomości e-mail
Aby wysłać wiadomość za pomocą biblioteki `smtplib`, należy wykonać kilka określonych kroków. Najpierw omówimy je teoretycznie, a następnie napiszemy kod.
#1. Nawiązywanie połączenia z serwerem SMTP
Każdy dostawca usług poczty elektronicznej dysponuje unikalną nazwą domeny oraz portem serwera SMTP. W skrypcie musimy wykorzystać te dane odpowiadające naszemu dostawcy. Dla Gmaila są to: `smtp.gmail.com` (nazwa domeny) oraz `465` (port).
Dla połączenia z serwerem SMTP użyjemy szyfrowania SSL, ponieważ jest ono bezpieczniejsze od TSL. W przypadku użycia TSL należy wykorzystać port `587`, zamiast `465`. Nazwa domeny serwera SMTP będzie się różnić w zależności od usługodawcy.
Kod niezbędny do połączenia z serwerem SMTP wygląda następująco:
server = smtplib.SMTP_SSL(smtp_server_domain_name, port, context=ssl_context)
#2. Logowanie do serwera
Po pomyślnym połączeniu z serwerem SMTP możemy się zalogować, wykorzystując adres e-mail oraz hasło. Użyjemy metody `login` obiektu SMTP. Kod wygląda następująco:
server.login(sender_email, password)
#3. Wysyłka wiadomości
Po pomyślnym zalogowaniu możemy przejść do wysłania wiadomości, korzystając z metody `sendmail`. Pamiętaj, by sformatować wiadomość w następujący sposób:
Temat: Twój_temat_wiadomości\nTreść_wiadomości
Puste przestrzenie nie są wymagane; służą jedynie dla klarowności powyższego formatu. Przykładowy kod:
server.sendmail(sender_mail, email, f"Subject: {subject}\n{content}")
#4. Wylogowanie
Nie można zapomnieć o zamknięciu połączenia z serwerem SMTP.
Omówiliśmy kroki niezbędne do wysyłania wiadomości e-mail za pomocą Pythona. Niemniej jednak, nie zaprezentowaliśmy jeszcze pełnego kodu. Przejdźmy zatem do niego.
import smtplib, ssl class Mail: def __init__(self): self.port = 465 self.smtp_server_domain_name = "smtp.gmail.com" self.sender_mail = "ADRES_GMAIL" self.password = "TWOJE_HASŁO" 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("Wprowadź adresy e-mail: ").split() subject = input("Wprowadź temat: ") content = input("Wprowadź treść: ") mail = Mail() mail.send(mails, subject, content)
Stworzyliśmy klasę o nazwie `Mail`, która zawiera metodę `send` do wysyłania wiadomości e-mail. Implementacja klasy zależy od potrzeb – w tym przypadku zwiększa ona czytelność kodu. W metodzie `send` umieściliśmy wszystkie kroki omówione wcześniej.
Gratulacje! Właśnie udało Ci się wysłać e-mail przy pomocy skryptu Pythona.
Wiadomości w formacie HTML
Co, jeśli zależy Ci na wysyłaniu wiadomości w formacie HTML? Czy jest to możliwe?
Oczywiście, że tak! Do tego celu użyjemy biblioteki `email.mime`, która jest wbudowana w Pythonie.
MIME to standard rozszerzający format wiadomości e-mail, umożliwiający przesyłanie nie tylko tekstu, ale także plików, obrazów, wideo itp.
Z modułu `email.mime` wykorzystamy dwie klasy: `MIMEText` i `MIMEMultipart`. Poniżej znajduje się ich krótkie omówienie.
#1. MIMEText
Klasa `MIMEText` jest przeznaczona do przechowywania treści wiadomości w formacie HTML. Tworzymy instancję klasy `MIMEText`, przekazując treść HTML oraz typ zawartości. Przykładowy kod:
html_content = MIMEText(html_template, 'html')
Niektóre serwery pocztowe mogą mieć problemy z poprawnym renderowaniem HTML. Dlatego zalecane jest utworzenie dwóch instancji klasy `MIMEText` – jednej dla zwykłego tekstu, a drugiej dla HTML.
#2. MIMEMultipart
Klasa `MIMEMultipart` upraszcza formatowanie wiadomości, w tym wprowadzenie tematu, adresów nadawcy i odbiorcy. Treść wygenerowaną za pomocą `MIMEText` dołączymy do obiektu `MIMEMultipart` przy użyciu metody `attach`.
Musimy pamiętać, aby utworzyć instancję `MIMEMultipart` z argumentem „alternative”, umożliwiającym renderowanie tekstu lub HTML. Poniżej przykład wysyłania wiadomości z treścią HTML.
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'] = 'newsblog.pl Świętuje' mail['From'] = self.sender_mail mail['To'] = email text_template = """ newsblog.pl Witaj {0}, Z radością informujemy, że nasz serwis osiągnął 10 milionów wyświetleń w tym miesiącu. """ html_template = """ <h1>newsblog.pl</h1> <p>Witaj {0},</p> <p>Z radością informujemy, że nasz serwis osiągnął <b>10 milionów</b> wyświetleń w poprzednim miesiącu.</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("Wprowadź adresy e-mail: ").split() mail = Mail() mail.send(mails)
Możemy dodać ukrytą kopię wiadomości (Bcc), wykorzystując odpowiedni atrybut w instancji `MIMEMultipart`.
Dodawanie załączników
Załącznikami mogą być obrazy, dokumenty PDF, arkusze kalkulacyjne itp. Do dodawania załączników wykorzystamy klasę `MIMEBase`, która jest częścią modułu `email.mime`.
Dodajmy załącznik do naszej wiadomości:
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: ## instancja MIMEMultipart ## szablony tekstu i HTML ## instancje MIMEText ## dołączenie wiadomości do MIMEMultipart ## dołączanie załącznika file_path = "newsblog.pl-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) ## wysyłanie maila service.quit() if __name__ == '__main__': mails = input("Wprowadź adresy e-mail: ").split() mail = Mail() mail.send(mails)
Wysyłanie wiadomości do wielu odbiorców jednocześnie
Do tej pory korzystaliśmy z pętli, aby wysłać tę samą wiadomość do wielu odbiorców (w sytuacji, gdy nie chcemy, aby adresaci wiedzieli o sobie nawzajem).
Załóżmy, że chcemy wysłać tę samą wiadomość do 1000 osób należących do tej samej grupy jednocześnie. W takiej sytuacji pętla nie będzie optymalnym rozwiązaniem. Rozwiązaniem może być dodanie wielu adresów e-mail w polu „Do”. Jak to zrobić w skrypcie Pythona?
Musimy połączyć listę adresów e-mail w jeden ciąg znaków, oddzielając je przecinkami oraz spacjami. W tym celu możemy wykorzystać metodę `join`. Kod:
", ".join(emails)
Teraz wystarczy zastąpić pole „Do” w naszym skrypcie powyższym ciągiem znaków. I gotowe! Wysłaliśmy wiadomość do wielu odbiorców jednocześnie.
Podsumowanie
W Pythonie dostępnych jest szereg zewnętrznych bibliotek ułatwiających wysyłanie wiadomości e-mail, takich jak: Envelopes, Yagmail, Flanker. Ułatwiają one pisanie skryptów przy użyciu zaledwie kilku linijek kodu. Zachęcamy do ich przetestowania.
Dzięki zdobytym informacjom możesz samodzielnie zautomatyzować wysyłkę wiadomości e-mail przy pomocy Pythona. Struktura wysyłania maili będzie zależeć od Twoich indywidualnych potrzeb. W niniejszym poradniku omówiliśmy różne scenariusze. Możesz dowolnie modyfikować zaprezentowane skrypty, dostosowując je do własnych wymagań. Inspiracją dla tego artykułu był ten artykuł.
Miłego kodowania! 🙂
newsblog.pl
Maciej – redaktor, pasjonat technologii i samozwańczy pogromca błędów w systemie Windows. Zna Linuxa lepiej niż własną lodówkę, a kawa to jego główne źródło zasilania. Pisze, testuje, naprawia – i czasem nawet wyłącza i włącza ponownie. W wolnych chwilach udaje, że odpoczywa, ale i tak kończy z laptopem na kolanach.