A professional furry-themed Discord bot platform with advanced image interactions, built as a modern monorepo.
Pawsitive is built as a pnpm monorepo with the following structure:
pawsitive/
βββ apps/
β βββ bot/ # Discord bot (Seyfert framework)
β βββ api/ # REST API (Elysia framework)
β βββ dashboard/ # Web dashboard (Astro)
βββ packages/
β βββ config/ # Environment & configuration management
β βββ types/ # Shared TypeScript types
β βββ shared/ # Shared utilities (logger, schemas, helpers)
βββ pnpm-workspace.yaml
- Bot: Seyfert - Modern Discord bot framework
- API: Elysia - Ultra-fast Bun-powered web framework
- Dashboard: Astro - Modern static site framework
- Package Manager: pnpm with workspaces
- Language: TypeScript
- Styling: Tailwind CSS (dashboard)
- Logging: Pino
- Validation: Zod
- Node.js 18+ (for bot and shared packages)
- Bun (for API) - Install from bun.sh
- pnpm -
npm install -g pnpm - Discord Bot Token - Get from Discord Developer Portal
- Clone the repository
git clone https://github.com/Chere3/pawsitive.git
cd pawsitive- Install dependencies
pnpm install- Set up environment variables
# Bot
cp apps/bot/.env.example apps/bot/.env
# Edit apps/bot/.env and add your BOT_TOKEN
# API
cp apps/api/.env.example apps/api/.env
# Edit apps/api/.env if needed
# Dashboard
cp apps/dashboard/.env.example apps/dashboard/.env
# Edit apps/dashboard/.env if needed- Build shared packages
pnpm --filter @pawsitive/config build
pnpm --filter @pawsitive/types build
pnpm --filter @pawsitive/shared buildRun all apps in development mode:
pnpm devOr run individual apps:
# Bot only
pnpm bot:dev
# API only
pnpm api:dev
# Dashboard only
pnpm dashboard:devOn first run, you need to upload commands to Discord:
# Set UPLOAD_COMMANDS=true in apps/bot/.env
# Then run the bot
pnpm bot:devDiscord bot built with Seyfert.
- Port: N/A (Discord Gateway)
- Commands:
/ping,/info - Events:
botReady,guildCreate - Features:
- Command framework
- Event handling
- Image interaction abstraction layer
- Environment validation
- Structured logging
Key Files:
src/index.ts- Bot entry pointsrc/commands/- Slash commandssrc/events/- Event handlerssrc/lib/image-interactions.ts- Image processing moduleseyfert.config.mjs- Seyfert configuration
REST API built with Elysia.
- Port: 3000 (default)
- Swagger: http://localhost:3000/swagger
- Features:
- Health check endpoints
- Webhook handling (Discord interactions)
- Bot status API
- Image processing queue (stub)
- Authentication ready (stub)
Endpoints:
GET /health- Health checkGET /health/version- API versionGET /health/ready- Readiness probePOST /webhook/discord- Discord webhookGET /api/bot/status- Bot statusPOST /api/image/process- Queue image processingGET /api/image/job/:jobId- Get job status
Web dashboard built with Astro + Tailwind CSS.
- Port: 4321 (default)
- URL: http://localhost:4321
- Features:
- Bot status overview
- Feature showcase
- Modern responsive UI
- Server-side rendering
Environment configuration and validation.
- Zod schemas for environment variables
- Type-safe configuration access
- Validation on startup
Shared TypeScript types and interfaces.
- Bot status types
- API response types
- Image processing types
- Domain models
Shared utilities and helpers.
- Logger: Pino-based structured logging
- Schemas: Zod validation schemas
- Utils: Format helpers, retry logic, ID generation
β Discord Bot
- Slash command framework
- Event handling
- Latency monitoring
- Multi-guild support
β REST API
- Health checks
- Webhook endpoints
- Swagger documentation
- CORS support
β Web Dashboard
- Status overview
- Feature showcase
- Responsive design
π§ Image Processing
- Upload and process images
- Filters and effects
- Format conversion
- Bulk operations
π§ Advanced Bot Features
- Moderation tools
- Custom reactions
- Role management
- Server analytics
π§ Dashboard Enhancements
- Real-time bot status
- Command management UI
- Guild settings
- Analytics dashboard
π§ Infrastructure
- Database integration (PostgreSQL)
- Redis caching
- Job queue (BullMQ)
- Image CDN integration
# Development
pnpm dev # Run all apps in parallel
pnpm bot:dev # Run bot only
pnpm api:dev # Run API only
pnpm dashboard:dev # Run dashboard only
# Build
pnpm build # Build all packages
# Type checking
pnpm typecheck # Type check all packages
# Linting (placeholder)
pnpm lint # Lint all packages
# Clean
pnpm clean # Remove all build artifactspawsitive/
βββ apps/
β βββ bot/
β β βββ src/
β β β βββ commands/ # Slash commands
β β β βββ events/ # Event handlers
β β β βββ lib/ # Utilities
β β β βββ index.ts # Entry point
β β βββ seyfert.config.mjs # Bot config
β β βββ .env.example
β βββ api/
β β βββ src/
β β β βββ routes/ # API routes
β β β βββ index.ts # Entry point
β β βββ .env.example
β βββ dashboard/
β βββ src/
β β βββ components/ # Astro components
β β βββ layouts/ # Page layouts
β β βββ pages/ # Routes
β βββ astro.config.mjs
β βββ tailwind.config.mjs
βββ packages/
β βββ config/
β β βββ src/index.ts # Environment validation
β βββ types/
β β βββ src/index.ts # Type definitions
β βββ shared/
β βββ src/
β βββ logger.ts # Logger setup
β βββ schemas.ts # Zod schemas
β βββ utils.ts # Utilities
βββ pnpm-workspace.yaml
βββ tsconfig.base.json
βββ package.json
- Create a new file in
apps/bot/src/commands/
import { Command, Declare, type CommandContext } from 'seyfert';
@Declare({
name: 'yourcommand',
description: 'Your command description'
})
export default class YourCommand extends Command {
async run(ctx: CommandContext) {
await ctx.write({
content: 'Hello from your command!'
});
}
}-
Restart the bot (commands are auto-loaded)
-
Upload commands to Discord:
# Set UPLOAD_COMMANDS=true in .env
pnpm bot:dev- Create or edit a route file in
apps/api/src/routes/
import { Elysia } from 'elysia';
export const myRouter = new Elysia({ prefix: '/my' })
.get('/', () => ({ message: 'Hello!' }));- Import and use in
apps/api/src/index.ts
import { myRouter } from './routes/my.js';
const app = new Elysia()
.use(myRouter)
// ...BOT_TOKEN= # Required - Discord bot token
BOT_PUBLIC_KEY= # Optional - For HTTP interactions
NODE_ENV=development # development | production
LOG_LEVEL=info # trace | debug | info | warn | error | fatal
UPLOAD_COMMANDS=false # Set to true to upload commands on startupAPI_PORT=3000
API_HOST=0.0.0.0
API_SECRET= # Optional - API authentication secret
NODE_ENV=development
LOG_LEVEL=infoPUBLIC_API_URL=http://localhost:3000
PUBLIC_BOT_INVITE_URL=https://discord.com/oauth2/authorize?client_id=YOUR_ID
PUBLIC_SUPPORT_SERVER_URL=https://discord.gg/your-serverThe bot includes an abstraction layer for image processing (apps/bot/src/lib/image-interactions.ts):
- Image validation (type, size, dimensions)
- Download from URL
- Process with various operations:
- Blur/sharpen
- Resize/crop
- Filters
- Format conversion
- Bot Commands: Users upload images via Discord
- Image Handler: Validates and queues processing
- API: Processes images asynchronously
- Response: Returns processed image to Discord
For future implementation, consider:
- sharp - High-performance image processing (Node.js)
- jimp - Pure JavaScript image library
- canvas - Drawing and compositing
- Cloudinary - Cloud-based image processing
# Build all packages
pnpm build
# Start in production
NODE_ENV=production node apps/bot/dist/index.js
NODE_ENV=production bun run apps/api/src/index.ts
# Dashboard: Deploy to Vercel/Netlify/Cloudflare Pages- Bot: Any Node.js hosting (Railway, Fly.io, VPS)
- API: Bun-compatible hosting (Fly.io, VPS)
- Dashboard: Static hosting (Vercel, Netlify, Cloudflare Pages)
Docker support is planned for easier deployment.
- Fork the repository
- Create a feature branch
- Make your changes
- Test thoroughly
- Submit a pull request
MIT
- Seyfert - Amazing Discord bot framework
- Elysia - Blazingly fast web framework
- Astro - Modern web framework
- The furry community πΎ
Made with π by the Pawsitive team