Synthesized research findings from 4 parallel researcher agents: Key Findings: - Stack: discord.py 2.6.4 + PostgreSQL/SQLite with webhook-driven PluralKit integration - Architecture: 7-component system with clear separation of concerns, async-native - Features: Rule-based learning system starting simple, avoiding context inference and ML - Pitfalls: 8 critical risks identified with phase assignments and prevention strategies Recommended Approach: - 5-phase build order (detection → translation → teaching → config → polish) - Focus on dysgraphia accessibility for teaching interface - Start with message detection reliability (Phase 1, load-bearing) - Shared emoji dictionary (Phase 1-3); per-server overrides deferred to Phase 4+ Confidence Levels: - Tech Stack: VERY HIGH (all production-proven, no experimental choices) - Architecture: VERY HIGH (mirrors successful production bots) - Features: HIGH (tight scope, transparent approach) - Roadmap: HIGH (logical phase progression with value delivery) Gaps to Address in Requirements: - Vivi's teaching UX preferences (dysgraphia-specific patterns) - Exact emoji coverage and naming conventions - Moderation/teaching permissions model - Multi-system scope and per-system customization needs Ready for requirements definition and roadmap creation. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
8.2 KiB
8.2 KiB
Quick Reference: Tech Stack Decisions
For comprehensive rationale, see STACK.md
One-Page Summary
Bot Framework: discord.py 2.6.4 (Python 3.10+)
Database: SQLite (MVP) / PostgreSQL (production)
PluralKit: pluralkit.py + webhook dispatch
Hosting: Railway ($0-5/month) or Oracle Cloud (free)
Command Style: Slash commands (/translate 🎭)
Installation Checklist (Fresh Project)
# Create project
mkdir vivi-speech-translator
cd vivi-speech-translator
python -m venv venv
source venv/bin/activate # or `venv\Scripts\activate` on Windows
# Core dependencies
pip install discord.py==2.6.4
pip install pluralkit==1.1.5
pip install aiosqlite==0.19.0 # MVP database
pip install aiohttp==3.9.0 # Webhook server
pip install emoji==2.11.0 # Emoji handling
pip install pydantic==2.5.0 # Data validation
pip install python-dotenv==1.0.0
# Optional (production)
pip install asyncpg==0.29.0 # PostgreSQL driver
pip install sentry-sdk==1.45.0 # Error tracking
# Testing
pip install pytest==7.4.0
pip install pytest-asyncio==0.23.0
Database Quick Start
MVP (SQLite)
import aiosqlite
# Create database
async with aiosqlite.connect('emoji.db') as db:
await db.execute('''
CREATE TABLE IF NOT EXISTS emoji_mappings (
id INTEGER PRIMARY KEY,
emoji TEXT UNIQUE NOT NULL,
meaning TEXT NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)
''')
await db.commit()
# Use in bot
async def learn_emoji(emoji_str, meaning):
async with aiosqlite.connect('emoji.db') as db:
await db.execute(
'INSERT INTO emoji_mappings (emoji, meaning) VALUES (?, ?)',
(emoji_str, meaning)
)
await db.commit()
Production (PostgreSQL)
import asyncpg
pool = await asyncpg.create_pool('postgresql://user:pwd@host/db')
async def learn_emoji(emoji_str, meaning):
async with pool.acquire() as conn:
await conn.execute(
'INSERT INTO emoji_mappings (emoji, meaning) VALUES ($1, $2)',
emoji_str, meaning
)
PluralKit Integration Checklist
- Get system token: Run
pk;tokenin Discord with PluralKit bot - Store token in
.env:PLURALKIT_TOKEN=pk_... - Create webhook endpoint in your bot
- Register webhook URL with PluralKit API
- Set up webhook signature verification (use nacl library)
- Cache member list in memory on startup
- Update cache on webhook events (CREATE_MEMBER, UPDATE_MEMBER, DELETE_MEMBER)
Webhook Endpoint Example:
from aiohttp import web
async def handle_pk_webhook(request):
body = await request.text()
signature = request.headers.get('X-Signature-Ed25519')
# Verify signature
if not verify_signature(body, signature):
return web.Response(status=401)
data = await request.json()
# Update emoji mappings based on member changes
return web.Response(status=200)
# Add to bot setup
app.router.add_post('/webhooks/pluralkit', handle_pk_webhook)
Slash Commands vs Prefix Commands
✅ Use Slash Commands (Recommended)
@bot.slash_command(name="learn")
async def learn(ctx, emoji: str, meaning: str):
"""Learn what an emoji means"""
await learn_emoji(emoji, meaning)
await ctx.respond(f"Learned: {emoji} = {meaning}")
# No MessageContent intent needed!
# Users see autocomplete, clearer UI
❌ Don't Use Prefix Commands
@bot.command(name="learn")
async def learn(ctx, emoji: str, meaning: str):
"""Learn what an emoji means"""
# Requires MessageContent intent ❌
# Harder to use, poor UX
Environment Variables (.env)
# .env (DO NOT COMMIT - add to .gitignore)
DISCORD_TOKEN=your_bot_token_here
PLURALKIT_TOKEN=pk_your_system_token_here
DATABASE_URL=postgresql://user:password@localhost/emojidb
WEBHOOK_SECRET=your_webhook_secret_from_pk
# Optional
SENTRY_DSN=https://...@sentry.io/...
LOG_LEVEL=INFO
Add to .gitignore:
.env
*.db
*.sqlite3
__pycache__/
venv/
Bot Intents Configuration
intents = discord.Intents.default()
intents.guilds = True # Required
intents.members = True # For member info
intents.message_content = False # NOT needed (use slash commands)
bot = discord.Bot(intents=intents)
Don't enable message_content unless you parse raw text messages.
Permissions URL
https://discord.com/oauth2/authorize
?client_id=YOUR_CLIENT_ID
&scope=bot
&permissions=536996928
Permissions included:
- Read Messages/View Channels (1024)
- Send Messages (2048)
- Embed Links (16384)
- Read Message History (65536)
Hosting Setup
Railway (Recommended)
# Install Railway CLI
curl -fsSL https://railway.app/install.sh | bash
# Initialize
railway init
# Deploy from GitHub
# (auto-deploys when you push to main)
# View logs
railway logs
# Set environment variables
railway variables set DISCORD_TOKEN=...
Cost
- First $5/month free credit
- $5 for 1GB RAM for bot
- $15 for PostgreSQL (or get free tier)
- Total: $0-20/month for small bot
Oracle Cloud (Free Alternative)
- 4 CPU, 24GB RAM, 200GB storage VM (always free)
- Run bot + PostgreSQL on same VM
- Note: May delete instances after 60 days inactivity
- Requires Linux/Docker knowledge
Common Commands During Development
# Run locally
python main.py
# Run tests
pytest
# Format code
black .
# Check types
mypy .
# View database (SQLite)
sqlite3 emoji.db
> SELECT * FROM emoji_mappings;
# View logs on Railway
railway logs -f
# Deploy to Railway
git push origin main # auto-deploys
Anti-Patterns to Avoid
❌ Using Pycord (py-cord) - unmaintained since 2023
❌ Storing bot token in code - use .env
❌ Requesting MessageContent intent for slash commands
❌ Polling PluralKit API - use webhooks instead
❌ Synchronous database calls - use async/await
❌ Custom webhook signature verification - use nacl library
❌ Unbounded emoji history table - set expiry policies
Testing Emoji Detection
# test_emoji.py
import pytest
import emoji
def test_emoji_detection():
test_emoji = "😊"
assert emoji.is_emoji(test_emoji)
demojized = emoji.demojize(test_emoji)
assert demojized == ":smiling_face_with_smiling_eyes:"
@pytest.mark.asyncio
async def test_learn_emoji():
await learn_emoji("🎭", "happy performance")
meanings = await get_emoji_meanings("🎭")
assert "happy performance" in meanings
Monitoring in Production
Recommended additions after MVP:
- Error Tracking: Sentry for automatic error alerts
- Logging: Structured logging to file or cloud
- Metrics: Track command usage, emoji diversity, member growth
- Health Checks: Endpoint that Railway monitors (
GET /health)
# Simple health check
@app.route('/health')
async def health(request):
return web.Response(text='OK', status=200)
Troubleshooting Quick Fixes
| Problem | Solution |
|---|---|
| Bot doesn't start | Check DISCORD_TOKEN in .env |
| Slash commands not appearing | Call await bot.sync_commands() |
| Database locked error (SQLite) | Only one writer at a time - use PostgreSQL for scaling |
| PluralKit webhook not received | Check public URL is reachable, signature verification |
| Slow emoji lookups | Add database indices, implement Redis cache |
| Bot unresponsive | Check for sync calls blocking event loop |
Next Steps
- Read full research: STACK.md
- Setup development environment using checklist above
- Start with MVP: SQLite, slash commands, Vivi user detection
- Implement PluralKit: Webhook dispatch, member caching
- Test locally: Private Discord server for development
- Deploy to Railway: Connect GitHub, set environment variables
- Monitor in production: Sentry, logs, metrics
- Iterate: Gather feedback, add features