ROIBot / README.md
Codex
Use public Dropbox folder discovery for Circa
ece5cde
---
title: ROI Bet Tracking Bot
emoji: 📈
colorFrom: blue
colorTo: green
sdk: docker
app_port: 7860
short_description: Discord bet tracker with per-user ROI stats.
---
# ROI Bet Tracking Discord Bot
A Discord bot for manually tracking bets and ROI per user. Each Discord user gets their own independent bet history, sport-tagged analytics, exports, and summary charts.
## Features
- `/bet` logs one bet privately using sportsbook and sport dropdowns
- `/bulkadd` logs multiple bets privately for one sportsbook and one sport
- `/editbet` updates an open bet privately
- `/deletebet` soft deletes a bet privately without wiping audit history
- `/resolve` grades a bet as `win`, `loss`, or `void`
- `/resolveall` grades multiple bet IDs to the same result
- `/bankroll` manages starting bankroll and unit settings
- `/roi` posts a public trend-first ROI view with filters and chart
- `/bets` posts a public filtered ledger with pagination
- `/summary` posts a public record-first summary with chart
- `/books` shows ROI and win rate by sportsbook
- `/sports` shows ROI and win rate by sport
- `/export` exports a filtered CSV of a user’s bets privately
- `/commands` posts a public command reference embed
- `/welcome` posts a public welcome embed and tags everyone for admins only
- CockroachDB / Postgres-compatible persistence via `DATABASE_URL`
- Docker-ready for Hugging Face Spaces
## Setup
1. Install dependencies:
```powershell
npm.cmd install
```
2. Copy `.env.example` to `.env` and add your bot config:
```env
DISCORD_TOKEN=your_token_here
GUILD_ID=optional_guild_id
DATABASE_URL=postgresql://username:password@host:26257/database?sslmode=require
ADMIN_ROLE_NAME=Admin
```
3. Start the bot:
```powershell
npm.cmd start
```
## Notes
- Node.js 24+ is required.
- The bot stores data in your remote CockroachDB database.
- `/welcome` is restricted to members with the Discord role name set in `ADMIN_ROLE_NAME`.
- If `GUILD_ID` is set, slash commands register to that guild for faster updates. Otherwise they register globally.
- Set `DATABASE_URL`, `DISCORD_TOKEN`, and `ADMIN_ROLE_NAME` as Hugging Face Space secrets.
- The Docker Space exposes a tiny health endpoint on port `7860` while the Discord bot runs in the same container.
## Hugging Face Deployment
1. Create a new Hugging Face Space using the `Docker` SDK.
2. Push this repository to that Space.
3. Add these Space secrets:
- `DISCORD_TOKEN`
- `DATABASE_URL`
- `ADMIN_ROLE_NAME`
- `GUILD_ID` (optional)
4. Let the Space build and start.
The app will create and backfill its tables automatically on startup if they do not exist yet.
## Bet Input Tips
The `/bet` command requires sportsbook and sport dropdowns first, then the modal asks for:
```text
prop: Luka Doncic over 29.5 points
odds: -115
stake: $25
```
The `/bulkadd` modal accepts one bet per line in this format:
```text
Bryan Rocchio 1+ HR | +1450 | $5
3 leg parlay | +1452 | $5
```
## Oracle Cloud Always Free Deployment
This bot is a good fit for an Oracle Cloud Always Free Ubuntu VM because it:
- runs on Node.js `24+`
- uses your remote CockroachDB/Postgres-compatible database
- does not require local persistent bet storage
Recommended deployment shape:
- Oracle Compute VM with Ubuntu LTS
- native Node runtime
- `systemd` for auto-restart and boot persistence
- SSH exposed publicly on port `22` only
Deployment assets included in this repo:
- `docs/oracle-always-free.md`
- `deploy/oracle/roibot.service`
- `deploy/oracle/roibot.env.example`
## Market Scanner
Market scanning is admin-controlled and built into the same long-running bot process.
- `/scanstatus` shows scanner health and last-run information
- `/scanrun` runs the Circa disagreement scanner manually
- `/scanreport` posts the morning discrepancy and width reports on demand
- `/circatest` previews Circa OCR parsing
Environment variables for scanner features:
- `ODDS_API_KEY`
- `ODDS_API_BASE_URL`
- `ODDS_API_SPORT_KEY`
- `ODDS_API_REGIONS`
- `ODDS_API_MARKETS`
- `CIRCA_DROPBOX_URL` (public shared folder link)
- `SCAN_REPORT_CHANNEL_ID`
- `SCAN_ALERT_CHANNEL_ID`
- `SCAN_MORNING_TIME`
- `SCAN_TIMEZONE`
- `SCAN_MIN_BOOKS`
- `SCAN_DISAGREEMENT_THRESHOLD`
- `SCAN_ALERT_COOLDOWN_MINUTES`
- `SCAN_FREQUENCY_MINUTES`