E-mail Automation using Python (Part - 1)

No comments
In this post I'll be covering sending and scheduling email sending using Python script:


Checking and replying to emails is a huge time sink. We cannot simply write a program to handle all our email cause obviously each message requires its own response.

For example you  have a list of people that you want to send say a standard birthday invitation to (with of course different name on each mail) depending on various parameters like their age, location etc. Typing and sending to each one of them would take a lot of time and patience. Fortunately we can automate this task by writing a simple python script.

Much like HTTP is the protocol used by computers to send web pages across the internet, Simple Mail Transfer Protocol (SMTP) is the protocol used for sending email. SMTP dictates how email messages should be formatted, encrypted, and relayed between mail servers, and all the other details that your computer handles after you click send. All these technical details are simplified into a few functions by Python’s smtplib module.

# coding: utf-8

import time,datetime

print "\nEnter time you want to send mail:\n\t1. Now\n\t2. Morning (8:00 AM)\n\t3. Afternoon (1:00 PM)\n\t4. Evening (6:00 PM)\n\t5. Night (9:00 PM)\n\t6. Customise\n"
choice = raw_input(":")

present_time = datetime.datetime.now()
send_time = datetime.datetime.now()

def now():
 global present_time
 print "Time now is: ",
 print present_time.strftime('%I:%M:%S %p')
 print "Date: ",
 print present_time.strftime('%A %d %b %Y')
 send_time = present_time

def morning():
 global send_time, present_time
 print "\nTime now is: ",
 print present_time.strftime('%I:%M:%S %p')
 print "Date: ",
 print present_time.strftime('%A %d %b %Y')

 send_time = datetime.datetime(datetime.date.today().year, datetime.date.today().month, datetime.date.today().day, 8, 0,0)
 if present_time > send_time:
  send_time = datetime.datetime(datetime.date.today().year, datetime.date.today().month,  datetime.date.today().day + 1, 8, 0,0)
 print "Mail will be sent: ",
 print send_time.strftime('%I:%M:%S %p') + ' on',
 print send_time.strftime(' %A %d %b %Y')

def afternoon():
 global send_time, present_time
 print "\nTime now is: ",
 print present_time.strftime('%I:%M:%S %p')
 print "Date: ",
 print present_time.strftime('%A %d %b %Y')

 send_time = datetime.datetime(datetime.date.today().year, datetime.date.today().month, datetime.date.today().day, 13, 0,0)
 if present_time > send_time:
  send_time = datetime.datetime(datetime.date.today().year, datetime.date.today().month,  datetime.date.today().day + 1, 13, 0,0)
 print "Mail will be sent: ",
 print send_time.strftime('%I:%M:%S %p') + ' on',
 print send_time.strftime(' %A %d %b %Y')

def evening():
 global send_time, present_time
 print "\nTime now is: ",
 print present_time.strftime('%I:%M:%S %p')
 print "Date: ",
 print present_time.strftime('%A %d %b %Y')

 send_time = datetime.datetime(datetime.date.today().year, datetime.date.today().month, datetime.date.today().day, 18, 0,0)
 if present_time > send_time:
  send_time = datetime.datetime(datetime.date.today().year, datetime.date.today().month,  datetime.date.today().day + 1, 18, 0,0)
 print "Mail will be sent: ",
 print send_time.strftime('%I:%M:%S %p') + ' on',
 print send_time.strftime(' %A %d %b %Y')

def night():
 global send_time, present_time
 print "\nTime now is: ",
 print present_time.strftime('%I:%M:%S %p')
 print "Date: ",
 print present_time.strftime('%A %d %b %Y')

 send_time = datetime.datetime(datetime.date.today().year, datetime.date.today().month, datetime.date.today().day, 21, 0,0)
 if present_time > send_time:
  send_time = datetime.datetime(datetime.date.today().year, datetime.date.today().month,  datetime.date.today().day + 1, 21, 0,0)
 print "Time at which mail will be sent: ",
 print send_time.strftime('%I:%M:%S %p') + ' on',
 print send_time.strftime(' %A %d %b %Y')

