How to send emails using Python and SMTP server

One way to send emails is by using third-party APIs. Another way is to connect to the SMTP server directly. This is the second approach here.

Import the required libraries.

import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
import email.utils as utils
import time
import ssl
from cryptography.fernet import Fernet
from urllib.parse import quote, unquote
from datetime import datetime
import html2text
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
import email.utils as utils
import time
import ssl
from cryptography.fernet import Fernet
from urllib.parse import quote, unquote
from datetime import datetime
import html2text
import smtplib from email.mime.text import MIMEText from email.mime.multipart import MIMEMultipart import email.utils as utils import time import ssl from cryptography.fernet import Fernet from urllib.parse import quote, unquote from datetime import datetime import html2text

Enter fullscreen mode Exit fullscreen mode

Create the EmailSenderclass.

Create __init__ and connectmethods as below.

class EmailSender:
def __init__(self):
self.smtp_server = "IP or DNS of SMTP Server"
self.smtp_port = PORT HERE. Probabily 587
self.username = "USERNAME"
self.password = "PASSWORD"
self.sender_name = "ANURAG RANA"
self.sender_address = "admin@anuragrana.in"
self.domain = "http://anuragrana.in"
self.smtp_connection = None
def connect(self):
if not self.smtp_connection:
# this line below takes the most time
self.smtp_connection = smtplib.SMTP(self.smtp_server, self.smtp_port)
# Create a secure SSL context
context = ssl.create_default_context()
# self.smtp_connection.starttls(context=context) # might generate SSL error
self.smtp_connection.starttls()
self.smtp_connection.login(self.username, self.password)
class EmailSender:
    def __init__(self):
        self.smtp_server = "IP or DNS of SMTP Server"
        self.smtp_port = PORT HERE. Probabily 587
        self.username = "USERNAME"
        self.password = "PASSWORD"
        self.sender_name = "ANURAG RANA"
        self.sender_address = "admin@anuragrana.in"
        self.domain = "http://anuragrana.in"
        self.smtp_connection = None

   def connect(self):
        if not self.smtp_connection:
            # this line below takes the most time
            self.smtp_connection = smtplib.SMTP(self.smtp_server, self.smtp_port)
            # Create a secure SSL context
            context = ssl.create_default_context()
            # self.smtp_connection.starttls(context=context) # might generate SSL error
            self.smtp_connection.starttls()
            self.smtp_connection.login(self.username, self.password)
class EmailSender: def __init__(self): self.smtp_server = "IP or DNS of SMTP Server" self.smtp_port = PORT HERE. Probabily 587 self.username = "USERNAME" self.password = "PASSWORD" self.sender_name = "ANURAG RANA" self.sender_address = "admin@anuragrana.in" self.domain = "http://anuragrana.in" self.smtp_connection = None def connect(self): if not self.smtp_connection: # this line below takes the most time self.smtp_connection = smtplib.SMTP(self.smtp_server, self.smtp_port) # Create a secure SSL context context = ssl.create_default_context() # self.smtp_connection.starttls(context=context) # might generate SSL error self.smtp_connection.starttls() self.smtp_connection.login(self.username, self.password)

Enter fullscreen mode Exit fullscreen mode

Add send method to this class to send the email.

def send_email(self, to_address, subject, body_html):
msg = MIMEMultipart("alternative")
msg['message-id'] = utils.make_msgid(domain=self.domain)
print(msg['message-id'])
msg["Subject"] = subject
msg["From"] = f"{self.sender_name} <{self.sender_address}>"
msg["To"] = to_address
# Attach the body of the email - text plain
text_content = html2text.html2text(body_html)
msg.attach(MIMEText(text_content, "plain"))
# Attach the body of the email - html
msg.attach(MIMEText(body_html, "html"))
# Add the List-Unsubscribe header
msg.add_header('List-Unsubscribe', unsubscribe_url)
msg["Date"] = utils.formatdate(localtime=True)
try:
response = self.smtp_connection.sendmail(self.sender_address, to_address, msg.as_string())
print(response)
except Exception as e:
print(e)
def send_email(self, to_address, subject, body_html):
    msg = MIMEMultipart("alternative")
    msg['message-id'] = utils.make_msgid(domain=self.domain)
    print(msg['message-id'])
    msg["Subject"] = subject
    msg["From"] = f"{self.sender_name} <{self.sender_address}>"
    msg["To"] = to_address
    # Attach the body of the email - text plain
    text_content = html2text.html2text(body_html)
    msg.attach(MIMEText(text_content, "plain"))
    # Attach the body of the email - html
    msg.attach(MIMEText(body_html, "html"))
    # Add the List-Unsubscribe header
    msg.add_header('List-Unsubscribe', unsubscribe_url)
    msg["Date"] = utils.formatdate(localtime=True)
    try:
        response = self.smtp_connection.sendmail(self.sender_address, to_address, msg.as_string())
        print(response)
    except Exception as e:
        print(e)
