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 actually 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 partnered with a plaintext password. If you lowered the security on 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, then 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 20222, 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 obviously 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 do 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 info 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 = "The_bots_Google_account@gmail.com"
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, for 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 = ["1st_Receiving_Email@gmail.com","2nd_Receiving_Email@gmail.com"]
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 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 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. Rotating IPs through a reliable proxy service like KocerRoxy will keep you safe from being blocked.

By Geminel

Geminel is a multi-format author, but is even moreso a giant nerd. With how many times they’ve fallen into several-hour-long research sprees just to accurately present a one-line joke, they realized they should probably use this power for good. To see their creative work, visit their personal site at: Team Gem

Leave a comment

Your email address will not be published.

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.