def custom():
 global send_time, present_time
 print "\nTime now is: ",
 print present_time.strftime('%I:%M:%S %p')
 print "Date: ",
 print present_time.strftime('%A %d %b %Y')
 
 print "\nCustomise Time(24hr format): "
 hr = int(raw_input("Enter hour: "))
 mn = int(raw_input("Enter minutes: "))
 send_time = datetime.datetime(datetime.date.today().year, datetime.date.today().month, datetime.date.today().day, hr, mn,0)
 if present_time > send_time:
  send_time = datetime.datetime(datetime.date.today().year, datetime.date.today().month,  datetime.date.today().day + 1, hr, mn,0)
 print "\nMail will be sent at: ",
 print send_time.strftime('%I:%M:%S %p') + ' on',
 print send_time.strftime(' %A %d %b %Y')

options = {
 '1':now,
 '2':morning,
 '3':afternoon,
 '4':evening,
 '5':night,
 '6':custom,
  }
    
options[choice]()

print "\nEnter mail details: ...(loading)"

import smtplib, time, getpass
smtpobj = smtplib.SMTP('smtp.gmail.com', 587)

if type(smtpobj.ehlo()[0]) == int:
 print "\nConnection established to Gmail"
#else:
# break
  
if type(smtpobj.starttls()[0]) == int:
 print "Encryption enabled"
#else:
# break

time.sleep(1)
mailid = raw_input("\nEnter your mail id: ")
pswd = getpass.getpass("Enter your password: ")

if smtpobj.login(mailid, pswd)[0] == int:
 print id + ' authenticated successfully.'

receiver_addr = raw_input("\nEnter receiver's address: ")
sub_of_mail = raw_input("Enter subject: ")
body_of_mail = raw_input("Enter body: ")

print "\nMail will be sent on ",
print send_time.strftime('%I:%M:%S %p') + ' on',
print send_time.strftime(' %A %d %b %Y')

#........Time to sleep..........#
for i in range(int(round((send_time - present_time).total_seconds()))):
 time.sleep(1)

#........Sleep over.............#
smtpobj.sendmail(mailid, receiver_addr, 'Subject:' + sub_of_mail + '\n' + body_of_mail)
print "Sending"

for i in range(5):
 print '.',
 time.sleep(1)
time.sleep(1)
print "Sent!"
smtpobj.quit()

Email providers and their SMTP servers
Gmail                            smtp.gmail.com
Outlook.com/Hotmail.com       smtp-mail.outlook.com
Yahoo mail                       smtp.mail.yahoo.com
AT&T                             smpt.mail.att.net  (port 465)
Comcast                          smtp.comcast.net
Verizon                          smtp.verizon.net   (port 465)

In the 3rd and 105th line, all necessary libraries are imported. 5th line is the menu that will ask the user when he/she wants to send mail. For convenience "morning", "afternoon", "evening" and "night" options are given. From line 11 to 90 all the menus are defined. The datetime library is used along with necessary parameters to format and displayed time and date. Line 1 to 101 is the scheduling mail part which is followed by sending mail using SMTP.

On line 106 SMTP object is created and gmail SMTP server is passed with out port 587. Out port is 587 for all except for AT&T and Verizon which is 465 as mentioned. On line 120 .ehlo() is like sending a "hello" message to gmail and if reply is positive (i.e an interger) then we may proceed. On line 113 .starttls() is used to start encryption for safety issues.

On line 120 getpass is a very nice function. It is used to accept passwords in script in hidden mode i.e your password will not be visible when you are typing it in while running the script. Line 124 - 126 asks you the details about the mail: mail id of receiver, subject of mail and body of mail.

On line 133, we calculate time difference between the: time that user decided to send the mail and present time. This is done so that we can make the script sleep for that time and send it after that. On line 145 SMTP sever is quit by passing the .quit() function.

No comments :