# SteamSelfGifter [![Tests](https://github.com/kernelcoffee/SteamSelfGifter/actions/workflows/test.yml/badge.svg)](https://github.com/kernelcoffee/SteamSelfGifter/actions/workflows/test.yml) [![Docker](https://github.com/kernelcoffee/SteamSelfGifter/actions/workflows/docker-publish.yml/badge.svg)](https://github.com/kernelcoffee/SteamSelfGifter/actions/workflows/docker-publish.yml) [![Python Version](https://img.shields.io/badge/python-3.14-blue.svg)](https://www.python.org/downloads/) [![License](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE) SteamSelfGifter is an automated bot for entering Steam game giveaways on SteamGifts.com. It features a modern web interface for managing your giveaway entries, tracking wins, and configuring automation settings. ![SteamSelfGifter dashboard](docs/screenshots/dashboard.png) ## Features - **Web Dashboard**: Modern React-based UI for monitoring and control - **Priority List**: An ordered list (up to three items) of wishlist, DLC and ending-soon giveaways decides what is entered first. Wishlist and DLC items skip the filters; ending-soon (window 5 minutes to 1 week, default 60 minutes, soonest first) obeys them. An empty list means everything obeys the filters, in price order. The default is wishlist only - **Smart Auto-join**: Automatically enters giveaways based on customizable criteria: - Minimum price threshold - Minimum review score - Minimum number of reviews - Included and excluded genres: only enter games in genres you list, and skip games in genres you don't want (exclusion wins when a genre is in both lists; wishlist and DLC giveaways are still entered when they are in your priority list). Genres come from the Steam store API; Steam's user-voted tags are not available through it, so filtering is by genre only - **Safety Detection**: Detects and avoids trap/scam giveaways with background safety checks - **Win Tracking**: Track your wins and win rate statistics - **Real-time Updates**: WebSocket-based live notifications - **Analytics Dashboard**: View entry statistics and trends - **Activity Logs**: View detailed logs of all bot activity ## Screenshots **Browse and filter giveaways** — by review score, win chance, time remaining, and safety, with live entry counts and win odds on every card: ![Giveaways page](docs/screenshots/giveaways.jpg) **Analytics** — entry statistics, giveaway coverage, and win rate at a glance: ![Analytics page](docs/screenshots/analytics.png) ## Quick Start ### Docker (Recommended) ```bash # Using the pre-built image from GitHub Container Registry docker run -d \ --name steamselfgifter \ -p 8080:80 \ -v steamselfgifter-data:/config \ ghcr.io/kernelcoffee/steamselfgifter:latest # Access the web interface at http://localhost:8080 ``` #### Image tags | Tag | Meaning | |-----|---------| | `latest` | Last tagged release (stable channel) | | `X.Y.Z`, `X.Y`, `X` | Specific release versions | | `nightly` | Latest master build, also rebuilt daily for base-image updates | | `` | Exact commit builds | Releases are cut by pushing a git tag: `git tag v2.0.0 && git push origin v2.0.0`. Images are only published after the full test suite passes. Or with Docker Compose: ```bash # Clone the repository git clone https://github.com/kernelcoffee/SteamSelfGifter.git cd SteamSelfGifter # Pulls the published image and starts it docker compose up -d # ...or build from source instead of pulling docker compose up -d --build # Access the web interface at http://localhost:8080 ``` > **Note:** after pulling a new image or rebuilding, use > `docker compose up -d --force-recreate` so the running container is > actually replaced (some engines, e.g. podman-compose, keep the old > container otherwise). #### Running the backend as a non-root user (Docker) By default everything in the container runs as root, which is fine for rootless podman (container-root maps to your own host user). On real Docker, set `PUID`/`PGID` (see the commented lines in `docker-compose.yml`) to run the backend as that uid/gid — `/config` is chown'd accordingly on startup so the database and logs end up owned by your host user instead of root. ### Development with Docker `docker-compose.dev.yml` runs both halves from source with auto-reload (uvicorn `--reload`, Vite HMR) — the production `docker-compose.yml` is untouched: ```bash docker compose -f docker-compose.dev.yml up # Frontend (proxies /api and /ws): http://localhost:5173 # Backend API directly: http://localhost:8000 ``` Dev data lives in `./config-dev` (separate from the production `./config`); dependencies are cached in named volumes, so only the first start installs. ### Manual Installation #### Backend ```bash cd backend python -m venv .venv source .venv/bin/activate # On Windows: .venv\Scripts\activate pip install -e . # Start the backend cd src uvicorn api.main:app --host 0.0.0.0 --port 8000 ``` #### Frontend ```bash cd frontend npm install npm run dev # Development server at http://localhost:5173 ``` ## Configuration 1. Open the web interface 2. Go to **Settings** 3. Enter your SteamGifts PHPSESSID (see below) 4. Configure your preferences: - Enable/disable automation - Set auto-join criteria (min price, score, reviews) - Optionally include or exclude Steam genres (**Included genres** / **Excluded genres**, up to 50 each, picked from the genres of cached games or typed in). Games cached before this feature get their genres over the next refresh cycles - Set the **priority list**: reorder or remove wishlist, DLC and ending-soon (threshold 5 to 10080 minutes, default 60); the Filters card previews how many giveaways would be entered - Enable safety check for trap detection ### How to get your PHPSESSID 1. Sign in to [SteamGifts](https://www.steamgifts.com) 2. Open your browser's developer tools (F12) 3. Go to the **Application** tab (Chrome) or **Storage** tab (Firefox) 4. Find **Cookies** → `www.steamgifts.com` 5. Copy the `PHPSESSID` value 6. Paste it in the Settings page ## Security **The web interface and API have no authentication** — anyone who can reach the port controls the bot and can read your SteamGifts session. The app is designed to run on a trusted home network (LAN) only: - Don't expose the port to the internet. If you need remote access, put it behind a reverse proxy with authentication (Authelia, basic auth, ...) or access it over a VPN/tunnel (WireGuard, Tailscale, ...). - Your `PHPSESSID` is stored in plain text in the SQLite database inside `/config` (or `./config` with the provided compose file). Treat that directory as a secret: don't commit it, don't share it. - The `PHPSESSID` cookie is your logged-in SteamGifts session. Anyone who obtains it can act as you on SteamGifts until it expires. ## Architecture ``` SteamSelfGifter/ ├── backend/ # FastAPI REST API + SQLite │ ├── src/ │ │ ├── api/ # REST API endpoints │ │ ├── core/ # Configuration, logging, exceptions │ │ ├── db/ # Database session management │ │ ├── models/ # SQLAlchemy ORM models │ │ ├── repositories/ # Data access layer │ │ ├── services/ # Business logic │ │ ├── utils/ # SteamGifts/Steam API clients │ │ └── workers/ # Background job scheduler │ └── tests/ # Test suite (pytest) ├── frontend/ # React + TypeScript + Vite + TailwindCSS │ └── src/ │ ├── components/ # Reusable UI components │ ├── hooks/ # React Query hooks │ ├── pages/ # Page components │ └── services/ # API client ├── docs/ # Documentation ├── Dockerfile # Multi-stage single-container build └── docker-compose.yml # Docker deployment configuration ``` ## API Documentation Once the backend is running, visit: - Swagger UI: http://localhost:8000/docs - ReDoc: http://localhost:8000/redoc When running via Docker, the API is available at: - http://localhost:8080/api/v1/ ## Development ### Running Tests ```bash # Backend tests cd backend pip install -e ".[test]" pytest # Frontend build/lint cd frontend npm run lint npm run build ``` ### Database Migrations The project uses Alembic for database migrations. Migrations run automatically on startup. The SQLite database lives in the runtime data directory: `/config` inside the container (mounted from `./config` by the compose file), or `./data` relative to the working directory when running the backend locally. ```bash # Create a new migration after model changes cd backend/src alembic revision --autogenerate -m "description" # Apply migrations manually alembic upgrade head ``` ## Contributing We welcome contributions! Please see our [Contributing Guidelines](CONTRIBUTING.md) for details. The maintainer develops this project with [Conclave](https://github.com/kernelcoffee/Conclave), an agent team for Claude Code that plans, reviews and tests each change against the project's conventions. Contributions written by hand are welcome and go through the same review. ## License This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details. ## Disclaimer This bot is for educational purposes only. Please ensure you comply with SteamGifts' terms of service and use this tool responsibly.