savepoint-deals
v0.1.0
Published
An always-on agent that watches PS5 game prices on the PlayStation Store and Amazon and tells you on Telegram when a game is worth buying.
Maintainers
Readme
Savepoint
An always-on agent that watches PS5 game prices on the PlayStation Store and on Amazon, keeps its own price history, and tells you on Telegram when a game is worth buying.
It runs on your own machine, needs no API keys except a free Telegram bot token, has zero runtime dependencies, and works for any PlayStation Store region. The public India channel it powers is @savepointdeals.
Built by Salient, an AI product engineering studio. MIT licensed.
What you get
- A public channel with only the exceptional drops: 75 percent off under ₹999, 60 percent off under ₹1,499, strong titles at 40 percent off, and new all-time lows. At most 8 posts a day plus one digest. Each post is the cover art, the price, the reason, and a verdict.
- Private alerts for your watchlist:
/watch Elden Ring 2000and you hear when it reaches ₹2,000, falls by ₹300, or hits its lowest price ever. - Disc and digital in one place. Amazon disc prices are checked against the PS Store, so "disc beats digital by ₹500" is a reason you will see.
- A verdict, optionally. With the Claude Code CLI installed, each new title gets a cached 1 to 10 reputation score and an eight-word verdict, once, forever. A 60 percent discount on a bad game is not a deal. Without it, the rules still work and the post says "not scored".
- A daily digest at 21:00 with the top ten of the day.
Quick start
You need Node 24 or newer and a Telegram account.
npm install -g savepoint-deals
savepoint init- Open Telegram, talk to @BotFather, send
/newbot, and paste the token into~/.savepoint/.envasSAVEPOINT_TELEGRAM_TOKEN. - Send
/startto your new bot, then runsavepoint doctor. It prints your chat id. Put it inSAVEPOINT_ADMIN_CHAT_IDS. - Optional: create a public channel, add the bot as an administrator with permission to post, and put the channel handle in
SAVEPOINT_CHANNEL. - Run
savepoint doctoragain. Every line should sayok. - Run
savepoint crawl --dry-runto see what would be posted right now, thensavepoint crawlto post it. - Keep it running:
savepoint install-launchdon macOS, orsavepoint startunder Docker or systemd elsewhere.
The first day is quiet on purpose: new all-time lows need a week of history before they count.
Commands in Telegram
| Command | What it does |
|---|---|
| /watch <title or ASIN> [target] | Add to your watchlist. /watch Elden Ring 2000, /watch B0C7VLXMT4, /watch Football Manager 2026 under 1500 |
| /unwatch <n> | Remove by the number shown in /list |
| /list | Your watchlist |
| /deals [n] | Best current deals across both stores |
| /low | Titles at their lowest price we have seen |
| /status | Last crawls, counts, outbox, whether Amazon is degraded |
| /digest | Send today's digest now |
| /crawl | Crawl both stores now |
| /pause, /resume | Stop and start alerts |
Only the chat ids in SAVEPOINT_ADMIN_CHAT_IDS can use commands. Strangers get one line pointing at the channel.
The rules, in plain words
All amounts are the India defaults. Other regions have their own presets and everything is overridable.
Public channel, PS Store. Full games and bundles on PS5 only, never DLC, never prices that need PS Plus. One of:
- 75 percent off and under ₹999
- 60 percent off and under ₹1,499
- 40 percent off and under ₹2,499, when the title scores 8 or more
- A new all-time low by at least 5 percent, under ₹2,999, with at least a week of history
For the first two, a guard keeps shovelware out: when the title is scored it needs at least 6 of 10, and when it is not scored its full price must be at least ₹1,499.
Public channel, Amazon disc. In stock, and one of: 35 percent below the reference price and under ₹2,499; ₹500 cheaper than last time we looked; ₹500 cheaper than the PS Store price for the same game. The reference price is Amazon's strike price, capped at 1.25 times the PS Store full price, because inflated list prices make fake discounts.
Your watchlist. At or below your target, a fall of ₹300, a new low, or 35 percent off under ₹2,499.
No repeats. One post per game, store and price. It posts again only when the price falls another ₹250 or 10 percent, or once when the sale ends within 24 hours.
Self-hosting for another region
Set SAVEPOINT_REGION to us or gb for the built-in presets (PS Store locale, Amazon domain, currency, thresholds in that currency). For any other region, start from the closest preset and override thresholds:
SAVEPOINT_REGION=us
SAVEPOINT_TIMEZONE=Europe/Berlin
SAVEPOINT_THRESHOLDS_JSON={"tier1MaxPrice":10,"tier2MaxPrice":15}The PS Store endpoint takes a locale header, so most of the roughly 70 store regions work by adding a preset in src/config.ts. Pull requests with presets are welcome.
Docker
docker build -t savepoint .
docker run -d --name savepoint --restart unless-stopped -v savepoint-data:/data --env-file .env savepointThe image runs savepoint start with SAVEPOINT_HOME=/data. Claude verdicts are off inside the container unless you mount a logged-in Claude Code install.
How it works
One process. Every 60 seconds it checks whether a job is due by looking at the timestamp of the last success, so a laptop that slept catches up on wake. The PS Store crawl runs every 3 hours and walks the store's own deals category through the same GraphQL endpoint the website uses, about 65 requests. Amazon runs every 6 hours over three search pages and your watchlisted ASINs, 8 seconds apart; a captcha pauses that source for 6 hours and never blocks PS Store alerts.
Everything lands in one SQLite file (node:sqlite, no native module to build). Price history is append-only: one row per price change per product. Alerts are keyed so the same deal is never sent twice. Sends go through a persistent outbox at one message per second with retries, so a Telegram outage loses nothing.
Telegram is long polling, so nothing needs a public URL.
Honest caveats
- The PS Store endpoint is unofficial. When Sony changes it, crawls fail, and after two failures in a row the bot tells you. Fixtures from real responses live in
test/fixturesso a fix is a small change with a test. - Amazon's HTML is parsed narrowly and Amazon does throw captchas. Disc prices are best effort.
- Flipkart blocks plain requests and is not covered.
- Verdicts are one model's opinion of a game's reputation. They influence only the "strong title" rule and the shovelware guard. Every other rule is arithmetic.
- The first week has no all-time lows because there is no history yet.
Development
npm install
npm test # vitest, fixture-driven
npm run build # tsc
node dist/cli.js crawl --dry-runDesign notes and the two-agent design discussion that produced this are in docs/.
