For Valentine’s Day this year I wanted to get a nice gift for a special someone. So I decided to buy some tickets for a dinner and show. Just one problem, the site I was looking at ran out of tickets for currently scheduled shows. When I called the restaurant they told me to check the website - they were going to add more tickets at a later time.
But I didn’t want to constantly check the page to see if new times and dates were added, so I wrote a new project called Ticket Owl to do it for me.
Ticket Owl periodically checks a website for characteristics I’m interested in. I’ve written it so that it is flexible enough to do a few different things:
- To check a website with varying frequency
- To allow you to check for text on a page
- To allow you to check for text not on a page
- To notify you via email or SMS or both when your condition is met
- To be deployed to AWS with the Serverless Framework
- To process multiple checks of multiple different websites
Now in addition to Valentine’s Day-esque uses you could probably use this to regularly monitor the status of different websites. But, realistically, you just want to know the moment that those Taylor Swift tickets are on sale.
Here’s how you can use this project.
Make sure you have an AWS account with your account
Clone the repo with
git clone https://github.com/fernando-mc/ticket-owl.git
Make sure you have a verified email address to use in your AWS account if you want to send email alerts.
a) Review the examples in
index.pyand update it to reflect the checks and alerts you’d like to work with Or b) Update the
jobs.pyfile to reflect the same details and make sure your
index.pyfile keeps the code to run the jobs in the handler function. (More on both of these in a moment)
Finally, when you’re ready just use
sls deployto deploy Ticket Owl to AWS and optionally use
sls invoke --function scanto manually trigger and test the function. Although if the conditions you’re waiting for haven’t happened yet, you won’t get any alerts!
Writing Your Checks
Let’s go into more detail on the two options you have to check your website for different characteristics.
Write ‘jobs’ in the
jobs.py file to be checked every time your AWS Lambda function runs. Jobs in this sense are basically just configurations values like the list of websites and conditions to potentially alert on as well as how to alert on them.
jobs.py file might look like this:
JOBS = [
'value_to_check': 'Feb 10',
'alerts': ['email', 'sms'],
'message': 'The ticket for Feb 10 is now on sale! - https://www.myticketsite.com/event/123123',
'subject': 'Ticket Owl Alert',
'message': 'Looks like your favorite musician is talking about her next tour! - https://www.myfavoritemuscian.com/',
Let’s break this down. In this file, there are two ‘jobs’ which are basically just Python dictionaries with a standard set of possible configuration values that are shown in the default
jobs.py file in GitHub.
All jobs require the
checker values. In the same order listed, these values tell Ticket Owl what URL to fetch the page text of, what string value to search for inside of the page text and what condition to apply to that value if found.
For example the
contains_text would return True if the page contained the
Additionally, there is an
alerts array that tells Ticket Owl how to alert the user. Either via SMS or email.
Finally, depending on the
alerts value some additional values must be included to allow alerting to take place. SMS and email require different values:
sms alert requires only
phone_number configuration values.
verified_email. The email must be verified in Amazon SES.
index.py file using the only the jobs method of checking websites might look as simple as this:
from jobs import JOBS
def handler(event, context):
index.py files are saved you can deploy the project with the
sls deploy command.
Alternatively, you can skip using the
jobs.py file entirely and write your own logic with the helpers provided in
helpers.py. In this case, you might see an
index.py file that looks like this:
url = 'https://www.tickets.com/event/123123'
message = 'That ticket you wanted is now on sale! https://www.tickets.com/event/123123'
verified_email = 'firstname.lastname@example.org'
subject = 'Your tickets are on sale!'
phone_number = '+1555777888#'
if helpers.contains_text('Mezzanine', url):
if helpers.lacks_text('Only VIP Tickets On Sale Now', url):
helpers.send_email(verified_email, subject, message)
Half of this file basically sets up the values you’ll use for alerting purposes. The latter half demonstrates how simple it is to check if a site contains text or doesn’t contain certain text and then how to use the helpers to alert on the result.
Right now there are only two main helpers:
lacks_text which evaluate to true, respectively, if the site contains the text you’re looking for, or lack it completely. However, I’m considering adding a
site_changed checker to be used to diff effectively between the site from one scan to another.
And that’s it really! Check it out and let me know what you think. As always, PRs are welcome and feel free to leave a comment below.