0

I have a task to create a bulk mailer in python which sends bulk email content to a list of subscribers - how would I go about inputting code to allow the subscribers to manage the frequency and content of emails they receive?

import pandas as pd
import smtplib

# reading excel email list + retrieving the values
e = pd.read_excel(r"C:\Users\****\OneDrive\Desktop\emailList.xlsx")
email = e['Email'].values

# setting up server to send mail
server = smtplib.SMTP("smtp.gmail.com", 587)
server.starttls()
server.login("bulkmailer****@gmail.com", "*****")
msg = "Hi there! Check out these exclusive offers tailored just for you!"
subject = "Exclusive Offers Inside"
body = "Subject : {}\n\n{}".format(subject, msg)

# for loop for server to send emails from server to email list
for email in email:
    server.sendmail("bulkmailer****@gmail.com", email, body)
server.quit()
  • Keep in mind that you might not want to do this yourself: see https://stackoverflow.com/questions/3905734/how-to-send-100-000-emails-weekly – Danya02 Aug 13 '21 at 08:33
  • I don’t need to create a bulk mailer at that magnitude - I just need it to be able to send to like 2-3 emails as this is just for a uni assignment – okayzafar Aug 14 '21 at 14:13

1 Answers1

0

The code you have provided has the effect of sending a single message to every one of your subscribers. To have any "frequency" to speak of, you need to run this program occasionally -- for example, you can set up a cron job (or a Windows equivalent) that executes it once every X time -- say, once per minute.

Won't that mean your subscribers will get spammed with messages once per minute? It would, unless we add something else: a way to record when the message has been sent, or, equivalently, when the next message is due.

Specifically, along with each address, you need to store: the content of the message you'd like to send to them this time; the interval with which you intend to send the messages; and the last time that we sent a message to that address.

For this, normal applications use a database. You are using Pandas Dataframes, which probably have sufficient capabilities, but they're definitely harder to use for this. Since you have said in the comments that this is a homework question, and also because I have no experience with Pandas, I will instead provide some ORM-like pseudocode.

from dataclasses import dataclass
import database
import time
import mailer

@dataclass
class DatabaseRow:
    """ Single row in database of email addresses and associated data """
    email: str  # email address to send message to
    subject: str  # message subject
    body: str  # message body
    send_interval: int  # or float -- number of seconds between each message
    next_send_at: Optional[int]  # int or None (or float or None); Unix time at which to send next message; if None, send immediately

for row in database.get_all_rows():
    current_time = time.time()  # this returns Unix time: the number of seconds since 1 Jan 1970
    if row.next_send_at is None or current_time < row.next_send_at: 
        # it is not time to send it to them yet; don't do anything
        continue
    mailer.send(row.address, row.subject, row.body)
    row.next_send_at = current_time + row.send_interval  # the next time we'll send a message is (send_interval) away from now
    row.save()
Danya02
  • 1,006
  • 1
  • 9
  • 24