A production-ready Discord bot integrated with n8n workflows for AI-powered chat automation. Built with TypeScript, Bun, and Turborepo.
- 🤖 Discord Bot Bridge - Forwards Discord messages to n8n workflows
- 🧠 AI Chat Integration - Channel-aware conversation memory with session management
- 📊 Distributed Tracing - OpenTelemetry + Jaeger for observability
- 📝 Structured Logging - Pino logger with configurable log levels
- 🔄 Workflow as Code - n8n-kit for TypeScript-based workflow development
- ⚡ Turborepo Monorepo - Parallel builds with intelligent caching
- ✅ Pre-commit Hooks - Automated testing before commits
- 🛠️ Just Task Runner - Simple command orchestration
graph LR
A[Discord User] -->|Message| B[Discord Bot]
B -->|Webhook| C[n8n Discord Bridge]
C -->|Execute Workflow| D[n8n AI Chat]
D -->|API Call| E[AI Model]
E -->|Response| D
D -->|Return| C
C -->|Webhook Response| B
B -->|Reply| A
B -.->|Traces| F[Jaeger]
B -.->|Logs| G[Pino Logger]
graph TD
A[Discord Message] --> B{Is DM?}
B -->|Yes| C[Session: discord-dm-userId]
B -->|No| D[Session: discord-server-channelId]
C --> E[AI Agent Memory]
D --> E
E --> F[Conversation History]
F --> G[AI Response]
graph TB
subgraph "Development"
A[TypeScript Code] -->|n8n-kit| B[Workflow JSON]
B -->|Deploy| C[n8n Instance]
end
subgraph "Runtime"
D[Discord Bot Container] -->|Webhook| C
C -->|Execute| E[AI Agent]
E -->|Memory| F[Simple Memory Store]
end
subgraph "Observability"
D -.->|Traces| G[Jaeger]
D -.->|Logs| H[Pino Logger]
end
packages/
├── discord-bot/ # Discord.js bot with n8n webhook integration
└── n8n-workflows/ # n8n workflows as TypeScript code
- Server channels:
discord-server-{channelId}- Shared conversation history per channel - Direct messages:
discord-dm-{userId}- Private conversation per user
- Bun >= 1.3.3
- Docker & Docker Compose
- Just (optional, for task runner)
- Discord Bot Token
- n8n API Key (for workflow deployment)
git clone https://github.com/pwarnock/discord-ai-platform.git
cd discord-ai-platform
bun installcp .env.example .envEdit .env with your credentials:
DISCORD_BOT_TOKEN=your_discord_bot_token
TEST_CHANNEL_ID=your_test_channel_id
N8N_API_KEY=your_n8n_api_key# Using Just
just up
# Or using Docker Compose
docker-compose up -d
# Activate n8n webhooks (required after n8n restart)
just activate-webhooks# Using Just
just test
# Or using Bun
bun run testjust # List all commands
just test # Run all tests
just build # Build all packages
just up # Start services
just down # Stop services
just logs [service] # View logs
just backup # Backup workflows (timestamped)
just backup-latest # Backup to latest/
just sync # Check for workflow changes and export
just delete-workflow ID # Delete workflow (backs up first)
just deploy-all # Full pipeline: backup → build → deploy
just dev # Development mode with watch
just test-webhook # Test Discord webhookturbo test # Run tests in all packages
turbo build # Build all packages
turbo deploy # Deploy workflows to n8n
turbo dev # Development mode# Export workflows from n8n
docker exec n8n n8n export:workflow --backup --output=backups/latest/
# Import workflow to TypeScript (requires N8N_API_KEY)
cd packages/n8n-workflows
export N8N_BASE_URL=http://localhost:5678
export N8N_API_KEY=your_api_key
bun run import -- --id=<workflow-id> --out=src/workflow.ts
# Deploy workflows from TypeScript
bun run deploy
# Watch mode for development
bun run watch.
├── packages/
│ ├── discord-bot/ # Discord bot package
│ │ ├── index.ts # Main bot logic
│ │ ├── logger.ts # Pino logger setup
│ │ ├── tracing.ts # OpenTelemetry config
│ │ └── index.test.ts # Bun tests
│ └── n8n-workflows/ # n8n workflows package
│ ├── src/ # TypeScript workflows
│ └── n8n-kit.config.ts # n8n-kit configuration
├── code-nodes/ # Extracted code node scripts
├── backups/ # n8n workflow exports
│ ├── latest/ # Latest backup
│ └── YYYYMMDD-HHMMSS/ # Timestamped backups
├── compose.yaml # Docker Compose config
├── turbo.json # Turborepo pipeline
├── justfile # Just task definitions
└── README.md
- Create workflow in n8n UI
- Export to TypeScript:
just import <workflow-id>
- Edit TypeScript in
packages/n8n-workflows/src/ - Deploy:
just deploy-all
Tests run automatically on pre-commit. To run manually:
just testDiscord bot tests are in packages/discord-bot/index.test.ts.
Access Jaeger UI at http://localhost:16686
Traces show:
- Discord message flow
- n8n webhook calls
- AI agent interactions
- Response handling
View logs with:
just logs # All services
just logs discord-bot # Discord bot only
just logs n8n # n8n onlyLog levels: error, warn, info, debug, trace
Set via LOG_LEVEL environment variable.
just backupjust deploy-allThis runs:
- Backup current workflows
- Build all packages
- Deploy to n8n
just build
cd packages/n8n-workflows
bun run deployjust test-webhook "Hello from test"curl -X POST http://localhost:5678/webhook-test/discord \
-H "Content-Type: application/json" \
-d '{
"content": "Test message",
"author": {"id": "123456789"},
"guild": {"id": "987654321"}
}'- Check bot is running:
docker ps - View logs:
just logs discord-bot - Verify webhook URL in bot config
- Test webhook:
just test-webhook - Ensure MESSAGE CONTENT intent is enabled in Discord Developer Portal
- Reactivate n8n webhooks:
just activate-webhooks
- Reactivate webhooks after restart:
just activate-webhooks - Check workflow is active in n8n UI
- View execution logs in n8n
- Verify API key is set:
echo $N8N_API_KEY - Re-export workflows:
just backup-latest
- Ensure services are running:
just up - Check test output:
just test - Run specific package tests:
cd packages/discord-bot bun test
- Create a feature branch
- Make changes
- Tests run automatically on commit (pre-commit hook)
- Push and create PR
MIT
- Runtime: Bun
- Bot Framework: Discord.js
- Workflow Engine: n8n
- Workflow as Code: n8n-kit
- Monorepo: Turborepo
- Task Runner: Just
- Tracing: OpenTelemetry + Jaeger
- Logging: Pino
- Git Hooks: Husky + lint-staged