- Python 86%
- JavaScript 9%
- HTML 4.3%
- CSS 0.7%
Add the final web UI layer on top of the FastAPI control API: - Real-time: /ws WebSocket pushes live engine status, watchlist stock/price changes, restock events and streamed log lines. Frontend live-updates the status indicator, watchlist cells and log panel; polling now only runs as a fallback when the socket drops, with exponential-backoff reconnect. Broadcast is push-based from a loguru sink + a polite status ticker (no busy loops). - Auth: single admin user with a PBKDF2-hashed password + signed HttpOnly session cookie stored in a new [web] config section. All pages, /api/* and /ws require login; deny-by-default with a setup notice when no password is set. 'python main.py web --set-password' helper. - Polish: graceful WS reconnect/backoff, toasts on restock/purchase, Buy confirmation + result display. - Default bind stays on 127.0.0.1; loud warning when bound to 0.0.0.0. - Docs: 'Web UI' README section. Offline tests for auth + WS (22 web tests, whole suite green offline). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|---|---|---|
| buyers | ||
| config | ||
| core | ||
| database | ||
| monitor | ||
| proxy | ||
| static | ||
| utils | ||
| web | ||
| .gitignore | ||
| config.ini.example | ||
| main.py | ||
| README.md | ||
| requirements.txt | ||
| test_bot.py | ||
| test_web_api.py | ||
""" PokeBot - Target Pokemon Card Buying Bot
Target-only. This bot buys from Target exclusively. The Amazon, Walmart, Best Buy, and Pokemon Center buyer/monitor classes and their
config.inisections still exist in the codebase but are disabled — only Target runs.
Features
- Target Support: Automated monitoring and checkout on Target
- Real-time Monitoring: Check availability every second
- Discord Integration: Monitor channels for restock alerts
- Proxy Rotation: Automatic IP rotation to avoid bans
- Anti-Detection: Human-like behavior simulation
- Auto Checkout: Complete purchases automatically
- Notifications: Slack, Telegram, Email, Pushover alerts
- Session Management: Save/load browser sessions
- CAPTCHA Solving: Integrated CAPTCHA solver
Installation
# Clone repository
git clone https://github.com/user/pokebot.git
cd pokebot
# Create virtual environment
python -m venv venv
venv\Scripts\activate # Windows
source venv/bin/activate # Mac/Linux
# Install dependencies
pip install -r requirements.txt
# Install Playwright browsers
playwright install chromium
Configuration
-
Copy the example config file:
cp config.ini.example config.ini -
Edit
config.iniand fill in your details:- Retailer login credentials
- Payment information
- Discord token and channels
- Proxy API details
- Notification settings
Target setup (RedSky monitoring)
Availability monitoring uses Target's unofficial RedSky aggregations API
(redsky.target.com). These endpoints are reverse-engineered from target.com
and can change without notice. Configure the [target] section of config.ini:
tcins— the items to watch, as a comma-separated list of TCINs (Target Catalog Item Numbers). To find a TCIN, open a product page on target.com; the URL ends in/A-<TCIN>(e.g.https://www.target.com/p/-/A-88897921→88897921). It also appears under "Specifications". Example:tcins = 88897921, 94300072.store_id— your preferred store's numeric id, used for pickup and scheduled-delivery checks. Find it via target.com → "Find Stores", pick a store, and read thestore_idfrom the resulting URL/store page.zip— your ZIP code; combined withstore_idit drives local fulfillment availability.redsky_api_key— the public RedSky "visitor" key. Leave blank to use the built-in default. Only set this if monitoring starts failing — Target rotates the key occasionally. You can recover the current key from thekey=query parameter on anyredsky.target.comrequest in your browser's DevTools → Network tab while browsing target.com.
With at least one TCIN configured, the monitor checks those items directly. With no TCINs, it falls back to searching by product name to discover a TCIN.
Credentials, payment details, and the RedSky key are read from
config.ini, which is git-ignored — never commit real values.
Drop-day tuning ([target])
These [target] knobs make a single, honest account as fast as it
realistically can be — detect early, already be logged in, and check out in the
fewest steps. They are about speed and reliability, not evasion: there are
no proxy pools, no multi-account rotation, no CAPTCHA services, and no attempt
to skip a Queue-it/Akamai waiting room.
| Knob | Default | What it does |
|---|---|---|
poll_interval |
2.5 |
Seconds between RedSky stock checks. Lower = faster detection but more requests. Keep it polite (~2–3s); the monitor backs off automatically on 429/errors. |
poll_jitter |
0.5 |
Max extra random seconds added to each poll so requests aren't perfectly periodic. |
max_queue_wait_seconds |
600 |
How long to wait in line in a Queue-it / waiting room before giving up. The bot never bypasses the queue — it holds your place and polls until released. |
pre_warm |
true |
Before stock is detected: launch the browser, restore saved cookies, log in, and park on the product PDP so checkout is instant on the in-stock flip. |
express_checkout |
true |
Use the minimal PDP → add to cart → checkout → place order path that relies on saved shipping + payment already on your Target account. |
Drop day runbook
-
Set your items. In
config.ini[target], settcinsto the TCIN(s) you're chasing, plus yourstore_idandzipfor local fulfillment checks. -
Save shipping + payment on the account. Express checkout assumes Target already has your default address and a saved card (
use_saved_address = true). Add them on target.com beforehand — the bot does not type a card number. -
Warm the session a few minutes early. Start the bot before the drop with
pre_warm = true. It logs in once (handling TOTP 2FA iftwo_factor_secretis set), persists cookies tostatic/cookies/, and parks on the PDP. After the first login you'll rarely need to log in again — cookies are reused.python main.py start --products "Charizard Booster Box" -
Let it poll. The engine tight-polls RedSky every
poll_interval(+ jitter). On the in-stock transition it immediately runs the express checkout against the already-warm, logged-in context. -
If a waiting room appears, it waits. A Queue-it interstitial is detected and the bot holds your place, logging queue status until released (up to
max_queue_wait_seconds), then continues checkout.
Reading the timing logs
Every successful express checkout logs three checkpoints so you can tune
poll_interval and per-step timeouts:
[Target][timing] detect @ +0.0s (2026-06-30T10:00:00.000)
[Target][timing] add_to_cart @ +0.42s (2026-06-30T10:00:00.420)
[Target][timing] order_placed @ +1.83s (2026-06-30T10:00:01.830)
[timing] Charizard Booster Box: detect->add_to_cart->order_placed (seconds from detect) = {'detect': 0.0, 'add_to_cart': 0.42, 'order_placed': 1.83}
- detect — when the in-stock flip was seen and checkout began.
- add_to_cart — seconds later the item was in the cart (retries a briefly-failing button; bails fast if sold out).
- order_placed — seconds later the order was confirmed (the real order number is captured on success).
Honest caveats. Target's DOM and anti-bot stack change without notice, so the checkout selectors and the RedSky endpoints may need updating over time. A single account cannot out-muscle large bot farms running thousands of sessions — but pre-warming, low-latency detection, and a minimal express checkout give one legit account its best realistic shot.
Usage
The bot is Target-only.
--retailers/--retaileraccepttarget(the default) orall— both run Target. Any other retailer is rejected with a clear error.
Start the bot
python main.py start --products "Charizard Base Set" "Pokemon Cards"
Start (explicit Target)
python main.py start --retailers target --products "Pokemon Cards"
Monitor a specific product
python main.py monitor --product "Shadow Realm Charizard" --retailer target
Buy immediately
python main.py buy --product "Pokemon Cards" --quantity 4 --retailer target
Web UI
A FastAPI control dashboard with a dependency-free single-page frontend, live WebSocket updates and session-based login. It drives the same engine, config and buyer as the CLI — no separate state.
Install
The web dependencies ship in requirements.txt (already installed if you ran
pip install -r requirements.txt):
pip install fastapi "uvicorn[standard]" python-multipart jinja2
No Node/bundler step — Tailwind loads from a CDN and the JS is plain ES.
1. Set the admin password (required)
The dashboard holds your Target credentials and payment info and can spend money, so it denies all access until a password is set (you'll see a setup notice instead of the login page). Set one with the built-in helper:
python main.py web --set-password
It prompts for a username (default admin) and password, then writes a PBKDF2
hash (never the plaintext) plus a random signing secret into the [web]
section of config.ini:
[web]
username = admin
password_hash = pbkdf2_sha256$240000$... # hashed, not reversible
secret_key = <random 64-hex signing key>
Re-run it any time to change the password. To rotate the cookie-signing key (and
invalidate all existing sessions), clear secret_key first or edit it directly.
2. Start the dashboard
python main.py web # binds 127.0.0.1:8000 (localhost only)
python main.py web --port 8080 # custom port
Open http://127.0.0.1:8000 and log in with the credentials you set. The signed, HttpOnly session cookie lasts 7 days; Sign out (top-right) clears it.
Tabs
- Status — engine running/stopped indicator + uptime, Start / Stop / Pre-warm / Test buttons, an auto-buy toggle, and a live "feed" indicator showing whether the WebSocket is connected or it has fallen back to polling.
- Watchlist — add/remove monitored TCINs, see last-known stock/price (cells update live), and trigger a per-row Buy now (confirmation prompt + result toast, since it spends money).
- Config — edit the
[target]account, shipping/payment, tuning (poll_interval,pre_warm,express_checkout, …) and notification settings. Secrets render as masked fields and are only written when changed. - History — recorded purchases (order id, product, price, time, status).
- Logs — a live tail of the bot log, streamed line-by-line over the socket.
Real-time updates
The dashboard opens a WebSocket to /ws and live-updates the status indicator,
watchlist stock/price cells and the log panel — no polling while it's connected.
A watched item going in stock or a successful purchase pops a toast. If
the socket drops, the UI reconnects with exponential backoff (up to 30s) and
falls back to 3–5s HTTP polling in the meantime, so it always stays current.
Drop-day workflow through the UI
- Config tab → fill in the Target account, shipping + payment, and tuning
(turn on
pre_warmandexpress_checkout); Save. - Watchlist tab → add the TCIN(s) you're hunting.
- Shortly before the drop, hit Pre-warm (Status tab) to log in and park a warm session, then Start to begin the low-latency poll loop.
- Watch the watchlist cells flip to in stock and the toast fire. With auto-buy on, the engine checks out automatically (Start asks you to confirm first); otherwise click Buy now on the row to purchase manually.
- Confirm the result in the toast and the History tab.
Security notes
- Localhost only by default. The bind stays on
127.0.0.1. If you bind to0.0.0.0the server logs a loud warning at startup — this UI exposes saved credentials and can spend money, so only expose it behind a trusted network/VPN + firewall, and only with a strong password set. - Single admin account, session cookie signed with a per-install secret; passwords are stored hashed (PBKDF2-HMAC-SHA256), never in plaintext.
- All pages, every
/api/*route and the/wssocket require login; an expired or missing session redirects to the login page (or401s the API).
Run the test suite
The bundled suite is fully offline — it mocks Target's RedSky API and the Playwright browser, so it never makes a network call and needs no credentials.
python test_bot.py
It exits 0 with Success Rate: 100.00% when everything passes. Coverage
includes the settings singleton, proxy manager, database, notifications and
anti-detection, plus the Target pipeline specifically: AvailabilityStatus
parsing from mocked RedSky payloads (in-stock and out-of-stock), the
check_product → handle_availability → buyer.purchase engine wiring, and the
TargetBuyer selector constants / login fallback path.
Test configuration (live)
These commands hit the real services and require a populated config.ini:
# Test proxy connection
python main.py test --proxy
# Test Target login
python main.py test --login target
Project Structure
pokeBot/
├── main.py # Entry point
├── config.ini # Configuration file
├── requirements.txt # Python dependencies
│
├── config/
│ └── settings.py # Configuration management
│
├── core/
│ ├── bot_engine.py # Main bot engine
│ └── monitor_manager.py # Product monitoring
│
├── monitor/
│ ├── base_monitor.py # Abstract monitor class
│ ├── discord_monitor.py # Discord integration
│ ├── target_monitor.py # Target-specific monitor
│ ├── amazon_monitor.py # Amazon-specific monitor
│ ├── walmart_monitor.py # Walmart-specific monitor
│ ├── bestbuy_monitor.py # Best Buy-specific monitor
│ └── pokemon_center_monitor.py # Pokemon Center monitor
│
├── buyers/
│ ├── base_buyer.py # Abstract buyer class
│ ├── factory.py # Buyer factory
│ ├── target_buyer.py # Target buyer
│ ├── amazon_buyer.py # Amazon buyer
│ ├── walmart_buyer.py # Walmart buyer
│ ├── bestbuy_buyer.py # Best Buy buyer
│ └── pokemon_center_buyer.py # Pokemon Center buyer
│
├── proxy/
│ ├── manager.py # Proxy rotation system
│ └── rotator.py # Proxy utilities
│
├── utils/
│ ├── anti_detection.py # Anti-detection measures
│ ├── notifications.py # Multi-channel notifications
│ ├── logger.py # Logging utilities
│ └── cookie_manager.py # Session management
│
├── database/
│ └── models.py # Database models
│
├── web/ # FastAPI control API + dashboard
│ ├── app.py # REST endpoints + serves the dashboard at /
│ ├── engine_controller.py # Start/stop/buy wrapper around BotEngine
│ ├── config_io.py # Grouped config read/write with secret masking
│ ├── log_buffer.py # In-memory log tail for /api/logs
│ ├── schemas.py # Pydantic request/response models
│ ├── templates/ # Jinja dashboard template (index.html)
│ └── static/ # Dashboard JS + CSS (no bundler)
│
├── logs/ # Application logs
│
└── static/
├── cookies/ # Saved session cookies
└── user_profiles/ # Browser profiles
License
MIT License - See LICENSE file