• Get application security done the right way! Detect, Protect, Monitor, Accelerate, and more…
  • Sending a bulk of emails manually is a tedious task. You can use third-party services to send the emails in bulk at a time.

    How about you create your own customized script to send emails?

    Isn’t it wonderful?

    Yeah, it is. We are going to write a script in Python to send emails.

    Python has a library called smtplib which is used to send emails. The library smtplib is based on the SMTP (Simple Mail Transport Protocol). SMTP is used to send emails to others.

    Setup Gmail

    Here, we are going to use Gmail as an email provider. Google doesn’t allow scripts to sign in. And we need to make a change in the security of our Gmail account that allows scripts to sign in to our Gmail account.

    Changing the security option in our Gmail account is not good as it allows others to access the account very easily. It’s recommended to create a new Gmail account. Go to the settings here and turn on the Allow less secure apps: ON setting.

    If you are not comfortable with turning on the above setting, you can use Google API to sign in to your Gmail account. You can find the script to use the Google APIs for authentication here.

    Steps to Send Mail

    Certain steps need to be done to send a mail using the smtplib library. Let’s see the steps first and then we’ll write the script.

    #1. Connecting to the SMTP server

    Each service provider will have a different SMTP server domain name and port. We have to use the SMTP server domain name and port of email provider that we are going to use in the script. The SMTP server domain name and port for Gmail are smtp.gmail.com and 465.

    We will be using SSL encryption for the SMTP server connection as it is more secure than the TSL encryption. If you want to use the TSL encryption, then use the port 587 instead of 465. The SMTP server domain name will be different based on the email service provider.

    The code to connect to the SMTP server

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

    #2. Login

    Once the connection is established to the SMTP server, we can log in using the email address and password with the login SMTP object’s method. The code looks as follows.

    server.login(sender_email, password)

    #3. Send Mail

    After login, there is no way we can wait to send the mail. Send the mail using sendmail the method. Make sure you send the mail in the following format.

    Subject: your_subject_for \newline mail_content

    Spaces are not necessary. They are just for clarification in the above format. Let’s see the sample code.

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

    #4. Quit

    Don’t forget to quit the SMTP c

    We have seen the steps to send mail using Python. But, we haven’t discussed the complete code. Let’s quickly go through the code.

    import smtplib, ssl
    
    class Mail:
    
        def __init__(self):
            self.port = 465
            self.smtp_server_domain_name = "smtp.gmail.com"
            self.sender_mail = "GMAIL_ADDRESS"
            self.password = "SECURE_PASSWORD"
    
        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("Enter emails: ").split()
        subject = input("Enter subject: ")
        content = input("Enter content: ")
    
        mail = Mail()
        mail.send(mails, subject, content)
    

    We have created a class called Mail. And it has a method called send to send the mails. Writing class or just not is up to you. The class makes it more readable. We have implemented all the steps discussed above one by one in the send method.

    Hurray! you have sent a mail using Python script.

    HTML Content

    What if you want to send the mail in HTML? Is it possible?

    Yeah, why not. We can send the mail using HTML the library called email.mime. It’s a built-in library.

    The MIME is a standard used to extend the format of emails to support application programs, video, images, etc..,

    There are two classes that we need from the email.mime module. They are MIMEText and MIMEMultipart. Let’s see a brief explanation about them.

    #1. MIMEText

    The MIMEText class is used to write our mail content in HTML. We will create an instance of the class MIMEText by passing HTML content and the type of content. See the sample code below.

    html_content = MIMEText(html_template, 'html')
    

    Some mail services don’t support HTML rendering. So, it’s better to create two instances of the class MIMEText for plain text and HTML.

    #2. MIMEMultipart

    The MIMEMultipart class is used to simplify the formatting and writing subject, from address, to address etc, We will give the content created with MIMEText class to MIMEMultipart using the attach method.

    We need to make sure that the instance of MIMEMultipart is created with the argument alternative to render plain text or HTML. Let’s send a mail with HTML content.

    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'] = 'Geekflare Celebrations'
                mail['From'] = self.sender_mail
                mail['To'] = email
    
                text_template = """
                Geekflare
    
                Hi {0},
                We are delighted announce that our website hits 10 Million views this month.
                """
                html_template = """
                <h1>Geekflare</h1>
    
                <p>Hi {0},</p>
                <p>We are delighted announce that our website hits <b>10 Million</b> views last month.</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("Enter emails: ").split()
    
        mail = Mail()
        mail.send(mails)
    

    You can also add blind carbon copy using that attribute Bcc in the MIMEMultipart instance.

    Adding Attachments

    Attachments can be images, pdfs, docs, sheets, etc, There is called MIMEBase in the email.mime class. It’s used to add attachments to the mail.

    Let’s add an attachment to the above mail.

    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 = "Geekflare-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("Enter emails: ").split()
    
        mail = Mail()
        mail.send(mails)
    

    Mail to Bulk Mails at Once

    We have used a loop to send the same mail to multiple members. That’s one case (when you don’t want the receivers to know about other receivers).

    Assume you have to send the same mail to 1000 members at once of the same group. In such cases, using a loop will not be appropriate. We can add multiple emails in the To field in general mail compose. How to do it in Python script?

    We need to combine the list of emails as a string separated with a comma and space. We can use the join method string to combine all emails as a string. See the code to combine emails as a string.

    ", ".join(emails)

    Replace the To field in the above script using the above string. That’s it, you have sent the mail to bulk mails at once.

    Conclusion

    There are some third-party libraries to send emails in Python. Some of them are Envelopes, Yagmail, Flanker, etc.., These libraries help us to write scripts with few lines of code. You can explore them as well.

    Now, you can automate your email stuff using Python scripts. The structure of sending emails will be different based on your use case. We have seen different scenarios of sending emails. You can easily customize the scripts discussed in the tutorial to your use case. I have taken the reference from this article.

    Happy Coding 🙂