I recently learned about Python 3 to see how to shoot a bunch of emails. There may be many simpler methods to do this, but the following ways I find effective at least for me.
And here’s the script: You have the names and email addresses of a range of contacts. And you want to send a message to each of those contacts, while adding a loved one “Dear [name]” name at the top of the message.
For simplicity, you can store contact details in a file rather than a database. You can also store samples of the messages you want to send in a file.
The Python smtplib module basically all you need is simple email, without any such subject line or additional information. But for real email, you need a subject line and a lot of information – maybe even pictures and attachments.
This is where Python’s email package appears. Remember that email messages cannot be sent just by package emails. You need a combination of both email and smtplib.
Here are four basic steps to sending email in Python: 1. Set up the SMTP server and log in to your account.
2. Create MIMEMultipart message object and load it with title that matches From, To and Subject fields
3. Add your message body.
4.Send the message using the SMTP server object.
Now let me guide you through the whole process
Suppose you have a contact file mycontacts.txt
as follows:
1 2 3 4 | <a class="__cf_email__" href="/cdn-cgi/l/email-protection">[email protected]</a> ~ $ cat mycontacts.txt john <a class="__cf_email__" href="/cdn-cgi/l/email-protection">[email protected]</a> katie <a class="__cf_email__" href="/cdn-cgi/l/email-protection">[email protected]</a> |
Each line represents a unique contact. We have the name followed by the email address. I’m storing everything in lowercase. I’ll put it according to the programming logic to convert any field to uppercase or lowercase if needed. All of that is pretty easy in Python.
Next, we have the sample message.txt.
file message.txt.
1 2 3 4 5 6 7 8 9 | <a class="__cf_email__" href="/cdn-cgi/l/email-protection">[email protected]</a> <span class="token operator">~</span> $ cat message <span class="token punctuation">.</span> txt Dear $ <span class="token punctuation">{</span> <span class="token constant">PERSON_NAME</span> <span class="token punctuation">}</span> <span class="token punctuation">,</span> This is a test message <span class="token punctuation">.</span> Have a great weekend <span class="token operator">!</span> Yours Truly |
Notice the word ${PERSON_NAME}?
It is a sample string in Python. Sample strings can easily be replaced with other strings; in this example, ${PERSON_NAME}
will be replaced with that person’s real name, as you’ll see shortly.
Now let’s start with the Python code, we need to read the contact from the file mycontacts.txt
. We can also generalize this bit into its own function.
1 2 3 4 5 6 7 8 9 10 11 | <span class="token comment"># Function to read the contacts from a given contact file and return a</span> <span class="token comment"># list of names and email addresses</span> <span class="token keyword">def</span> <span class="token function">get_contacts</span> <span class="token punctuation">(</span> filename <span class="token punctuation">)</span> <span class="token punctuation">:</span> names <span class="token operator">=</span> <span class="token punctuation">[</span> <span class="token punctuation">]</span> emails <span class="token operator">=</span> <span class="token punctuation">[</span> <span class="token punctuation">]</span> <span class="token keyword">with</span> <span class="token builtin">open</span> <span class="token punctuation">(</span> filename <span class="token punctuation">,</span> mode <span class="token operator">=</span> <span class="token string">'r'</span> <span class="token punctuation">,</span> encoding <span class="token operator">=</span> <span class="token string">'utf-8'</span> <span class="token punctuation">)</span> <span class="token keyword">as</span> contacts_file <span class="token punctuation">:</span> <span class="token keyword">for</span> a_contact <span class="token keyword">in</span> contacts_file <span class="token punctuation">:</span> names <span class="token punctuation">.</span> append <span class="token punctuation">(</span> a_contact <span class="token punctuation">.</span> split <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">[</span> <span class="token number">0</span> <span class="token punctuation">]</span> <span class="token punctuation">)</span> emails <span class="token punctuation">.</span> append <span class="token punctuation">(</span> a_contact <span class="token punctuation">.</span> split <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">[</span> <span class="token number">1</span> <span class="token punctuation">]</span> <span class="token punctuation">)</span> <span class="token keyword">return</span> names <span class="token punctuation">,</span> emails |
The get_contacts()
function get_contacts()
the file name as its argument. It will open the file, read each line (i.e. each contact), divide it into a name and email, and then join them into two separate lists. Finally, two lists are returned from the function.
We also need a function to read in the template file (like message.txt
) and return an object Template
created from its contents.
1 2 3 4 5 6 7 | <span class="token keyword">from</span> string <span class="token keyword">import</span> Template <span class="token keyword">def</span> <span class="token function">read_template</span> <span class="token punctuation">(</span> filename <span class="token punctuation">)</span> <span class="token punctuation">:</span> <span class="token keyword">with</span> <span class="token builtin">open</span> <span class="token punctuation">(</span> filename <span class="token punctuation">,</span> <span class="token string">'r'</span> <span class="token punctuation">,</span> encoding <span class="token operator">=</span> <span class="token string">'utf-8'</span> <span class="token punctuation">)</span> <span class="token keyword">as</span> template_file <span class="token punctuation">:</span> template_file_content <span class="token operator">=</span> template_file <span class="token punctuation">.</span> read <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token keyword">return</span> Template <span class="token punctuation">(</span> template_file_content <span class="token punctuation">)</span> |
Just like the previous function, this function takes the file name as its argument.
To send email, you need to use SMTP (Simple Mail Transfer Protocol) . As mentioned earlier, Python provides libraries to handle this task.
1 2 3 4 5 6 7 | <span class="token comment"># import the smtplib module. It should be included in Python by default</span> <span class="token keyword">import</span> smtplib <span class="token comment"># set up the SMTP server</span> s <span class="token operator">=</span> smtplib <span class="token punctuation">.</span> SMTP <span class="token punctuation">(</span> host <span class="token operator">=</span> <span class="token string">'your_host_address_here'</span> <span class="token punctuation">,</span> port <span class="token operator">=</span> your_port_here <span class="token punctuation">)</span> s <span class="token punctuation">.</span> starttls <span class="token punctuation">(</span> <span class="token punctuation">)</span> s <span class="token punctuation">.</span> login <span class="token punctuation">(</span> MY_ADDRESS <span class="token punctuation">,</span> PASSWORD <span class="token punctuation">)</span> |
In the code above, you are entering smtplib and then creating an SMTP version that encapsulates the SMTP connection. It takes the parameters of the server address and the port number, both of which depend entirely on the SMPT settings of your specific email service provider. For example, in the case of Outlook, line 4 above would be:
1 2 | s <span class="token operator">=</span> smtplib <span class="token punctuation">.</span> SMTP <span class="token punctuation">(</span> host <span class="token operator">=</span> <span class="token string">'smtp-mail.outlook.com'</span> <span class="token punctuation">,</span> port <span class="token operator">=</span> <span class="token number">587</span> <span class="token punctuation">)</span> |
You should use the server address and port number of your specific email service provider for the entire operation.
MY_ADDRESS
and PASSWORD
above are two variables that contain the email address and full password of the account you will use.
Now would be a good time to get contact information and message templates using the functions we defined above.
1 2 3 | names <span class="token punctuation">,</span> emails <span class="token operator">=</span> get_contacts <span class="token punctuation">(</span> <span class="token string">'mycontacts.txt'</span> <span class="token punctuation">)</span> <span class="token comment"># read contacts</span> message_template <span class="token operator">=</span> read_template <span class="token punctuation">(</span> <span class="token string">'message.txt'</span> <span class="token punctuation">)</span> |
Now, for each of those contacts, send a separate letter.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | <span class="token comment"># import necessary packages</span> <span class="token keyword">from</span> email <span class="token punctuation">.</span> mime <span class="token punctuation">.</span> multipart <span class="token keyword">import</span> MIMEMultipart <span class="token keyword">from</span> email <span class="token punctuation">.</span> mime <span class="token punctuation">.</span> text <span class="token keyword">import</span> MIMEText <span class="token comment"># For each contact, send the email:</span> <span class="token keyword">for</span> name <span class="token punctuation">,</span> email <span class="token keyword">in</span> <span class="token builtin">zip</span> <span class="token punctuation">(</span> names <span class="token punctuation">,</span> emails <span class="token punctuation">)</span> <span class="token punctuation">:</span> msg <span class="token operator">=</span> MIMEMultipart <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token comment"># create a message</span> <span class="token comment"># add in the actual person name to the message template</span> message <span class="token operator">=</span> message_template <span class="token punctuation">.</span> substitute <span class="token punctuation">(</span> PERSON_NAME <span class="token operator">=</span> name <span class="token punctuation">.</span> title <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token comment"># setup the parameters of the message</span> msg <span class="token punctuation">[</span> <span class="token string">'From'</span> <span class="token punctuation">]</span> <span class="token operator">=</span> MY_ADDRESS msg <span class="token punctuation">[</span> <span class="token string">'To'</span> <span class="token punctuation">]</span> <span class="token operator">=</span> email msg <span class="token punctuation">[</span> <span class="token string">'Subject'</span> <span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token string">"This is TEST"</span> <span class="token comment"># add in the message body</span> msg <span class="token punctuation">.</span> attach <span class="token punctuation">(</span> MIMEText <span class="token punctuation">(</span> message <span class="token punctuation">,</span> <span class="token string">'plain'</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token comment"># send the message via the server set up earlier.</span> s <span class="token punctuation">.</span> send_message <span class="token punctuation">(</span> msg <span class="token punctuation">)</span> <span class="token keyword">del</span> msg |
For each name
and emai
(from the directory file), you are creating a MIMEMultipar
object, setting From
, To
, Subjectcontent-type
headers as a keyword dictionary, and then attaching the message contents. MIMEMultipart
object in the form of simple text. You may want to read the documentation to learn more about other MIME
types that you can test.
Also note that on line 10 above, I will replace ${PERSON_NAME}
with the actual name extracted from the directory file with the template creation mechanism in Python.
In this particular example, I will delete MIMEMultipart
object and recreate it every time you loop through the loop.
Once that’s done, you can send the message using the send_message ()
function of the SMTP
object you created earlier. Here is the full code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | <span class="token keyword">import</span> smtplib <span class="token keyword">from</span> string <span class="token keyword">import</span> Template <span class="token keyword">from</span> email <span class="token punctuation">.</span> mime <span class="token punctuation">.</span> multipart <span class="token keyword">import</span> MIMEMultipart <span class="token keyword">from</span> email <span class="token punctuation">.</span> mime <span class="token punctuation">.</span> text <span class="token keyword">import</span> MIMEText MY_ADDRESS <span class="token operator">=</span> <span class="token string">' <a class="__cf_email__" href="/cdn-cgi/l/email-protection">[email protected]</a> '</span> PASSWORD <span class="token operator">=</span> <span class="token string">'mypassword'</span> <span class="token keyword">def</span> <span class="token function">get_contacts</span> <span class="token punctuation">(</span> filename <span class="token punctuation">)</span> <span class="token punctuation">:</span> <span class="token triple-quoted-string string">""" Return two lists names, emails containing names and email addresses read from a file specified by filename. """</span> names <span class="token operator">=</span> <span class="token punctuation">[</span> <span class="token punctuation">]</span> emails <span class="token operator">=</span> <span class="token punctuation">[</span> <span class="token punctuation">]</span> <span class="token keyword">with</span> <span class="token builtin">open</span> <span class="token punctuation">(</span> filename <span class="token punctuation">,</span> mode <span class="token operator">=</span> <span class="token string">'r'</span> <span class="token punctuation">,</span> encoding <span class="token operator">=</span> <span class="token string">'utf-8'</span> <span class="token punctuation">)</span> <span class="token keyword">as</span> contacts_file <span class="token punctuation">:</span> <span class="token keyword">for</span> a_contact <span class="token keyword">in</span> contacts_file <span class="token punctuation">:</span> names <span class="token punctuation">.</span> append <span class="token punctuation">(</span> a_contact <span class="token punctuation">.</span> split <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">[</span> <span class="token number">0</span> <span class="token punctuation">]</span> <span class="token punctuation">)</span> emails <span class="token punctuation">.</span> append <span class="token punctuation">(</span> a_contact <span class="token punctuation">.</span> split <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">[</span> <span class="token number">1</span> <span class="token punctuation">]</span> <span class="token punctuation">)</span> <span class="token keyword">return</span> names <span class="token punctuation">,</span> emails <span class="token keyword">def</span> <span class="token function">read_template</span> <span class="token punctuation">(</span> filename <span class="token punctuation">)</span> <span class="token punctuation">:</span> <span class="token triple-quoted-string string">""" Returns a Template object comprising the contents of the file specified by filename. """</span> <span class="token keyword">with</span> <span class="token builtin">open</span> <span class="token punctuation">(</span> filename <span class="token punctuation">,</span> <span class="token string">'r'</span> <span class="token punctuation">,</span> encoding <span class="token operator">=</span> <span class="token string">'utf-8'</span> <span class="token punctuation">)</span> <span class="token keyword">as</span> template_file <span class="token punctuation">:</span> template_file_content <span class="token operator">=</span> template_file <span class="token punctuation">.</span> read <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token keyword">return</span> Template <span class="token punctuation">(</span> template_file_content <span class="token punctuation">)</span> <span class="token keyword">def</span> <span class="token function">main</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">:</span> names <span class="token punctuation">,</span> emails <span class="token operator">=</span> get_contacts <span class="token punctuation">(</span> <span class="token string">'mycontacts.txt'</span> <span class="token punctuation">)</span> <span class="token comment"># read contacts</span> message_template <span class="token operator">=</span> read_template <span class="token punctuation">(</span> <span class="token string">'message.txt'</span> <span class="token punctuation">)</span> <span class="token comment"># set up the SMTP server</span> s <span class="token operator">=</span> smtplib <span class="token punctuation">.</span> SMTP <span class="token punctuation">(</span> host <span class="token operator">=</span> <span class="token string">'your_host_address_here'</span> <span class="token punctuation">,</span> port <span class="token operator">=</span> your_port_here <span class="token punctuation">)</span> s <span class="token punctuation">.</span> starttls <span class="token punctuation">(</span> <span class="token punctuation">)</span> s <span class="token punctuation">.</span> login <span class="token punctuation">(</span> MY_ADDRESS <span class="token punctuation">,</span> PASSWORD <span class="token punctuation">)</span> <span class="token comment"># For each contact, send the email:</span> <span class="token keyword">for</span> name <span class="token punctuation">,</span> email <span class="token keyword">in</span> <span class="token builtin">zip</span> <span class="token punctuation">(</span> names <span class="token punctuation">,</span> emails <span class="token punctuation">)</span> <span class="token punctuation">:</span> msg <span class="token operator">=</span> MIMEMultipart <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token comment"># create a message</span> <span class="token comment"># add in the actual person name to the message template</span> message <span class="token operator">=</span> message_template <span class="token punctuation">.</span> substitute <span class="token punctuation">(</span> PERSON_NAME <span class="token operator">=</span> name <span class="token punctuation">.</span> title <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token comment"># Prints out the message body for our sake</span> <span class="token keyword">print</span> <span class="token punctuation">(</span> message <span class="token punctuation">)</span> <span class="token comment"># setup the parameters of the message</span> msg <span class="token punctuation">[</span> <span class="token string">'From'</span> <span class="token punctuation">]</span> <span class="token operator">=</span> MY_ADDRESS msg <span class="token punctuation">[</span> <span class="token string">'To'</span> <span class="token punctuation">]</span> <span class="token operator">=</span> email msg <span class="token punctuation">[</span> <span class="token string">'Subject'</span> <span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token string">"This is TEST"</span> <span class="token comment"># add in the message body</span> msg <span class="token punctuation">.</span> attach <span class="token punctuation">(</span> MIMEText <span class="token punctuation">(</span> message <span class="token punctuation">,</span> <span class="token string">'plain'</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token comment"># send the message via the server set up earlier.</span> s <span class="token punctuation">.</span> send_message <span class="token punctuation">(</span> msg <span class="token punctuation">)</span> <span class="token keyword">del</span> msg <span class="token comment"># Terminate the SMTP session and close the connection</span> s <span class="token punctuation">.</span> quit <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token keyword">if</span> __name__ <span class="token operator">==</span> <span class="token string">'__main__'</span> <span class="token punctuation">:</span> main <span class="token punctuation">(</span> <span class="token punctuation">)</span> |
I believe that after this tutorial, sending emails by pyhon has become much easier than before.
Please use and configure it to best suit your usage
In addition to the official Python documents, I have consulted other sources here http://naelshiab.com/tutorial-send-email-python/