The official RetroAchievements Discord bot.
RABot is the official RetroAchievements Discord bot. It serves the RetroAchievements community with various utility commands, polls, and integration features.
RABot utilizes:
- The Bun runtime for high speed, low memory footprint, and native TS execution
- TypeScript for static type safety
- Discord.js for tight integration with Discord
- Drizzle ORM with SQLite for data persistence
- @retroachievements/api for web API calls
- Bun 1.3.10+
- A Discord application ID, bot token, and RetroAchievements Web API key
Clone the repository and install dependencies:
git clone https://github.com/RetroAchievements/RABot-Next.git
cd RABot-Next
bun installCopy the example environment file and fill in your values:
cp .env.example .envThen edit .env with your configuration:
DISCORD_TOKEN- Your bot's token from Discord Developer PortalDISCORD_APPLICATION_ID- Your bot's application ID from Discord Developer PortalRA_WEB_API_KEY- Your RetroAchievements Web API keyRA_CONNECT_API_KEY- RetroAchievements Connect API key required for/memachievement ID/URL lookups and code notesRA_CONNECT_API_USER- RetroAchievements Connect API username (default:RABot)YOUTUBE_API_KEY- Your YouTube Data API v3 key (optional, for/ganlongplay searches)MAIN_GUILD_ID- Discord guild ID for the main RetroAchievements server (optional, but recommended for production guild authorization)WORKSHOP_GUILD_ID- Discord guild ID for the RetroAchievements Workshop server (required for Workshop-only features)CHEAT_INVESTIGATION_CATEGORY_ID- Category ID required for RACheats/pingteam pingrestrictionsUWC_VOTING_TAG_ID- Forum tag ID for active UWC polls (optional)UWC_VOTE_CONCLUDED_TAG_ID- Forum tag ID for completed UWC polls (optional)UWC_FORUM_CHANNEL_ID- Forum channel ID for UWC auto-detection (optional)DEV_CHANNELS- Comma-separated channel IDs where/memmay show code notes (optional)AUTO_PUBLISH_CHANNEL_IDS- Comma-separated list of announcement channel IDs to auto-publish from (optional)NODE_ENV- Environment mode:developmentorproduction(default:development)LOG_LEVEL- Logging level:trace,debug,info,warn,error,fatal(default:debugin dev,infoin prod)
Initialize the database:
bun run db:generate # Generate migration files
bun run db:migrate # Apply migrations
bun run db:seed # Seed default teams (optional)Deploy the application's global slash commands:
bun run deploy-commandsThis needs to be run:
- When you first set up the bot
- Whenever you add or modify slash commands
- After major Discord.js updates
bun run dev # Runs with auto-restart on file changesbun run start # Standard runFor production deployments, the bot is automatically deployed via Forge when changes are merged to the main branch. The bot runs under a process supervisor on the production server.
bun run dev- Run in development mode with hot reloadbun run start- Run in production modebun run deploy-commands- Deploy slash commands to Discordbun run db:generate- Generate database migrationsbun run db:migrate- Apply database migrationsbun run db:seed- Seed default teamsbun run format- Format code with oxfmtbun run format:check- Check formatting without writingbun run lint- Run oxlintbun run lint:fix- Run oxlint with auto-fixbun run tsc- Run TypeScript type checking (via tsgo)bun run test- Run all testsbun run test:watch- Run tests in watch modebun run verify- Format, lint-fix, type check, and test locallybun run ci- Run CI-safe format check, lint, type checking, and tests
RABot is slash-command only. The legacy ! prefix commands were removed because Discord revoked the bot's Message Content privileged intent, which made reading prefixed messages impossible.
/topic- Display the current channel topic/contact- Show contact information for various RA teams/status- Display bot status and statistics/poll- Create a simple poll (up to 10 options)/tpoll- Create a timed poll that automatically closes/gan <game-id>- Generate achievement news template/gan2 <game-id>- Generate pretty achievement news template with colors/pingteam- Team management system (Workshop server only)/pingteam ping <team>- Ping all members of a team/pingteam add <team> <user>- Add user to team/pingteam remove <team> <user>- Remove user from team/pingteam create <name>- Create a new team
/uwc- Create an Unwelcome Concept poll (Workshop server only, requires UWC role or admin, auto-manages forum tags)- Auto-detection: When a new UWC thread is created in the configured forum channel with format
12345: Achievement Title (Game Name), the bot automatically posts links to previous discussions for that achievement
- Auto-detection: When a new UWC thread is created in the configured forum channel with format
/dadjoke- Get a random dad joke/frames <input>- Convert between time and frames at different frame rates/rules [rule]- Display the server rules, a single rule, or the Code of Conduct link/mem <input>- Parse a MemAddr string and show achievement logic (accepts an achievement ID, URL, or raw MemAddr)
src/
├── slash-commands/ # Modern slash commands (*.command.ts files)
├── config/ # Configuration and constants
├── database/ # Database setup and schemas
├── handlers/ # Event handlers
├── models/ # TypeScript interfaces and types
├── services/ # Business logic services
├── test/ # Shared test database and mocks
└── utils/ # Utility functions and logging
Contributions are welcome! Please see our Contributing Guide for detailed information on:
- Setting up your development environment
- Development workflow and standards
- Submitting pull requests
- Code style and project structure
For quick questions, feel free to open an issue or ask in our Discord server!