My Opera is closing 3rd of March

Raphael's Pflock

miscellaneous Opera, Debian, Media and German posts

Python script for sending out bulk password e-mails

, ,

I needed it today and did not find anything like this. The following script combines a template file and a CSV file (see below) and sends the output to an e-mail address specified in the CSV file. I used it to send temporary passwords to ~100 students.
Hope this example helps somebody.

#!/usr/bin/python

import smtplib
import csv

# CONFIG
CSVFILE = "accounts.csv"
TEMPLATE = "mail_template.txt"

SENDER = '"Sender Name" <sender@example.com>'
SMTP_SERVER = 'smtp.example.com'

USE_TLS = 0 # for encrypted connection to SMTP server set to 1
AUTH_REQUIRED = 0 # if you need to use SMTP AUTH set to 1
SMTP_USER = 'sender'  # for SMTP AUTH, set SMTP username here
SMTP_PASS = 'pass'  # for SMTP AUTH, set SMTP password here

# You have to set the following two variables to 0 
# in order to actually send the e-mails to the recipients!
DRY_RUN = 1 # do not actually send e-mails but print what would have happened
SAFE_MODE = 1 # if set, all mails wil be sent to RECIPIENTS instead of the address specified in the csv file.
RECIPIENTS = ['sender@example.com']

template = open(TEMPLATE, "r")
csvfile  = open(CSVFILE, "r")

mail_template = template.read()
csv_reader = csv.reader(csvfile)

######## Open SMTP session ########
smtpresult = 0  # define it so we do not get an error during DRY_RUN
if not DRY_RUN:
    print "Opening SMTP session"
    session = smtplib.SMTP(SMTP_SERVER)
    #session.set_debuglevel(1)
    session.ehlo()
    if USE_TLS and session.has_extn("STARTTLS"): # not tested!
        session.starttls()
        session.ehlo()
    if AUTH_REQUIRED:
        session.login(SMTP_USER, SMTP_PASS)

######## Send Mails ########
for row in csv_reader:
    # adapt these fields to your needs
    surname = row[0]
    givenname = row [1]
    email = row[2]
    login = row[6]
    passwd = row[7] 
    # you might want to remove this part:
    if passwd == "":
        print "Skipping " + login + " - account already existed"
    else:
        print "Sending mail to " + email
        mssg = mail_template.replace("$NAME$", givenname + " " + surname)
        mssg = mssg.replace("$USERNAME$",login)
        mssg = mssg.replace("$PASSWORD$",passwd)
        if SAFE_MODE:
            recipients = RECIPIENTS
            mssg = mssg + "\r\nThis message would have been sent to " + email
        else:
            recipients = [email]
        if DRY_RUN:
            print "[DRY RUN] Sending mail to " + recipients[0]
            print mssg
        else:
            smtpresult = session.sendmail(SENDER, recipients, mssg)

        if smtpresult:
            errstr = ""
            for recip in smtpresult.keys():
                errstr = """Could not deliver mail to: %s

        Server said: %s
        %s

        %s""" % (recip, smtpresult[recip][0], smtpresult[recip][1], errstr)
            raise smtplib.SMTPException, errstr



The template file looks like this (in German):

From: "Raphael" <example@example.com>
Reply-to: test@example.com
Subject: [MT] Accounts

Hallo $NAME$,
Du erhältst mit dieser E-Mail deine Account-Daten für die Windows-Arbeitsplätze.
Beim ersten Login wirst Du aufgefordert, das Passwort zu ändern. 

Benutzername: $USERNAME$
Passwort: $PASSWORD$

Gruß,
Raphael 


The CSV file looked like this:
Miller,Peter,miller@example.com,12,232445,Student,peter.miller,Zgsd.aSda

Opera Master Password Bug GaloreVisitor OSs

Comments

Unregistered user Wednesday, July 16, 2008 11:22:44 AM

Vasu writes: Excellent. Very helpful script. I was looking for one today and found your site. Thanks for posting it!!

Unregistered user Friday, October 31, 2008 8:07:40 PM

Enrique writes: Very good! - I have to notify 650 users about their new email passwords, your script is exactly what I was looking for. Just one cuestion: Where can I set encoding for the outgoing mails: I need to use "tildes" ñ, á, ü etc...

Raphael Wimmerraphman Friday, October 31, 2008 8:28:17 PM

Hi Enrique,

put the following lines in the template (just after the Subject: line):

MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 8bit

Unregistered user Tuesday, November 24, 2009 2:17:28 AM

Nicolas writes: Very usefull for me the comment about how to send ñ, "tildes" and others. thanks raphman

Unregistered user Tuesday, February 8, 2011 5:47:57 PM

vangel writes: hi Raphael Thanks for sharing this script. I want to use this to send HTML email. So if I set the mime type and let the template be there it will work? or what do you recommend. Its plain HTML with nice fonts and colors. no image etc but clickable links. thanks again. appreciate your reply. http://vangel.3ezy.com

Raphael Wimmerraphman Tuesday, February 8, 2011 9:57:16 PM

Hi vangel,
you should use a multipart mime message that also contains a plaintext version of your text for people who prefer this.
The easiest way to do this is to send an HTML e-mail with the content to your own e-mail address and look at its headers + source. This should give you the correctly formatted content for your template.

Unregistered user Wednesday, February 9, 2011 12:44:10 AM

vangel writes: Hi Raphael, Good idea on that. Thank you very much Vangel

Unregistered user Wednesday, February 9, 2011 6:33:47 AM

vangel writes: hey Raphael, your idea worked :D its great it all works fine and am able to send emails. Except one unique case where sometimes the script hangs when sending email to specific domains like yahoo. I think there is SMTP error or other problem. I am searching docs to see if I can put in a timeout of some sort somewhere. Thank you so much again Python rules. \m/

Write a comment

New comments have been disabled for this post.