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
- Pino for structured logging with command analytics
- Bun 1.2.18+
- A Discord bot token
Clone the repository and install dependencies:
git clone https://github.com/RetroAchievements/RABot-Next.git
cd RABot-Next
bun install
Copy the example environment file and fill in your values:
cp .env.example .env
Then 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 PortalLEGACY_COMMAND_PREFIX
- Command prefix for legacy commands (default:!
)RA_WEB_API_KEY
- Your RetroAchievements Web API keyYOUTUBE_API_KEY
- Your YouTube Data API v3 key (optional, for/gan
longplay searches)MAIN_GUILD_ID
- Discord guild ID for the main RetroAchievements serverWORKSHOP_GUILD_ID
- Discord guild ID for the RetroAchievements Workshop serverUWC_VOTING_TAG_ID
- Forum tag ID for active UWC polls (optional)UWC_VOTE_CONCLUDED_TAG_ID
- Forum tag ID for completed UWC polls (optional)AUTO_PUBLISH_CHANNEL_IDS
- Comma-separated list of announcement channel IDs to auto-publish from (optional)NODE_ENV
- Environment mode:development
orproduction
(default:development
)LOG_LEVEL
- Logging level:trace
,debug
,info
,warn
,error
,fatal
(default:debug
in dev,info
in prod)
Initialize the database:
bun db:generate # Generate migration files
bun db:migrate # Apply migrations
bun db:seed # Seed default teams (optional)
After adding your bot to a server, deploy the slash commands:
bun deploy-commands
This needs to be run:
- When you first set up the bot
- Whenever you add or modify slash commands
- After major Discord.js updates
bun dev # Runs with auto-restart on file changes
bun start # Standard run
For 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 dev
- Run in development mode with hot reloadbun start
- Run in production modebun deploy-commands
- Deploy slash commands to Discordbun db:generate
- Generate database migrationsbun db:migrate
- Apply database migrationsbun lint
- Run ESLintbun lint:fix
- Run ESLint with auto-fixbun tsc
- Run TypeScript type checkingbun test
- Run all testsbun test:watch
- Run tests in watch modebun verify
- Run lint, type checking, and tests (comprehensive check)
RABot is transitioning to slash commands! When you use a legacy prefix command (e.g., !gan
), you'll see a migration notice encouraging you to use the modern slash command version (e.g., /gan
). The legacy command will still work during the transition period.
/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 (admin only)/pingteam remove <team> <user>
- Remove user from team (admin only)/pingteam list <team>
- List team members/pingteam create <name>
- Create a new team (admin only)
/uwc
- Create an Unwelcome Concept poll (Workshop server only, auto-manages forum tags)/dadjoke
- Get a random dad joke/frames <input>
- Convert between time and frames at different frame rates
The bot still supports the following legacy prefix commands (all prefixed with !
by default):
!topic
- Display the current channel topic!rule [number]
- Display server rules!contact
- Show contact information for various RA teams!poll
- Create a simple poll!tpoll
- Create a timed poll!gan <game_id>
- Generate achievement news template!mem <achievement_id|achievement_url|memaddr>
- Parse MemAddr strings and show achievement logic!dadjoke
- Get a random dad joke!frames <time|frames> [fps]
- Convert between time and frames at different frame rates
src/
├── commands/ # Legacy prefix commands (*.command.ts files)
├── slash-commands/ # Modern slash commands (*.command.ts files)
├── config/ # Configuration and constants
├── database/ # Database setup and schemas
├── handlers/ # Message and event handlers
├── models/ # TypeScript interfaces and types
├── services/ # Business logic services
└── 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!