Updated on: February 14, 2024

Sending Email Notifications in Python

Sending Email Notifications in Python

Previously in the DIY PS5 Availability Tracker article, we covered the basic foundation of the scraper portion. However, availability trackers are only useful if you’re alerted ASAP. So, let’s go over sending email notifications in Python. This way, you’ll immediately get the alert on your phone and any other devices that you check your email with. 

This article is going to cover how to send emails to either one or multiple recipients. We’ll also implement a check to make sure it doesn’t bomb you with a ton of emails simultaneously.

What You’ll Need

Building off of the previous DIY PS5 Availability Tracker article, there are two more things you’ll need. They are: an email account for the bot to use; and two more imports at the start of the code.

Email Address for the Bot

You can potentially have your bot send out emails from your existing email address. However, I highly recommend making a fresh Google account specifically for the bot to use. 

This is in part because the account will need to have lower security access than you should normally use. A simple bot is only capable of entering the account name paired with a plaintext password. If you lowered the security of your regular email, it would be easy for a malicious bot to access it.

You can safely receive the emails on your normal account, though.

Once you’ve determined what account the bot will use for outgoing emails, you need to adjust its settings.

First, you’ll need to go into that Google account’s security settings and turn off 2-step verification. 

Once that’s off, you also need to turn on Less Secure App Access. You can’t enable it until 2-step verification is already disabled. 

However, starting May 30th, 2022, this will no longer be possible, as Google will be removing the option.

Once that’s live, I’m sure it won’t be long until a workaround or an alternate service becomes favored for botting.

However, moving on…

Import Commands

There are two more things that you’ll need to import,, in addition to Requests and BeautifulSoup from the scraper portion. They are time and smtplib. They’re both modules that are already built into Python, so there are no additional installations required before using them.

Time should be pretty self-explanatory.

SMTPlib is Python’s module for handling emails, which is important for what we’re about to do.

This means that for everything covered in the previous DIY PS5 Availability Tracker article, plus what we’re about to go over, you’re going to be looking at:

from bs4 import BeautifulSoup
import time, smtplib, requests

Now, let’s get started!

Sending Email Notifications in Python

You have a few options regarding connection security. You could use SMTP_SSL() through port 465 for your connection. However, let’s use SSL’s more secure successor, TLS, via .starttls() through the modern standardized port 587.

The variables could be hardcoded into the main function of the bot’s code if you’re only sending notifications to yourself. However, let’s aim for the goal of easier scalability and being able to adjust for other purposes. 

If the variables are made inside a function, their values don’t carry over between loops. Therefore, we should declare them beforehand and adjust the values as needed.

Declare Variables

The server and port information are filled in under the assumption that you’ll use a Gmail account as recommended. Other service providers have different identifiers, such as AT&T’s SMTP server address being Outbound.att.net.

sender_name = "[email protected]"
sender_password = "The_bots_Google_account_Password"
smtp_port = 587
smtp_server = "smtp.gmail.com"

We’ll set two receiving accounts that’ll be called in a for loop to demonstrate the skeleton needed for upward scalability. If you’re unfamiliar, loops will step through a list or range in sequence, executing the code once per item.

Let’s keep the email body as plaintext for now. If you want to make the link clickable via HTML, you should look into using mimetypes.

email_recipients = ["[email protected]","[email protected]"]
email_subject = "PS5 in stock on Amazon!"
email_body = “PS5 in stock on Amazon @ https://www.amazon.com/PlayStation-5-Console/dp/B09DFCB66S/”

Finally, we also need to declare the variables to track an internal timer to prevent email spam. 

The bot could theoretically detect that the PS5 is available a few hundred times within a very short timeframe. At least, it might be easier after you have the scraper fleshed out to use rotating proxies to repeatedly check availability. The bot would then end up aggressively flooding your mailbox if you don’t have any failsafes in place.

Let’s use the time.time() command to get the current time. The output is a floating point value equivalent to the number of seconds since a fixed starting point. 

We’ll save a timestamp whenever an email is successfully sent out. We can then determine how much time has passed by comparing the saved value to the current time. It’s then a simple formula of current time – last time > cooldown to ensure enough time has passed between emails.

If you’re thinking of the cooldown in minutes, remember to multiply by 60 to convert it into seconds. In this instance, we’ll set a 1-minute cooldown between emails.

last_email_sent = 0
email_cooldown = 60

Send Email Function

The function we’re using for sending email notifications in Python will operate under the assumption that you are only calling it if the desired conditions are met. In this example, that means that Amazon has PS5s in stock. 

First up, we’ll define the send_email function. It will start with a check to see if any emails were sent out recently. It will get to work as long as it has been longer than the internal cooldown since the last one. The default value of 0 will ensure that there aren’t any issues when an email hasn’t been sent yet.

def send_email():
	if time.time() - last_email_sent > email_cooldown:

The bot can’t casually throw emails around all willy-nilly without preparing beforehand. It needs to log in to an existing email account first. Then, we need to tell it what kind of encryption to use.

server = smtplib.SMTP(smtp_server, smtp_port)
server.starttls()
server.login(sender_name, sender_password)

Next up is the for loop to send the email out to everyone in the recipient list.

If you only want one recipient, you can remove the for loop statement and just directly execute its internal components. When doing so, remember to replace ‘recipient’ with the variable you used in the initial declaration. If you’re using the same names as above, then it would be ‘email_recipients’.

for recipient in email_recipients:
   teh_email = [sender_name, ", ".join(recipient, subject, body)]
      try:
         server.sendmail(sender_account, recipient, teh_email)

Now we update the variable tracking the timestamp for the latest email sent out.

last_email_sent = time.time()

The following print message is more for initial setup and debugging. Once everything is fully operational; if you have it set with a short cooldown, the success messages could get spammy pretty quick. Keep the error message in the exception, though, in case something goes sideways. That way you can troubleshoot it faster and easier.

   print ("Email sent successfully!")

except Exception as ex: 
   print("Email sending issue: ",ex)

Once the bot is all done sending out emails, remember to log out.

server.quit()

Conclusion

What we’ve covered so far is enough for a basic notification scraper that you could schedule to run periodically. Next time, we’ll work on upgrading the tracker into a Discord bot. That way, it can announce notifications in chat and passively loop the availability checks.

As you can see, sending email notifications in Python isn’t much of a challenge with a little know-how. But, to ensure you catch drops immediately, your tracker needs to be actively on the lookout. As covered in Five Tips for Outsmarting Anti-Scraping Techniques, checking too frequently will tip Amazon off to bot activity.

How useful was this post?

Click on a star to rate it!

Average rating 0 / 5. Vote count: 0

No votes so far! Be the first to rate this post.

We are sorry that this post was not useful for you!

Let us improve this post!

Tell us how we can improve this post?

Read More Blogs