def send_email(self, to_address, subject, body_html): msg = MIMEMultipart("alternative") msg['message-id'] = utils.make_msgid(domain=self.domain) print(msg['message-id']) msg["Subject"] = subject msg["From"] = f"{self.sender_name} <{self.sender_address}>" msg["To"] = to_address # Attach the body of the email - text plain text_content = html2text.html2text(body_html) msg.attach(MIMEText(text_content, "plain")) # Attach the body of the email - html msg.attach(MIMEText(body_html, "html")) # Add the List-Unsubscribe header msg.add_header('List-Unsubscribe', unsubscribe_url) msg["Date"] = utils.formatdate(localtime=True) try: response = self.smtp_connection.sendmail(self.sender_address, to_address, msg.as_string()) print(response) except Exception as e: print(e)

Enter fullscreen mode Exit fullscreen mode

Important: message-id, List-Unsubscribe, and Date are three headers that are required for better deliverability. Without these headers, your email score will be low. A low email score might lead your email to the spam folder.

MIMEMultipart(“alternative”): This is a subtype of the multipart content type. Using “alternative” indicates that the email message contains multiple representations of the same content, but in different formats. For example, you might have the same email message in both plain text and HTML. The recipient’s email client can then choose which one to display, usually the last part that the client understands. This is useful for ensuring that the recipient can read the email regardless of whether their email client supports plain text or HTML.

Finally, add the close-connection method to the above class.

# close the connection
def close_connection(self):
if self.smtp_connection:
self.smtp_connection.quit()
self.smtp_connection = None
# close the connection
def close_connection(self):
    if self.smtp_connection:
        self.smtp_connection.quit()
        self.smtp_connection = None
# close the connection def close_connection(self): if self.smtp_connection: self.smtp_connection.quit() self.smtp_connection = None

Enter fullscreen mode Exit fullscreen mode

Now in the main code, perform the below steps to send the emails.

Initialize the EmailSender class and call the connect method to create a connection with the SMTP server.

email_sender = EmailSender()
email_sender.connect()
email_sender = EmailSender()
email_sender.connect()
email_sender = EmailSender() email_sender.connect()

Enter fullscreen mode Exit fullscreen mode

Create an Email Template in an HTML file. Read the content of this file in a variable.

# Read the content of the HTML file
with open("templates/my-first-email-template.html", "r", encoding="utf-8") as file:
body = file.read()
# Read the content of the HTML file
with open("templates/my-first-email-template.html", "r", encoding="utf-8") as file:
    body = file.read()
# Read the content of the HTML file with open("templates/my-first-email-template.html", "r", encoding="utf-8") as file: body = file.read()

Enter fullscreen mode Exit fullscreen mode

Create the list of recipients. Let’s call it batch. Iterate over this batch to send emails to everyone individually.

batch = []
# current_batch text file contains email, one email in each line
with open("current_batch.txt", 'r') as file:
batch = file.readlines()
batch = []
# current_batch text file contains email, one email in each line
with open("current_batch.txt", 'r') as file:
    batch = file.readlines()
batch = [] # current_batch text file contains email, one email in each line with open("current_batch.txt", 'r') as file: batch = file.readlines()

Enter fullscreen mode Exit fullscreen mode

Now send the emails.

for recipient in batch:
# sleep for few seconds before each email to avoid flooding the recepient's inbox
time.sleep(5)
if not recipient or not recipient.strip():
continue
recipient = recipient.strip()
# check if recipient is in bouncelog
if recipient in bounced:
print(f'email in bouncelog. {recipient}')
continue
email_sender.send_email(recipient, subject, body)
print(f'Mail sent to {recipient} - {time.time()}')
for recipient in batch:
    # sleep for few seconds before each email to avoid flooding the recepient's inbox
    time.sleep(5)
    if not recipient or not recipient.strip():
        continue
    recipient = recipient.strip()
    # check if recipient is in bouncelog
    if recipient in bounced:
        print(f'email in bouncelog. {recipient}')
        continue

    email_sender.send_email(recipient, subject, body)
    print(f'Mail sent to {recipient} - {time.time()}')
for recipient in batch: # sleep for few seconds before each email to avoid flooding the recepient's inbox time.sleep(5) if not recipient or not recipient.strip(): continue recipient = recipient.strip() # check if recipient is in bouncelog if recipient in bounced: print(f'email in bouncelog. {recipient}') continue email_sender.send_email(recipient, subject, body) print(f'Mail sent to {recipient} - {time.time()}')

Enter fullscreen mode Exit fullscreen mode


We will discuss the bounce log and how to parse the POSTFIX logs for bounced emails in another article.

Connect with me if you want to set up a fully functional new email Postfix SMTP server to send and receive emails.

https://anuragrana.in

Follow me on Medium: https://medium.com/@03A_R/custom-parameter-logging-in-postfix-mta-logs-30c269c681b2

原文链接:How to send emails using Python and SMTP server

© 版权声明
THE END
喜欢就支持一下吧
点赞5 分享
I am the luckiest person in the world.
我是世界上最幸运的人
评论 抢沙发

请登录后发表评论

    暂无评论内容