Search code examples
pythonemailcronsmtpsmtplib

How do I schedule an email to send at a certain time using cron and smtp, in python?


So far I have only been able to send emails. Here's my code:

import smtplib

email_user = 'myemail@gmail.com'
server = smtplib.SMTP ('smtp.gmail.com', 587)
server.starttls()
server.login(email_user, 'email pass')

#SET TIME HERE?
from crontab import CronTab

#EMAIL
message = 'sending this from python!'
server.sendmail(email_user, email_user, message)
server.quit()

I'm struggling to set a time to send the email. If someone can also help me figure out how to add attachments, that would be great!


Solution

  • Assuming you already have your send_email() function working I would do:

    import datetime as dt
    import time
    import smtplib
    
    def send_email():
        email_user = 'myemail@gmail.com'
        server = smtplib.SMTP ('smtp.gmail.com', 587)
        server.starttls()
        server.login(email_user, 'email pass')
    
        #EMAIL
        message = 'sending this from python!'
        server.sendmail(email_user, email_user, message)
        server.quit()
    
    send_time = dt.datetime(2018,8,26,3,0,0) # set your sending time in UTC
    time.sleep(send_time.timestamp() - time.time())
    send_email()
    print('email sent')
    

    If you want to send the email regularly, you can do:

    import datetime as dt
    import time
    import smtplib
    
    def send_email():
        email_user = 'myemail@gmail.com'
        server = smtplib.SMTP ('smtp.gmail.com', 587)
        server.starttls()
        server.login(email_user, 'email pass')
    
        #EMAIL
        message = 'sending this from python!'
        server.sendmail(email_user, email_user, message)
        server.quit()
    
    def send_email_at(send_time):
        time.sleep(send_time.timestamp() - time.time())
        send_email()
        print('email sent')
    
    first_email_time = dt.datetime(2018,8,26,3,0,0) # set your sending time in UTC
    interval = dt.timedelta(minutes=2*60) # set the interval for sending the email
    
    send_time = first_email_time
    while True:
        send_email_at(send_time)
        send_time = send_time + interval
    

    You can also spawn a thread and leave this thread handle the sending of the email.