Technology Stack
Annie Mei uses modern Rust ecosystem tools for building a reliable and performant Discord bot:Project Layout
The codebase follows a modular structure organized by functionality:Commands Directory
Each command is organized as a module insrc/commands/. Example structure:
Models Directory
Data structures for API responses and database models:Utils Directory
Shared functionality and external integrations:Database access
Annie Mei uses SQLx for PostgreSQL queries. The bot shares a database with the auth service, reads from the auth-service-ownedannie_auth.oauth_credentials table, and owns settings tables under the annie_mei schema.
The bot previously used Diesel ORM. The current bot uses SQLx migrations at startup for
annie_mei.user_settings and annie_mei.guild_settings. OAuth schema migrations still live in the companion auth service repo and run during auth-service startup.Entry Points
The bot’s execution flow starts insrc/main.rs:
-
Initialization (
main.rs)- Parse CLI arguments (including a
hashsubcommand) - Install Rustls crypto provider
- Initialize Sentry error tracking
- Set up tracing/logging
- Create SQLx connection pool
- Run bot-owned SQLx migrations
- Create Discord client with data (pool, LLM client, OAuth config)
- Parse CLI arguments (including a
-
Event Handler (
main.rs)interaction_create- Routes slash commands to handlersready- Registers slash commands with Discord
-
Command catalog and routing (
commands/mod.rs)- Uses one
BotCommandcatalog for command names, Discord definitions, and runtime dispatch - Configures tracing spans for observability
- Commands:
ping,help,songs,manga,anime,search,recommend,character,studio,register,unregister,whoami,settings
- Uses one
-
Protocol integration tests (
tests/discord_plumbing.rs)- Deserialize synthetic Discord interactions into Serenity models
- Send Serenity requests to a local mock HTTP server
- Verify immediate and deferred interaction response plumbing without external credentials
Environment Configuration
The bot requires these environment variables to run:
See
src/utils/statics.rs for constant definitions.