EN | 中文
AniAvatar, appearing on Discord as Minori, started as an anime profile-picture search bot and grew into a complete community platform.
It combines intelligent anime image discovery with persistent progression, rendered profile cards, server economies, interactive games, polls, and moderation utilities. The codebase is organized around feature ownership so Discord commands remain thin while repositories, workflows, views, rendering, and external integrations stay independently maintainable.
- 🔍 Smart anime image search with Pinterest and Google fallback
- 🧠 User-aware history that reduces repeated image results
- 📈 Persistent EXP, levels, coins, title roles, and leaderboards
- 🎮 Discord-native games with isolated interaction state
- 🛍️ Shop, inventory, consumables, and item donation
- ⚙️ Feature-oriented architecture with async repositories and services
- 🛡️ Timeouts, cooldowns, rate limits, fallback providers, and recovery paths
- 🔍 Smart PFP Search — Search for high-quality anime profile pictures by character name.
- 📌 Pinterest Worker — Uses Playwright to collect image candidates and resolve higher-resolution Pinterest assets.
- 🌐 Google Fallback — Falls back to Google Custom Search when Pinterest cannot provide enough usable results.
- 🧠 User-Aware Results — Tracks previously served images so repeated searches remain fresh.
- 🧹 Deduplication & Validation — Filters duplicate, unreachable, and unsuitable image URLs.
- 📚 Anime Metadata — Retrieves anime information through AniList.
- ⭐ EXP and Leveling — Members earn experience through messages and supported games.
- 📢 Level-Up Feedback — Announces level progression and rewards.
- 🏷️ Automatic Title Roles — Creates and synchronizes progression roles from Novice through Enlightened.
- 🪪 Profile Cards — Renders rank, title, level, EXP, and customizable backgrounds.
- 🏆 Server Leaderboards — Generates visual leaderboard images for the top members.
- 🪙 Coin Economy — Stores persistent balances alongside progression data.
- 🛒 Shop and Inventory — Buy consumables, inspect owned items, and apply item effects.
- 🎁 Item Donation — Transfer supported inventory items to another server member.
- 🧩 Anime Trivia — Run multiple-choice quizzes with balanced question selection.
- 🖼️ Guess the Character — Identify a character from an image and earn rewards.
- 🎲 Coin Gambling — Play an interactive risk-and-reward coin game.
- 💬 Anime Quotes — Receive randomized quotes while reducing immediate repeats.
- 🌸 Waifu Images — Fetch random SFW images through
waifu.im. - 📊 Persistent Polls — Create timed polls with custom options, vote tracking, recovery, and result presentation.
- 📣 Announcements — Let administrators compose formatted server announcements through a modal.
- 🧭 Dynamic Help — Browse the available commands from Discord.
AniAvatar uses a feature-oriented architecture that separates Discord integration from business logic and shared infrastructure.
- Thin Discord cogs handle command registration, validation, and response orchestration.
- Feature packages own their workflows, views, repositories, domain models, and external integrations.
- Core packages contain infrastructure shared across multiple features.
- PostgreSQL repositories persist progression, economy, trading, polling, and search state.
- Redis is optional and accelerates selected progression and leaderboard operations.
- Process-pool rendering keeps profile and leaderboard image generation away from the Discord event loop.
- Dedicated Discord views isolate interaction state for concurrent games, shops, inventories, donations, and polls.
- External API clients use timeouts, validation, provider fallback, and user-facing error handling.
- Recovery workflows restore active poll state after restarts.
- A member submits a character name.
- The search engine checks cached and previously served results.
- Pinterest is queried through a rate-limited Playwright worker.
- Google Custom Search provides fallback candidates when configured.
- Results are normalized, validated, and deduplicated.
- New images are returned and recorded for that member.
- A supported message or game action produces EXP or coin rewards.
- The progression workflow validates and persists the update.
- Level changes trigger role synchronization and feedback.
- Profile and leaderboard requests are rendered outside the event loop.
- Optional Redis caching reduces repeated work.
AniAvatar/
├── bot/
│ ├── cogs/ # Discord extension entrypoints
│ ├── config/ # Settings, paths, assets, emojis, constants
│ ├── core/
│ │ ├── discord/ # Shared Discord helpers
│ │ ├── logging_config/ # Structured application logging
│ │ ├── rendering/ # Shared render management
│ │ └── repositories/ # Cross-feature repositories
│ └── features/
│ ├── administration/ # Announcement components
│ ├── anime/ # AniList, Jikan, and quiz helpers
│ ├── animepfp/ # Smart image search engine
│ ├── fun/ # Quotes, gambling, responses, waifu client
│ ├── games/ # Trivia and character-guess workflows
│ ├── polling/ # Poll domain, persistence, recovery, and UI
│ ├── progression/ # EXP, profiles, leaderboards, rendering
│ ├── roles/ # Progression-role synchronization
│ └── trading/ # Shop, inventory, donation, item effects
├── data/ # Trivia, quote, and application data
├── docs/ # Screenshots and translated documentation
├── tests/
│ └── manual/ # External API connectivity checks
├── main.py # Bot entrypoint and shared resources
└── requirements.txt
| Command | Category | Description |
|---|---|---|
/animepfp <name> [count] |
Search | Fetch up to five unique anime profile pictures for a character. |
/anime <query> |
Search | Retrieve anime information from AniList. |
/profile [user] |
Progression | Display your profile card or another member's card. |
/leaderboard |
Progression | Render the server's top members by EXP. |
/profiletheme |
Progression | Select a custom profile-card theme and background. |
/resetprofiletheme |
Progression | Restore the default profile-card theme. |
/shop |
Trading | Open the item shop and purchase consumables. |
/inventory |
Trading | Inspect your inventory and use supported items. |
/donate <member> |
Trading | Donate an inventory item to another member. |
/animequiz <questions> |
Games | Start a multiple-choice anime trivia session. |
/guesscharacter |
Games | Guess a character from an image. |
/gamble |
Fun | Gamble coins through an interactive Discord view. |
/waifu |
Fun | Fetch a random SFW image from waifu.im. |
/animequotes |
Fun | Display a random anime quote. |
/poll <duration> |
Community | Create a timed poll through a Discord modal. |
/announce <mention> <channel> |
Admin | Compose and send a server announcement. |
/help |
General | Display the available commands. |
/ping |
General | Check the bot's Discord latency. |
Most user-facing commands are hybrid commands and can also be invoked through the configured ! prefix.
-
Discord Application —
discord.py
Handles slash commands, prefix commands, modals, selects, buttons, cooldowns, listeners, and persistent interaction flows. -
Database — PostgreSQL +
asyncpg
Stores user progression, economy state, trading data, polls, search history, and image-cache metadata. -
Optional Cache — Redis
Supports selected progression and leaderboard caching while remaining optional for local development. -
Anime Search — Playwright + Google Custom Search
Uses Pinterest as the primary visual source and Google as an optional fallback. -
Rendering — Pillow + process workers
Generates profile cards and leaderboards without blocking the Discord event loop. -
External APIs — AniList, Jikan, and
waifu.im
Supply anime metadata, character data, quiz options, and SFW images. -
Networking —
aiohttp
Provides one shared asynchronous HTTP session for external integrations.
Create a .env file in the project root:
# Required
DISCORD_TOKEN=your_discord_bot_token
DATABASE_URL=postgresql://postgres:postgres@localhost:5432/aniavatar
# Optional: owner-only development commands
OWNER_ID=your_discord_user_id
# Optional: Google fallback for /animepfp
GOOGLE_API_KEY=your_google_api_key
SEARCH_ENGINE_ID=your_google_custom_search_engine_id
# Optional: progression and leaderboard cache
REDIS_URL=redis://localhost:6379/0
# Optional: PostgreSQL statement timeout
PG_STATEMENT_TIMEOUT_MS=2000
# Optional: external or mounted asset directory
ASSET_ROOT=DISCORD_TOKEN and DATABASE_URL are required at runtime. Google credentials, Redis, and the owner ID are optional. The bot initializes its required PostgreSQL schemas when the relevant extensions load.
git clone https://github.com/Dendroculus/AniAvatar.git
cd AniAvatarpython -m venv .venvActivate it:
# Windows PowerShell
.venv\Scripts\Activate.ps1
# macOS / Linux
source .venv/bin/activatepip install -r requirements.txtThe Pinterest worker imports Playwright, which is not currently pinned in requirements.txt. Install it and its Chromium runtime separately:
pip install playwright
playwright install chromiumCreate a PostgreSQL database and assign its connection string to DATABASE_URL.
Redis is optional. Without REDIS_URL, AniAvatar continues using PostgreSQL and in-process behavior for supported workflows.
In the Discord Developer Portal:
- Create an application and bot.
- Enable the Server Members Intent.
- Enable the Message Content Intent.
- Invite the bot with the permissions needed by the commands you plan to use.
- Add the bot token to
.env.
python main.pyOn startup, AniAvatar:
- Initializes the shared
aiohttpsession. - Creates the PostgreSQL connection pool.
- Loads the Discord cogs.
- Initializes feature schemas and services.
- Synchronizes application commands.
- Secrets are loaded from environment variables and should never be committed.
- External API calls use shared asynchronous networking and explicit timeout handling.
- The character providers use fallback behavior between AniList and Jikan.
- The waifu client validates HTTP status, JSON structure, session availability, and image presence.
- Search workers use rate limiting and result validation.
- Interactive games and trading views validate the original user before accepting actions.
- Cooldowns protect resource-heavy and economy-related commands.
- Admin and owner-only commands apply explicit permission checks.
- PostgreSQL statement timeouts can be configured through
PG_STATEMENT_TIMEOUT_MS.
Issues, pull requests, and focused improvements are welcome.
For larger changes, open an issue first to align on scope. Keep feature-specific logic inside its owning package and avoid adding new generic utility modules when a clear feature or core owner exists.
Before submitting changes:
ruff format .
ruff check .
python -m compileall -q bot main.pyLicensed under the MIT License. See LICENSE for details.
- discord.py
- AniList
- Jikan
- waifu.im
- Playwright
- Noto Fonts for CJK profile-card support
AniAvatar is an independent project and is not affiliated with, supported by, or endorsed by Discord, AniList, Jikan, Pinterest, Google, or waifu.im.
![]() Hans Valerie Creator & Lead Developer |
