Commit Graph

13 Commits

Author SHA1 Message Date
prosolis
b8a0fd5f35 Rewrite Pastel from Python to Go with watchlist feature
Full rewrite of the gaming deals Matrix bot in Go for better performance
and a single static binary. Includes all original functionality (CheapShark,
ITAD, Epic free games, multi-currency pricing, dedup, preflight checks,
presence heartbeat) plus a new watchlist feature where users can DM the bot
to watch for specific game deals with 180-day auto-expiry.

New: systemd service file, DB migration script for Python-to-Go transition.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 20:56:15 -07:00
Claude
2b1c606a80 Add optional Matrix thread support for per-category deal organization
When MATRIX_USE_THREADS=true, deals are posted into dedicated threads
instead of the room timeline:

  - 🎮 Game Deals — CheapShark + ITAD type=game
  - 🧩 DLC Deals — ITAD type=dlc
  - 🆓 Epic Free Games — current and upcoming Epic free games
  - 📦 Non-Game Deals — ITAD non-game content (software, courses, etc.)

Thread roots are created on first use and persisted in the database.
When threads are disabled (default), behaviour is unchanged.

Key changes:
- New threads.py module with ThreadCategory enum and routing logic
- ITADDeal now carries deal_type; type filter moved from fetcher to bot
- MatrixDealsClient gains send_deal_in_thread() and create_thread_root()
- Database gets thread_roots table for storing root event IDs
- Bot routes each deal to the appropriate thread via _send_to_thread_or_room()

https://claude.ai/code/session_01EfPjktyrF24DBNHWsY1KBP
2026-03-01 00:37:26 +00:00
Claude
f13bfd7b07 Default ITAD_DEALS_LIMIT to 200 (API max) to maximise deal coverage
Since the ITAD API only sorts by discount or price (no time-based sort),
fetching the full 200-deal window per country ensures our client-side
filtering sees every available deal rather than just the top N by discount.
The dedup database already prevents reposting, so the extra data is cheap.

https://claude.ai/code/session_01EfPjktyrF24DBNHWsY1KBP
2026-02-28 23:42:54 +00:00
Claude
e4d90d0331 Add multi-country ITAD deals, configurable currency, and per-source filtering
- ITAD deals can now be fetched from multiple countries simultaneously via
  ITAD_COUNTRIES (e.g. US,CA,GB,DE). Deals are merged across regions and
  deduplicated by game+shop, with the first country taking priority.

- Prices from non-USD regions are normalised to USD using exchange rates
  so filtering (max price) works consistently across countries.

- ITAD results are now sorted by newest deals first (client-side by
  timestamp) instead of only by highest discount, reducing missed deals.

- Default fetch limit raised from 20 to 100 to capture more deals.

- Display currency is now configurable: DEFAULT_CURRENCY sets the primary
  currency shown first, EXTRA_CURRENCIES sets additional ones. All
  Frankfurter-supported currencies are available with proper symbols.

- Filtering is now per-source with dedicated env vars:
  CHEAPSHARK_MIN_DISCOUNT, CHEAPSHARK_MIN_RATING, CHEAPSHARK_MAX_PRICE,
  ITAD_MIN_DISCOUNT, ITAD_MAX_PRICE, ITAD_DEALS_LIMIT. Shared fallbacks
  (MIN_DISCOUNT_PERCENT, MAX_PRICE) are still supported. Legacy
  MAX_PRICE_USD and MIN_DEAL_RATING continue to work as fallbacks.

https://claude.ai/code/session_01EfPjktyrF24DBNHWsY1KBP
2026-02-28 23:40:36 +00:00
Claude
d1a33e97c5 Update README to document ITAD as a deal source and DEAL_SOURCES config
https://claude.ai/code/session_01B7YPGrE3NatkwadCXVjv2j
2026-02-28 05:04:24 +00:00
Claude
13cdd6d8b5 Document SEND_INTRO_MESSAGE in README config table
https://claude.ai/code/session_017eMsVwUopgmnEyd6JJedpV
2026-02-28 03:02:56 +00:00
Claude
88377e258a Use CheapShark's native 0-10 scale for MIN_DEAL_RATING
The previous 0-100 scale with a * 10 conversion was confusing —
CheapShark returns deal ratings as floats (e.g. 9.8, 7.5) so the
config should match. Default is now 8.0 instead of 80.

https://claude.ai/code/session_01LPpSZFfyh6vdV5HGFWjoQX
2026-02-28 02:21:24 +00:00
Claude
016d2c1973 Add --check preflight to validate config and connectivity
`python -m gaming_deals_bot --check` tests each external dependency
before starting the bot:

- Matrix: verifies access token (whoami) and room membership
- CheapShark: hits the deals endpoint
- Epic Games Store: hits the free-games endpoint
- Frankfurter: fetches exchange rates
- IsThereAnyDeal: validates the API key (skipped if not set)

Exits 0/1 so it works in CI pipelines and Docker health-checks.

https://claude.ai/code/session_01LPpSZFfyh6vdV5HGFWjoQX
2026-02-28 01:52:48 +00:00
Claude
d5f30487cb Add instructions for obtaining a Matrix bot access token
Walk through creating a bot account, logging in via the client API
to retrieve the access token, and inviting the bot to the room.

https://claude.ai/code/session_01LPpSZFfyh6vdV5HGFWjoQX
2026-02-28 01:39:32 +00:00
Claude
6fdbc9f9a0 Reduce exchange rate refresh to twice daily
Be respectful of the free Frankfurter API — ECB rates only update once
a day anyway, so a 12-hour cache TTL is more than sufficient.

https://claude.ai/code/session_01LPpSZFfyh6vdV5HGFWjoQX
2026-02-28 00:56:21 +00:00
Claude
8277cf37e2 Add multi-currency pricing (USD, CAD, EUR, GBP) for deal posts
Fetches live exchange rates from the Frankfurter API (ECB data, free,
no API key) and displays converted prices alongside USD in every deal
message. Rates are cached in memory and auto-refreshed hourly.

https://claude.ai/code/session_01LPpSZFfyh6vdV5HGFWjoQX
2026-02-28 00:51:52 +00:00
Claude
6e84429ad1 Add gaming deals Matrix bot
Implements a Matrix bot that posts PC gaming deals and free game alerts:
- CheapShark API integration (Steam, GOG, Humble, GMG) polled every 2 hours
- Epic Games Store free games detection polled daily
- IsThereAnyDeal historical low price flagging (optional)
- SQLite deduplication with 30-day pruning
- First-run population (records existing deals without posting)
- Matrix-flavored HTML + plain text fallback messages
- Dockerfile for containerized deployment

https://claude.ai/code/session_01LPpSZFfyh6vdV5HGFWjoQX
2026-02-28 00:00:22 +00:00
prosolis
11a3eace9f Initial commit 2026-02-27 15:47:43 -08:00