Multi-tenant Discord bot with DynamoDB-backed character profiles and a Next.js admin console.
bot/— Python Discord bot (discord.py, OpenRouter, DynamoDB, S3)web/— TypeScript Next.js dashboard (Auth.js Discord OAuth)infra/— AWS setup scripts for DynamoDB + S3 + IAM policy
- Configure AWS CLI credentials or attach
infra/iam-ec2-policy.jsonto your EC2 instance role. - Run:
chmod +x infra/setup-aws.sh
./infra/setup-aws.sh- Seed your first admin in DynamoDB (replace
YOUR_DISCORD_ID):
{
"pk": "USERS",
"sk": "USERID#YOUR_DISCORD_ID",
"discordId": "YOUR_DISCORD_ID",
"approved": true,
"admin": true,
"gsi1pk": "APPROVAL#approved",
"gsi1sk": "USERID#YOUR_DISCORD_ID",
"usageInputTokens": 0,
"usageOutputTokens": 0
}cd bot
python -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install -r requirements.txt
cp .env.example .env # fill TOKEN, AWS_*, S3_BUCKET, ENCRYPTION_SECRET
python main.pycd web
npm ci
cp .env.example .env # fill AUTH_*, DISCORD_*, AWS_*, ENCRYPTION_SECRET, OPENROUTER_MANAGEMENT_KEY
npm run build
npm start- Clone repo on EC2; configure
bot/.envandweb/.env. - Build web:
cd web && npm ci && npm run build. - Start:
pm2 start ecosystem.config.jsonfrom repo root. - Point Caddy/nginx at
localhost:3000with TLS. - Set
AUTH_URL=https://your-domain.comand matching Discord OAuth redirect.
See the project plan for full Discord Developer Portal setup (OAuth redirects, bot invite with permissions 2416299008, Message Content Intent).
Bot invite permissions include Change Nickname so the bot can set its server nickname to the active character name. If the bot was invited with an older link, re-invite using the dashboard link or:
https://discord.com/api/oauth2/authorize?client_id=YOUR_APP_ID&permissions=2416299008&scope=bot%20applications.commands
- Set
OPENROUTER_MANAGEMENT_KEYon the web server for admin user approval (auto-provisions per-user keys). - Each approved user gets an encrypted key in DynamoDB; the bot decrypts with
ENCRYPTION_SECRET.