Webhooking into Discord with Python

Bargain Hunting for Games with the Beautiful Soup Library

Mike Riley
The Pragmatic Programmers

--

I work hard, write code, and love my job. At the end of a long day, I also enjoy unwinding with a quick Xbox gaming session. I’m not a hard-core gamer, so things like subscriptions to monthly game services don’t really appeal to me, but finding good bargains certainly does. While PC gaming services like Steam alert customers when a wish-listed item is on sale, Microsoft doesn’t offer any sort of alert service. No matter — a quick Python script using the Beautiful Soup library and a Discord client will alert me when a game is on sale. Let’s get started building our alert system.

The Hardware: Pi Zero

Photo by Harrison Broadbent on Unsplash

I have a Pi Zero acting as my internal Git server as well as monitoring for water leaks in my basement (see my book Portable Python Projects for that useful solution).

Since Microsoft updates Xbox game sales every Tuesday morning, I cron the following script to run on my Pi Zero (although a regular Pi 3 or higher will also do just fine) at that time. Setting up cronjobs on the Pi is easy. If you have never done it before, just search for Pi crontab web pages and videos, and you will be good to go.

The Software: Beautiful Soup, pipenv, and Webhooks

We are going to use pipenv as our Python virtual environment manager. pipenv keeps Pi’s OS file system tidy while ensuring no oddball dependencies from other Python projects are stepping on my desired running script. To install pipenv on a Python 3 Pi environment, simply run:

$ sudo pip3 install pipenv

Photo by Piotr Miazga on Unsplash

We are going to scrape Microsoft’s game sales page for the current selling price, with Beautiful Soup 4, so install that next. If there is a game price change, you’ll post a webhook notification to a URL for your designated Discord channel.

I find this method of throwaway notification far more efficient than email. It’s also more secure — no worries about including any account credentials to log into an email server to transmit a message. If the assigned webhook URL ever gets compromised, simply delete it and regenerate a new one.

To make Discord webhook transmission easy from Python without having to rely on raw JSON formatting of the message, I also used the discord-webhook library.

Create a new project folder such as pricealert, change to that folder and run:

$ pipenv shell

You now have a new virtual environment for Python scripts in that folder. Within that activated virtual environment, run pip3 to install the Beautiful Soup, Discord webhook, and Requests library dependencies.

$ pip3 install beautifulsoup4 discord-webhook requests

Now it's time to set up a webhook on Discord.

Getting (web)Hooked to Discord

I already had a Discord account (with two-factor authentication enabled, naturally). Activating it for webhook access is simply a matter of accepting the Discord developer agreement.

Create a custom, private channel on Discord. I called mine #price-alerts.

Create a Private Discord Channel

Next, have Discord generate a webhook URL for that channel via the Integrations > Webhooks settings page for the #price-alert channel.

Integrations > Webhooks Dialog

Now, copy the webhook URL for use in your Python script.

Python Script to Check for Sales

With the hardware and software dependencies configured, let’s write the simple Python script that will do the tedious job of checking for specific sales every week:

How the Script Works

After importing the Beautiful Soup, Discord Webhook and Requests Python libraries, we define a function called getxbprice that accepts the game URL and the price to validate. Then we use Beautiful Soup to parse out the current selling price for the game. If the current price is different than the one passed into the getxbprice function, the script returns the game’s name that was found in the respective Beautiful Soup DOM element search. If the price does match, it returns an empty string. We add the result to any other game URL and price to pass to the getxbprice function until all specified game URLs have been processed. Finally, if the resulting string at the end of this processing isn’t empty, we instantiate a Discord webhook, embed the results, and execute (that is, send) the webhook.

Game Price Alert Results

The game URLs I included are a sampling from my Xbox Wishlist, and they include pricing as of the date of this article’s publication. To test the script yourself, simply change any of the prices to verify. Doing so should post a webhook alert that displays the game’s title and current price in your #price-alerts Discord channel. Neato!

#price-alerts Channel Alert Notification

Next Steps: Optimize the Script

This article shows just how simple it is to get Python and Discord to send notifications when monitored conditions change. You can further optimize the script by:

  • Placing the game URLs into an array.
  • Converting the soup-scraped price string into a float.
  • Performing a conditional range on it.

For example, if you want to be notified only when the price variance is greater than 30%, send a notification. Embedding a URL within the game’s title displayed in the Discord message might also be helpful as a way to quickly verify the game’s price and even proceed to purchase it.

Beautiful Soup price-checking recipes for other ecommerce websites like Amazon and eBay are plentiful — and you can apply them in your own web-hooking scenarios. Now you will never again miss out on a sales event for an item you want to buy!

If you enjoyed this article, here are more articles from Mike Riley:

--

--