Github

Daniel Limanowski

the red team is watching

Home Posts

Automating customized email campaigns with Python and G Suite

Emails floating into an inbox

Ever wanted to send customized emails for a marketing or phishing awareness campaign?

Sure, you could pay a monthly fee to some SaaS to handle it for you, but why bother when a few free lines of Python will do the trick?

This blog post will explore exactly that: how to send individual, customized emails from a CSV file of contacts through a G Suite account.

Outcome

Let’s look where we want to be before jumping in. This blog post will allow you to provide a Comma Separated Values (CSV) file with different values for a given recipient/addressee (such as name, title, company, and more) then send individual emails from a template to each of these receipients customized with their unique details through your G Suite basic (or above) email.

Instead of “Hi valued customer,” you’ll have “Hi Daniel Limanowski,”.

This customization can be as little or as much as you need - including the subject line.

Now to start implementing this:

Configuring Gsuite

Google has SMTP servers available in which you can configure your account to act as a relay. You can even remove the authentication requirement if you specify a whitelisted IP address or range you’ll be sending from.

Head to the G Suite admin console and login with your G Suite administrator account credentials.

Search for “SMTP” in the settings search bar and you should see “SMTP relay service” as an option. Click on that link to bring you direct to the relay settings.

Searching G Suite settings

Sometimes you’ll have to scroll down a bit to find the relay service setting(s). Look for the “Routing” section.

Once you’ve located the “SMTP relay service” setting, hover over it then click “Add Another”. Just to be clear, Simple Mail Transer Protocol (SMTP), is an extremely popular mail transfer protocol. In this context, we are about to configure a service that will relay the mail from the script we’ll soon write over SMTP from a predetermined location to our addressees.

Adding a new relay service

Add a description for the service, then perform the following for each setting:

  1. Allowed senders: Only addresses in my domains
  2. Authentication: Check Only accept mail from the specified IP addresses and add your public IP address.
    • Don’t know your public IP? You can do a Google search for “What’s my IP” to quickly find out. Be aware however, depending on your ISP or network setup, that this address may or may not change frequently.
    • Uncheck Require SMTP Authentication, but be aware that this is a security risk: anyone who shares this public IP address can then send mail on your behalf!
  3. Encryption: Check Require TLS encryption to encrypt all emails sent

Configuring relay settings

The code

The following Python script uses Python’s smtplib and csv libraries to 1) ask the user for a CSV input file and extract details for each email to customize and send and 2) sends the finalized email through G Suite’s SMTP relay.

Github Repo: https://github.com/b1tst0rm/pygsuite

#!/usr/bin/python3

import smtplib
import ssl
import traceback
from email.message import EmailMessage
import csv

csv_name = input("Enter path to CSV: ")

with open(csv_name) as csv_file:
    csv_reader = csv.reader(csv_file, delimiter=",")
    for row in csv_reader:
        title = row[0]
        last_name = row[1]
        org = row[2]
        email = row[3]

        body = (
			"""\
			%s %s,

			Thanks for signing up for our mailing list.

			We're happy your organization, %s, has joined us.

			Cheers,
			Daniel Limanowski
			""" % (title, last_name, org)
		)

        msg = EmailMessage()
        msg['Subject'] = ("%s %s - mailing list" % (title, last_name))
        msg['From'] = "daniel@b1tst0rm.net"
        msg['To'] = email
        msg.set_content(body)

        context = ssl.create_default_context()

        try:
            # Do NOT use STMP_SSL, it fails negotiating SSL versions. 
			# Instead use the starttls command to force encryption.
            server = smtplib.SMTP('smtp-relay.gmail.com', 587)
            server.set_debuglevel(1)
            server.starttls(context=context)
            server.send_message(msg)
            server.quit()
            print('Email sent!')
        except Exception:
            traceback.print_exc()

You’re free to modify the code as you see fit, but right now the code expects your CSV to be laid out as follows (minus the header row):

Title Last name Organization Email
CEO Bob Bob’s Meatwiches bob@burger.pickle
CTO Frond Counselors Direct mr.frond@counselors.dir
Asst. Manager Gene Belcher Jingles gene@catchy.jingles

Finally, let’s kick off the script (I doubt the example emails have legitimate TLDs but I use them only as mock examples, of course use real emails for your case):

dev@rtdev:~/pygsuite$ cat contacts.csv                                        
CEO,Bob,Bob's Meatwiches,bob@burger.pickle
CTO,Frond,Counselors Direct,mr.frond@counselors.dir
Asst. Manager,Gene,Belcher Jingles,gene@catchy.jingles 
dev@rtdev:~/pygsuite$ chmod +x send.py
dev@rtdev:~/pygsuite$ ./send.py 
Enter path to CSV: contacts.csv                                                   
send: 'ehlo [REDACTED]\r\n'
reply: b'250-smtp-relay.gmail.com at your service, [REDACTED]\r\n'
reply: b'250-SIZE 157286400\r\n'
reply: b'250-8BITMIME\r\n'               
reply: b'250-STARTTLS\r\n'               
reply: b'250-ENHANCEDSTATUSCODES\r\n'
reply: b'250-PIPELINING\r\n'                                                      
reply: b'250-CHUNKING\r\n'               
reply: b'250 SMTPUTF8\r\n'
...

You’ll see detailed output as all of your emails are sent.

If and when someone replies, you’ll then see the response in your inbox.

Conclusion

Hopefully this post gives you an idea of what’s possible with a few lines of Python. If your use case is basic, you might save $20 a month on just another SaaS with a pretty UI doing the exact same thing. There, I just justified your Netflix subscription fees. Cheers.

~ b1tst0rm (Daniel)