Automatically mine timed Twitch Drops without streaming video or audio.
Twitch Drops Miner is a low-bandwidth, headless application that discovers eligible campaigns, selects an appropriate live channel, and tracks drop progress from a web dashboard. It sends Twitch watch events without downloading the stream itself.
- Low-bandwidth mining — progresses timed drops without downloading video or audio
- Automatic campaign discovery — detects active and upcoming drop campaigns
- Smart channel selection — prioritizes eligible channels, preferred games, and viewers
- Drop-name ignore rules — excludes unwanted reward names and dependent branches
- Persistent sessions — saves OAuth login state between runs
- Web dashboard — manages campaigns, channels, inventory, settings, and login status
- Optional dashboard password — protects the web UI, API, and live connections with one password
- Drop history — records every claimed drop locally (date, game, campaign, rewards) with a filterable History tab, aggregated stats, and one-click Export CSV
- Telegram notifications — sends an alert when a drop is claimed, including claims found during startup and inventory refresh
- Headless deployment — runs locally, remotely, or in Docker without a desktop GUI
- Safe rendering — builds dynamic translated content with DOM APIs instead of raw HTML
Docker stores persistent application data in /app/data. The command below binds that
directory to ./data on the host:
docker run -d \
--name twitch-drops-miner \
-p 8080:8080 \
-v "${PWD}/data:/app/data" \
--restart unless-stopped \
rangermix/twitch-drops-miner:latestOpen http://localhost:8080.
From the repository root, build and start the included
docker-compose.yml:
docker compose up -d --buildSource installations require Python 3.12 or newer and
uv:
uv sync
uv run main.pyThen open http://localhost:8080.
- Log in with your Twitch account through the OAuth device flow.
- Wait for the miner to discover available campaigns.
- Choose the games you want to prioritize. You can also search for a game, select Add Game, and then select Reload.
- Leave the miner running while it selects eligible channels and tracks drop progress.
In Games to Watch, drag games to reorder them or type a priority number to move a game directly. Priority 1 is highest; out-of-range numbers are clamped to the list ends. Blank or fractional values leave the order unchanged. Priority controls and remove buttons use translated labels for screen readers.
Special Events and IRL campaigns can be mined on their listed participating channels even when those channels stream another category or lack a drops-enabled flag. Include the campaign's category in Games to Watch. Channels must be live and eligible; campaigns without an enabled participating-channel list still require a matching category. Channels streaming categories outside Games to Watch retain the lowest automatic priority. When the watched channel goes offline or becomes ineligible, another eligible participant can replace it even at that same fallback priority.
Inventory filters combine Active, Upcoming, and Expired as alternatives. Not Linked narrows that status result, while fully claimed campaigns stay hidden until Finished is selected. Zero-minute subscription rewards are omitted from the Inventory and Wanted Drops Queue because they cannot be earned by watching. Individually expired and non-mineable rewards are also omitted from the queue, while upcoming and sequential rewards remain visible; successful claims refresh the queue immediately. The channel list matches game names case-insensitively and keeps the actively watched channel visible while game settings are changing. Campaign totals and claim messages count only rewards that can be earned by watching. Consecutive identical no-active-campaign console prompts are collapsed until another console message appears.
Ignored Drop Keywords in Settings is empty by default. Enter one literal substring per line; surrounding whitespace and blank lines are removed, and duplicates are collapsed case-insensitively while preserving the first spelling. Matching is also case-insensitive. A matching drop and every unclaimed branch that depends on it are ignored dynamically. Prerequisite-only branches with no remaining mineable reward are shown as skipped, while a prerequisite shared by an allowed reward remains mineable. Ignored and skipped drops are never reported as claimed. This controls what the miner intentionally targets, but Twitch may still grant simultaneous progress to an ignored reward while another reward advances.
In Settings, Clear All Cache calls POST /api/cache/clear to discard local
campaign, channel, and other derived miner state while preserving your OAuth login and
settings, then reloads the data from Twitch. This is a recovery and diagnostic action;
it cannot correct inaccurate campaign metadata returned by Twitch.
Password protection is off by default. In Settings → Dashboard password, enter and confirm a password (8–1024 characters), then select Enable password protection. This password is separate from your Twitch account; no username is needed. Enabling it immediately locks out other browsers. Mining continues while the dashboard is locked.
If the login page shows a temporary request error, you can still enter your password and select Log in to retry without reloading the page.
- Login uses an HttpOnly, SameSite=Strict session cookie by default. Select Remember me for 30 days for a persistent cookie with a fixed 30-day expiry. Sessions survive miner restarts, and all sessions have a maximum server lifetime of 30 days. Browser session-restore features may preserve session cookies; use Log out to explicitly revoke a session on shared devices.
- Change password requires the current password and signs out all other sessions. The browser making the change receives a new session cookie.
- Disable protection and clear password also requires the current password. It deletes the stored password hash and all sessions, making the dashboard public again.
- Passwords are salted and hashed with scrypt; only digests of random session tokens are stored. Login and password-setting attempts are rate limited (5 per minute per client IP, 30 per minute overall). Auth credentials never enter normal settings or logs.
- The UI, application API, and Socket.IO are protected.
/healthzstays public and returns only a health flag for Docker checks. Login resources and auth status are public. API writes requireX-TDM-Request: 1; browser clients send it automatically. Cross-origin writes and Socket.IO connections are rejected.
Remote access: use HTTPS through a reverse proxy to encrypt passwords and cookies.
Cookies receive the Secure flag over HTTPS. Preserve the original Host header and configure
Uvicorn to trust forwarded protocol/IP headers only from your proxy (for example via
FORWARDED_ALLOW_IPS). A proxy that hides client IPs shares the per-IP login limit.
Configure protection on a trusted network before making the dashboard publicly reachable.
Run one miner process per data directory.
Forgotten password: stop the miner, restrict network access to its port, delete only
data/web_auth.json (Docker: /app/data/web_auth.json in the mounted data directory),
then restart and set a new password in Settings before restoring remote access. This
resets dashboard authentication without deleting Twitch cookies or other settings.
Keep the data directory private. A malformed auth file stops startup rather than silently
turning off protection. Clear All Cache preserves dashboard authentication.
The History tab logs every successfully claimed drop to data/drop_history.json.
Filter the table by game name or "claimed on or after" date, view per-game and per-month
stats, or download the current view as a CSV file (UTF-8 BOM so Excel opens it cleanly).
History controls are translated in all supported languages. The date filter starts at
midnight UTC on the selected date; displayed claim times use your browser’s local timezone.
CSV downloads support Unicode game names. Existing Twitch claims are not backfilled.
The Clear button deletes all locally recorded history; this does not affect your
Twitch account or already-claimed rewards.
In Settings → Telegram Notifications, enter a bot token from @BotFather and your chat ID. Start a conversation with your bot before selecting Test Connection. The Help tab contains the setup steps. A successful test sends a test message and saves the credentials; Save Settings saves without sending a message. A failed test or save displays an error.
The bot token is stored on the server and is never returned to the browser. Leave the token field blank to reuse it when testing or changing the chat ID. To disable notifications, clear the chat ID and save. Enter a new chat ID to enable notifications again.
Notifications cover new successful claims from both live events and inventory checks. Repeated events for an already claimed drop do not send another alert. Telegram delivery failures do not undo a Twitch claim, and failed notifications are not retried.
Note
Your Twitch account must be linked to the relevant game accounts. Review your Twitch Drops campaigns before mining.
Warning
Avoid watching Twitch manually with the same account while the miner is running. Simultaneous viewing can cause drop-progress desynchronization.
- Docker data is stored inside the container at
/app/data; the examples persist it to./dataon the host. - Source installations store persistent data in the repository's
data/directory. - Logs can be persisted separately by mounting
./logs:/app/logs.
See CONTRIBUTING.md for issue reporting, development setup,
pull requests, required unit and regression checks, and independent adversarial review.
Coding agents must follow the mandatory workflow in AGENTS.md, also
available through the CLAUDE.md and GEMINI.md symlinks. The pull request template
records validation and review evidence.
Contributors are credited automatically when their pull requests are merged into main.
| Contributor | Merged pull requests |
|---|---|
| @birdhimself | #41 |
| @capkz | #70 |
| @EthanBlazkowicz | #33 |
| @Klages | #94 · #95 |
| @Knight-sys | #3 |
| @rangermix | #1 · #2 · #7 · #8 · #9 · #13 · #20 · #24 · #29 · #32 · #45 · #74 · #79 · #80 · #84 · #86 · #88 · #93 · #89 · #90 · #91 · #92 · #104 · #105 |
| @Sean-Destefano | #49 |
| @SimpliAj | #72 |
| @Stein-N | #71 |
| @vurmil | #12 · #17 · #18 · #100 |
If Twitch Drops Miner saves you time or bandwidth, you can support the project by:
- starring the repository
- reporting an issue or submitting a pull request
- buying the maintainer a coffee
This project is a modern fork of DevilXD/TwitchDropsMiner, created by @DevilXD. You can support the original author through Buy Me a Coffee or Patreon.
Original project and translation credits
- Arabic — @Bamboozul
- Chinese (Simplified) — @Suz1e, @wwj010, and @zhangminghao1989
- Chinese (Traditional) — @Ricky103403 and @LusTerCsI
- Czech — @nwvh
- Danish — @Kjerne
- French — @roobini-gamer and @Calvineries
- German — @ThisIsCyreX
- Hungarian — @centipederat
- Indonesian — @Eriza-Z
- Italian — @casungo
- Japanese — @ShimadaNanaki
- Polish — @Patriot99, co-authored with @DevilXD
- Portuguese — @zarigata
- Russian — @Sergo1217 and @kilroy98
- Spanish — @Shofuu
- Turkish — @alikdb
- Ukrainian — @Nollasko and @kilroy98
Repository instructions for all coding agents live in AGENTS.md.
CLAUDE.md and GEMINI.md are relative symlinks to that file; edit AGENTS.md to
update the shared guidance.
This fork is maintained with AI-assisted development tools. Changes are validated through
automated tests and code-quality checks, but users should still review updates before
deploying them. The validation suite includes GraphQL watch events and batched channel
discovery, alongside settings, full-locale translation schema and placeholder checks,
and frontend safety checks. Use the software
responsibly. Release automation verifies that the runtime, package, and lockfile versions
match before publishing tags and Docker images. Docker validation and release jobs use
the same pinned, Node-24-native Buildx and image-build action releases.
The suite also covers ignored-keyword normalization, dependency branches, the combined
expiry/ignore Wanted Queue guard, watch selection, API persistence, translated placeholder
parity, frontend rendering, and the claimed-drop history store with CSV export and API
endpoints. Any web/static/app.js or web/static/styles.css change
must go through the release workflow so the application version and browser asset cache key
are bumped before deployment.
Telegram regression coverage includes Help translation rendering, saved-token reuse, disabling notifications, failed saves, claim deduplication, and mocked Telegram transport errors. From the activated environment, run:
python -m pytest tests/test_telegram_frontend.py tests/test_telegram_api.py tests/test_telegram_integration.pyNo real Telegram messages are sent by these tests.
Games to Watch supports Enter to add an exact or unique partial match. Ambiguous searches ask for a more specific name. Manual names and Deselect All require a confirmation; Escape cancels and keyboard focus stays in the dialog. Select All retains the existing priority order and manual entries, adding missing games only.
