A to Z Guide
How this project works, from data collection to GitHub Pages.
This page documents the project architecture, scripts, workflow, data files, and deployment path so anyone opening the repository can understand the full system quickly.
Overview
What this project does
The project tracks free game promotions from Epic Games and Steam, stores structured JSON snapshots, sends notifications through email, Telegram, and Discord when lineups change, updates the README automatically, and exposes the latest offers through this GitHub Pages site.
System Flow
End-to-end flow
`epic.PY` calls Epic's promotion endpoint and `steam.py` gathers Steam deals from web/API sources.
Each script converts the results into predictable JSON records with title, link, image, type, and timing fields.
A signature is built from the offer list so emails only send when the lineup actually changes.
The latest state is saved into `free.json` and `free-steam.json` for downstream consumers.
`generate_readme.py` refreshes the README while GitHub Pages serves the JSON-backed website, and `start.py` runs both notifiers locally in sequence.
Repository
Main files
Data
JSON structure
The site expects these repository files:
free.json
{
"signature": "...",
"updated_at": "...",
"current_games": [{ "title": "", "link": "", "image": "", "start": "", "end": "" }],
"upcoming_games": [{ "title": "", "link": "", "image": "", "start": "", "end": "" }]
}
free-steam.json
{
"signature": "...",
"updated_at": "...",
"games": [{ "type": "", "title": "", "link": "", "image": "", "time": "" }]
}
Delivery
Notification channels
The project can notify through email, Telegram, and Discord. Each channel can be enabled or disabled
independently inside config.json.
{
"secrets": {
"use_hardcoded_secrets": false,
"secrets_file": "secrets.json"
},
"notifications": {
"email": true,
"telegram": true,
"discord": true
}
}
Email, Telegram, and Discord all support multiple targets separated by commas. Email supports up to
30 recipients per run, for example first@example.com,second@example.com. Telegram and
Discord support comma-separated chat or channel IDs like -1003918180986,1845799450 and
123456789012345678,987654321098765432.
{
"email": {
"email": "you@gmail.com",
"password": "your-app-password",
"to_email": "first@example.com,second@example.com,third@example.com"
},
"telegram": {
"bot_token": "123456:telegram-bot-token",
"chat_id": "-1003918180986,1845799450"
},
"discord": {
"bot_token": "YOUR_DISCORD_BOT_TOKEN",
"channel_id": "123456789012345678,987654321098765432"
}
}
Automation
GitHub Actions
The workflow runs every 6 hours and can also be triggered manually. It installs dependencies, runs both fetcher scripts, regenerates the README, and commits updated JSON snapshots.
Deployment
GitHub Pages setup
The public entry lives at the repository root in index.html, while shared site assets and
the documentation page live in the SITE/ folder. This keeps GitHub Pages happy while still
grouping the website files cleanly.
Setup
How to run locally
pip install requests beautifulsoup4
$env:EMAIL="you@example.com"
$env:PASSWORD="your-app-password"
$env:TO_EMAIL="first@example.com,second@example.com"
$env:TELEGRAM_BOT_TOKEN="123456:telegram-bot-token"
$env:TELEGRAM_CHAT_ID="-1003918180986,1845799450"
$env:DISCORD_BOT_TOKEN="your-discord-bot-token"
$env:DISCORD_CHANNEL_ID="123456789012345678,987654321098765432"
python start.py
python generate_readme.py
Extend
How to grow the project
You can add more storefronts by following the same pattern: fetch data, normalize it into JSON, generate a signature, save a state file, and teach the site how to render the new data source.