Wednesday, June 18, 2014

Mass-mailing with SMTP (ssmtp) from Linux/CentOS via GMail or outlook365.com

I needed to send 500 emails to the customers followed by another few thousands customers notifying them about the changes in their account. Unfortunately, our other departments are not skilled enough to use MailChimp, iContact or any other mass-mailer, so... no choice.

I wanted to go over our SMTP server to reduce any risk of emails going to spam. I also needed full control of "From:" field, so while sending from account "aaa" I could force emails to appear like they were sent from account "bbb" in our company. After about two hours of playing with
mail -s "some subject" address@domain.com -- -f "bbb@ccc.com"
I came into conclusion I can not do it with "mail" utility. Below I describe further steps I took to start sending emails.

1. Install ssmtp


yum install ssmtp


2. Edit the configuration file


sudo vi /etc/ssmtp/ssmtp.conf

so it looks this way:

2.a for sending via GMail -


#
# /etc/ssmtp.conf -- a config file for sSMTP sendmail.
#
# See the ssmtp.conf(5) man page for a more verbose explanation of the
# available options.
#

# The person who gets all mail for userids < 500
# Make this empty to disable rewriting.
root=

# The place where the mail goes. The actual machine name is required
# no MX records are consulted. Commonly mailhosts are named mail.domain.com
# The example will fit if you are in domain.com and your mailhub is so named.

# Where will the mail seem to come from?
RewriteDomain=my-company.com
mailhub=smtp.gmail.com:465
AuthUser=my-username-at-gmail
AuthPass=my-password-at-gmail
TLS_CA_File=/etc/pki/tls/certs/ca-bundle.crt
FromLineOverride=YES
UseTLS=YES



2.b for sending via outlook365.com


#
# /etc/ssmtp.conf -- a config file for sSMTP sendmail.
#
# See the ssmtp.conf(5) man page for a more verbose explanation of the
# available options.
#

# The person who gets all mail for userids < 500
# Make this empty to disable rewriting.
root=

# The place where the mail goes. The actual machine name is required
# no MX records are consulted. Commonly mailhosts are named mail.domain.com
# The example will fit if you are in domain.com and your mailhub is so named.

# Where will the mail seem to come from?
RewriteDomain=biscience.com
mailhub=smtp.office365.com:587
AuthUser=my-user@my-company.com
AuthPass=my-pwd
TLS_CA_File=/etc/pki/tls/certs/ca-bundle.crt
FromLineOverride=YES
UseTLS=YES
UseSTARTTLS=YES

3.  Create a text file with your email, e.g. vi /tmp/email.txt


To: __EMAIL__
From: "Support "
Reply-To: "Support "
Subject: Link to reset your password

Hi __USER__,

Following our previous e-mail, your login credentials have been reset. Please click the below link and follow the instructions to reset your password.


Reset your password now: __LINK__

Best Regards,
__ACCOUNT_MANAGER__


4. Test you can send your email to some address:


ssmtp -v your-user@your-company.com < /tmp/email.txt



For GMail, you have to approve the IP you are sending from via GMail web interface. Do it after your first sending attempt (obviously it will fail since you did not approve your IP yet). GMail policy is to block all suspicious sending requests, so you have to explicitly approve your IP. 

For Outlook365 you have to create a SMTP-Relay connector like it is described here
http://technet.microsoft.com/en-us/library/dn554323.aspx
and allow your IP address sending to any domains.


5. Create a script to send all emails out

Once you are sure you are getting test emails via eitehr GMail or Outlook365, write a script which takes CSV with users data (the variable fields in the above email template), replaces them with the users data and then sends email by email.

Here is a sample script which replaces template' values and then sends an email out:

#!/bin/bash
TMP_FILE=/tmp/e.tmp

while IFS=, read email user link mgr;
do
        cat $2 | sed "s/__EMAIL__/$email/g" > $TMP_FILE
        sed -i "s/__USER__/$user/g" $TMP_FILE
        sed -i "s/__LINK__/$link/g" $TMP_FILE
        sed -i "s/__ACCOUNT_MANAGER__/$mgr/g" $TMP_FILE
#cat /tmp/e.tmp
        echo "Sending message..."
        ssmtp -v $email < $TMP_FILE
        echo "Message has been sent, now sleeping for 5 seconds..."
        sleep 5s
done < $1

6. Run the script

/tmp/send_emails.sh /tmp/users.csv /tmp/email.txt > /tmp/emails.log 2>&1; echo "Emails sending has been completed!"

It is supposed that users.csv is in the following format:

email, user name, link, account manager
email, user name, link, account manager
email, user name, link, account manager
...
Your emails are on their way out, good luck!