Annie Mei is a Rust Discord bot that fetches anime and manga data from AniList and theme songs from MyAnimeList and Spotify. Users interact via Discord slash commands. This page focuses on the bot service codebase. For the self-hosted service layout, including the separate AniList OAuth companion service, see Self-hosting architecture.Documentation Index
Fetch the complete documentation index at: https://anniemei.app/llms.txt
Use this file to discover all available pages before exploring further.
Technology Stack
Annie Mei uses modern Rust ecosystem tools for building a reliable and performant Discord bot:| Component | Technology | Purpose |
|---|---|---|
| Language | Rust 2024 Edition | Core programming language |
| Discord | Serenity 0.12 | Discord API client and gateway |
| Database | PostgreSQL + Diesel ORM | User data persistence and schema management |
| Cache | Redis | Fast API response caching |
| HTTP | Reqwest (blocking) | External API requests (AniList, MAL) |
| Async | Tokio | Asynchronous runtime for event handling |
| Logging | tracing + tracing-subscriber | Structured logging and observability |
| Errors | Sentry | Error tracking and monitoring |
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:Async/Blocking Architecture
Annie Mei uses a hybrid async/blocking pattern:- Async: Discord interactions via Serenity and Tokio
- Blocking: External API calls via blocking reqwest
- Bridge:
tokio::task::spawn_blockingwraps blocking operations
Example Pattern
Entry Points
The bot’s execution flow starts insrc/main.rs:
-
Initialization (
main.rs:116-241)- Parse CLI arguments
- Initialize Sentry error tracking
- Set up tracing/logging
- Run database migrations
- Create Discord client
-
Event Handler (
main.rs:52-112)interaction_create- Routes slash commands to handlersready- Registers slash commands with Discord
-
Command Routing (
main.rs:66-84)- Matches command names to handler functions
- Configures tracing spans for observability
Environment Configuration
The bot requires these environment variables to run:| Variable | Description |
|---|---|
DISCORD_TOKEN | Bot token from Discord Developer Portal |
SENTRY_DSN | Sentry project DSN for error tracking |
ENV | Environment name (dev/staging/prod) |
DATABASE_URL | PostgreSQL connection string |
REDIS_URL | Redis connection string |
AUTH_SERVICE_BASE_URL | Auth service origin for OAuth start URLs |
SPOTIFY_CLIENT_ID | Spotify API client ID |
SPOTIFY_CLIENT_SECRET | Spotify API client secret |
MAL_CLIENT_ID | MyAnimeList API client ID |
OAUTH_CONTEXT_SIGNING_SECRET | Shared secret for OAuth context signing |
USERID_HASH_SALT | Salt for hashing Discord user IDs in logs |
OAUTH_CONTEXT_TTL_SECONDS | Optional: OAuth context expiry in seconds (default 300) |
SENTRY_TRACES_SAMPLE_RATE | Optional: Sentry trace sampling (0.0-1.0) |
SERVER_PORT | Optional: health server port (default 8080) |
GEMINI_API_KEY | Optional: enables Gemini/OpenAI-compatible LLM features |
LLM_MODEL | Optional: overrides the default LLM model |
LLM_BASE_URL | Optional: overrides the default LLM base URL |
src/utils/statics.rs for constant definitions.