← All Posts

Automating Concert Ticket Price Watching With GitHub Actions

5 min readMarch 2, 2026
pythonplaywrightgithub-actionsautomationweb-scraping

Automating Concert Ticket Price Watching With GitHub Actions

Automating Concert Ticket Price Watching With GitHub Actions
Automating Concert Ticket Price Watching With GitHub Actions

StubHub
StubHub
Viagogo
Viagogo

Resale ticket prices move constantly. The window where a good deal appears and disappears can be hours — or minutes. Checking manually means either paying too much or missing it entirely.

I wanted a bot that watches for me.


The Setup

The monitor runs every 30 minutes via GitHub Actions cron. It scrapes two resale platforms, compares the lowest price (including fees) to my threshold, and emails me if it's below.

on:
  schedule:
    - cron: '*/30 * * * *'

No server. No hosting fees. GitHub Actions gives you 2,000 free minutes per month — more than enough for a 30-minute cron running a 30-second script.


The WAF Problem

Both StubHub and Viagogo sit behind AWS WAF. Load the page with a standard HTTP request and you get a JavaScript challenge page, not the actual prices.

Playwright solves this by running a real Chromium browser. The WAF challenge auto-resolves when a real browser executes the JavaScript. The trick is waiting for it:

page.wait_for_selector("[data-price]", timeout=20000)

Instead of scraping immediately after navigation, we wait for the price element to appear. The WAF has already resolved by then.


Fee Normalization

One platform shows the ticket price. Another shows the ticket price plus a processing fee at checkout. If you compare them directly, you're comparing different numbers.

The fix: a configurable VIAGOGO_FEE environment variable. The monitor adds it to the scraped price before comparing to threshold. You set it once in GitHub secrets and forget it.

viagogoPrice = scraped_price + int(os.getenv("VIAGOGO_FEE", 0))

Configuration Without Code Changes

All tunable parameters live in GitHub secrets and repository variables:

VariableWhat It Controls
STUBHUB_URLThe specific event listing URL
VIAGOGO_URLThe specific event listing URL
PRICE_THRESHOLDAlert below this price
VIAGOGO_FEEFee to add to Viagogo prices
GMAIL_USERSending Gmail account
GMAIL_APP_PASSWORDGmail app password (not account password)
ALERT_EMAILWhere to send the alert

Want to watch a different event? Update the URLs in the repo variables — no code change, no redeploy.


The Alert

When a price drops below threshold, Gmail SMTP sends a plain-text email with the current price on each platform and a direct link to buy. Simple, fast, actionable.


What I'd Do Differently

Persistent price history. Right now the monitor only checks the current price — it doesn't track trends. Adding a simple CSV append to the workflow would let me see whether prices are generally falling or spiking.

Smarter WAF handling. The wait_for_selector approach works, but it's brittle if the selector changes. A retry loop with multiple selector fallbacks would be more robust.

Telegram over email. Email alerts feel slow. A Telegram bot message is instant and works from anywhere without opening an email client.


The Broader Pattern

GitHub Actions as a free cron executor is underused. Any script that needs to run on a schedule — price monitoring, data aggregation, report generation, health checks — can run here without infrastructure. The repo becomes the deployment unit, secrets become the config layer, and the workflow file documents exactly what runs and when.