Files
pokemon-stock-checker/config.py
T
2026-04-10 18:30:04 -04:00

252 lines
11 KiB
Python

"""
Configuration for Pokemon Stock Monitor
Update DISCORD_WEBHOOK_URL with your actual webhook URL
"""
import os
try:
from dotenv import load_dotenv
load_dotenv()
except ImportError:
pass # python-dotenv not installed, fall back to env vars or hardcoded values
def _env(key, default=""):
return os.environ.get(key) or default
# Discord webhook URL - GET THIS FROM YOUR DISCORD SERVER
# Server Settings -> Integrations -> Webhooks -> New Webhook -> Copy Webhook URL
# This is the default/fallback webhook for anything not specifically routed below
# Set DISCORD_WEBHOOK_DEFAULT in .env to override
DISCORD_WEBHOOK_URL = _env("DISCORD_WEBHOOK_DEFAULT", "https://discord.com/api/webhooks/1488982276455796756/4HEzQDBF-Hs4a9Iyd7yvj7-SfP0BwrbQGdGBmQ9TL9urWzkTRaHelkvrqX4v9NTf2ZJ_")
# =============================================================================
# MULTI-CHANNEL WEBHOOK ROUTING (Optional)
# =============================================================================
# Route notifications to different Discord channels based on site and/or alert type.
# Leave webhooks as None to use the default DISCORD_WEBHOOK_URL above.
#
# Create webhooks in Discord: Server Settings -> Integrations -> Webhooks -> New Webhook
#
# Lookup priority:
# 1. overrides (specific site + type combo)
# 2. sites (all alerts for a specific store)
# 3. types (all alerts of a specific type)
# 4. default (DISCORD_WEBHOOK_URL)
#
# Override any value by setting the corresponding env var in .env
DISCORD_WEBHOOKS = {
# Per-site channels - all alerts from a specific store go here first
"sites": {
"target": _env("DISCORD_WEBHOOK_TARGET", "https://discord.com/api/webhooks/1488982720901025852/O0KkVFHrQ6-k6FmCqQE4QpuWF6YFJ8YyFgojBPKcQu9g0UHzTpnAU9G1gbhOftARS11R") or None,
"bestbuy": _env("DISCORD_WEBHOOK_BESTBUY", "https://discord.com/api/webhooks/1488982786781216798/AtG6x7FWzJjOsmosq9oPMuwlPrSwNHZJJTUuB3AApjyT7LIOxmEcYeiMFP7HiA_Ov1pn") or None,
"gamestop": _env("DISCORD_WEBHOOK_GAMESTOP", "https://discord.com/api/webhooks/1488982854036619355/NWZtydrKEhj-kxKbFi78f1Gpf3h16W_1kAJEcSuIgtjJUoAO8Sk7inOI2T8fb9GXo9xY") or None,
"walmart": _env("DISCORD_WEBHOOK_WALMART", "https://discord.com/api/webhooks/1488982929450340375/0g16tJXw8f9UtUrRrLd2jDPWWD__LTDYO_X2VT2WL4F5GBYB8ykVxrjV-bCjzKKjSA5C") or None,
"pokemoncenter": _env("DISCORD_WEBHOOK_POKEMONCENTER", "https://discord.com/api/webhooks/1488983050090975364/DwY9QQvBZa6V-zz8mIg302sukbISSbkXOhDwe1Q6yDG0zAwvaGQcn8iTzNB4D676e3cA") or None,
},
# Per-type channels - used when no site-specific webhook is set
"types": {
"restock": _env("DISCORD_WEBHOOK_RESTOCK", "https://discord.com/api/webhooks/1488982403048542269/s1J_p8R6IMGQGypPh_ZYTHHBD0cMnd_BjLGggVWaL2OcyDQAR42KS-CyuHcVr5s21vl3") or None,
"new_drop": _env("DISCORD_WEBHOOK_NEW_DROP", "https://discord.com/api/webhooks/1488982511613771898/RLDoHxNjsAx0PfHfT0kZe6-IW3g9PR_ckX_sI-CALcv4Lt0USslvI0rqePqW9gVP7D7v") or None,
"price_change": _env("DISCORD_WEBHOOK_PRICE_CHANGE", "https://discord.com/api/webhooks/1488982573723025633/J864UL4vk_q9Rmj4i4wtkGfzB3nKAOc0y7jzBFDgUbhwg4XKm1Z7sWduqRc6x_ThWetc") or None,
"error": _env("DISCORD_WEBHOOK_ERROR", "https://discord.com/api/webhooks/1488983128641900657/RP5FRSWwbVaRAf7RdXPs66ETbY8ziI1ekIx7lrHqxp8n200KpzUiX_EylCxXBH5nJD3B") or None,
"captcha": _env("DISCORD_WEBHOOK_ERROR", "https://discord.com/api/webhooks/1488983128641900657/RP5FRSWwbVaRAf7RdXPs66ETbY8ziI1ekIx7lrHqxp8n200KpzUiX_EylCxXBH5nJD3B") or None,
},
# Override specific site + type combinations (highest priority)
# Use tuples: ("site", "type"): "webhook_url"
"overrides": {
# ("bestbuy", "restock"): "https://discord.com/api/webhooks/xxx/bestbuy-restocks",
# ("pokemoncenter", "new_drop"): "https://discord.com/api/webhooks/xxx/pokemon-drops",
},
}
# Enable/disable Discord notifications
NOTIFICATIONS_ENABLED = True # Set to False to disable all Discord alerts
NEW_DROP_NOTIFICATIONS = True # Set to False to silence new drop notifications
PRICE_CHANGE_NOTIFICATIONS = True # Set to False to silence price change notifications
SKIP_DUPLICATE_SKUS = True # Skip notifications for products we've already notified about
# Restock notification cooldown (prevents duplicate alerts for same product)
# Set to number of hours before a product can trigger another restock notification
RESTOCK_COOLDOWN_HOURS = 6 # Minimum hours between restock alerts for same product
# Discord Bot Token (for interactive bot commands)
# Create a bot at https://discord.com/developers/applications
# Required for !setlocation, !stores, !stock commands
# Set DISCORD_BOT_TOKEN in .env to override
DISCORD_BOT_TOKEN = _env("DISCORD_BOT_TOKEN", "MTQ4NjQ2ODM2NDkyMTczNzM3OQ.Gxl8pq.wIvK2eVbp1G0SJhW4XTYD3zopR1gohaNv5sxlQ")
# How often to check each site (in seconds)
CHECK_INTERVAL_SECONDS = 60
# Pagination settings - how many pages to scrape per site
# Set to 1 for fastest checks, higher for more thorough scraping
MAX_PAGES = {
"target": 1, # Each page has ~24 products
"bestbuy": 1,
"gamestop": 1,
"walmart": 1,
"pokemoncenter": 1,
}
# Sort by newest - ensures new drops appear first
SORT_BY_NEWEST = True
# Which sites to monitor
# Note: PokemonCenter has strong bot protection (Imperva) - may need manual workarounds
# Note: Walmart has aggressive bot protection (PerimeterX) - may need stealth mode
SITES_ENABLED = ["target", "gamestop", "bestbuy"] # Options: "pokemoncenter", "target", "gamestop", "bestbuy" (disabled - needs rework), "walmart"
# PokemonCenter URLs to monitor
POKEMON_CENTER_URLS = [
"https://www.pokemoncenter.com/category/tcg-cards?sort=relevance",
]
# Target URLs to monitor
TARGET_URLS = [
"https://www.target.com/s?searchTerm=pokemon+tcg",
]
# GameStop URLs to monitor
GAMESTOP_URLS = [
"https://www.gamestop.com/search/?q=pokemon+tcg&lang=en_US",
]
# Best Buy URLs to monitor
BESTBUY_URLS = [
"https://www.bestbuy.com/site/searchpage.jsp?st=pokemon+tcg",
]
# Walmart URLs to monitor
WALMART_URLS = [
"https://www.walmart.com/search?q=pokemon+tcg",
]
# Keyword filtering (disabled by default)
KEYWORD_FILTER_ENABLED = False
KEYWORDS = [
"chaos rising",
"booster",
"etb",
"elite trainer",
"booster bundle",
]
# Browser settings
HEADLESS = True # Set to False to see the browser (useful for debugging)
SLOW_MO = 0 # Milliseconds to slow down browser actions (for debugging)
# Chrome profile for PokemonCenter (optional - helps bypass bot detection)
# Set to your Chrome user data directory to use your real browser profile
# Windows: C:\Users\USERNAME\AppData\Local\Google\Chrome\User Data
# Linux: ~/.config/google-chrome
# Mac: ~/Library/Application Support/Google/Chrome
# Leave as None to use a fresh browser profile
# Set to None to use a fresh profile, or a path to use an existing profile
# Note: Chrome must be closed when using an existing profile
CHROME_USER_DATA_DIR = None # Disabled - causes issues with Playwright persistent context
# Use real Chrome instead of Playwright's Chromium (helps with bot detection)
USE_REAL_CHROME = True
# =============================================================================
# STEALTH MODE SETTINGS (for Pokemon Center and other protected sites)
# =============================================================================
# Use undetected-chromedriver instead of Playwright (better for Imperva/Cloudflare)
USE_STEALTH_BROWSER = True
# Stealth browser settings
STEALTH_HEADLESS = True # Set True for headless/no-display environments
GAMESTOP_HEADLESS = False # GameStop (Cloudflare) hard-blocks headless Chrome - must stay False
BESTBUY_HEADLESS = False # BestBuy detects headless and blocks GraphQL product loading - must stay False
STEALTH_SESSION_NAME = "pokemoncenter" # Name for cookie/session persistence
# Human-like behavior settings
MIN_CHECK_INTERVAL = 180 # Minimum seconds between checks for protected sites
MAX_CHECK_INTERVAL = 300 # Maximum seconds (will randomize between min/max)
HUMAN_DELAY_MIN = 2.0 # Minimum delay between actions (seconds)
HUMAN_DELAY_MAX = 5.0 # Maximum delay between actions (seconds)
# Proxy settings (optional but recommended for heavy use)
USE_PROXIES = False # Set to True to enable proxy rotation
# Configure proxies in proxies.json file
# Auto-solve CAPTCHA settings
CAPTCHA_WAIT_TIMEOUT = 120 # Seconds to wait for manual CAPTCHA solve
PAUSE_ON_CAPTCHA = True # Pause monitoring when CAPTCHA detected (requires manual solve)
# =============================================================================
# AUTO-BUY SETTINGS
# =============================================================================
# Credentials are loaded from .env — never put card/login data in this file.
# Copy .env.example to .env and fill in your details.
# Master kill switch — must be True AND the site must be in AUTO_BUY_SITES
AUTO_BUY_ENABLED = False
# Which sites to attempt auto-buy on (subset of SITES_ENABLED)
# Options: "target", "bestbuy", "gamestop"
AUTO_BUY_SITES: list[str] = []
# Dry-run: go through the entire checkout flow but stop before clicking Place Order
# Set to False only when you are ready to make real purchases
AUTO_BUY_DRY_RUN = True
# Price ceiling — skip auto-buy if detected price exceeds this (USD)
AUTO_BUY_MAX_PRICE = 60.00
# Maximum quantity to add to cart per product
AUTO_BUY_MAX_QUANTITY = 1
# Seconds to wait between browser actions during checkout (humanizes behavior)
AUTO_BUY_ACTION_DELAY_MIN = 0.8
AUTO_BUY_ACTION_DELAY_MAX = 2.0
# Logging
LOG_LEVEL = "INFO"
# Dashboard settings
DASHBOARD_HOST = "0.0.0.0" # Listen on all interfaces
DASHBOARD_PORT = 5000
DASHBOARD_DEBUG = False # Set to True for development
# Database settings
DATABASE_PATH = None # None = use default (stats.db in project root)
# =============================================================================
# NEWS AGGREGATION SETTINGS
# =============================================================================
# News sources configuration
NEWS_CONFIG = {
'twitter': {
'enabled': False, # Enable when you have API access
'bearer_token': 'YOUR_TWITTER_BEARER_TOKEN', # Get from https://developer.twitter.com
'accounts': [
'pokepullzhq', # Poke Pullz
'PokemonRestocks', # Pokemon TCG Restocks & News
'PokemonDealsTCG', # Pokemon Deals, Alerts & News!
'PokeNotifyX' # PokeNotify
],
'fetch_interval': 300 # 5 minutes (free tier: 1500 tweets/month)
},
'manual_sources': {
'enabled': True,
'sources': ['Poke Pullz Discord', 'PokePings Discord', 'Other']
},
'pokemon_official': {
'enabled': True,
'url': 'https://www.pokemon.com/us/pokemon-tcg-news/',
'fetch_interval': 3600 # 1 hour (official news updates less frequently)
}
}
# Auto-fetch news on dashboard start
NEWS_AUTO_FETCH = True
# Clean up old news articles after this many days
NEWS_RETENTION_DAYS = 30