EyeBOT is a Discord bot built with TypeScript and discord.js v14, designed to integrate Albion Online player data with Discord servers. It provides character registration, verification, automatic nickname synchronization, and comprehensive health monitoring for production deployments.
- Character Registration: Link Discord accounts to Albion Online characters
- Character Verification: Secure verification system via in-game mail
- Automatic Nickname Sync: Discord nicknames update to match Albion character names
- Multi-Character Support: Users can register multiple Albion characters
- Bulk Updates: Admin command to update all registered members at once
- Health Monitoring: Built-in system monitoring with heartbeat functionality
- Database Migrations: Version-controlled database schema management
- Modular Architecture: Feature-based organization for easy expansion
| Technology | Purpose |
|---|---|
| TypeScript | Type-safe development |
| discord.js v14 | Discord API integration |
| MySQL | Data persistence |
| Node.js | Runtime environment |
| Albion Online API | Character data retrieval |
Before installing EyeBOT, ensure you have:
- Node.js v16 or higher (Download)
- npm (comes with Node.js)
- MySQL v5.7 or higher (Download)
- Discord Bot Token (Create a bot)
- Git (optional, for cloning)
git clone https://github.com/DBcide/EyeBOT.git
cd EyeBOTnpm installCreate a .env file in the project root:
# Copy the example below and fill in your values# ================================
# Discord Configuration
# ================================
# Your Discord bot token (from https://discord.com/developers/applications)
DISCORD_TOKEN=your_discord_bot_token_here
# Your Discord application client ID
CLIENT_ID=your_client_id_here
# (Optional) Your Discord guild/server ID for testing
GUILD_ID=your_guild_id_here
# ================================
# Database Configuration
# ================================
# MySQL database host
DB_HOST=localhost
# MySQL username
DB_USER=root
# MySQL password (leave empty if no password)
DB_PASSWORD=your_password_here
# Database name (will be created during setup)
DB_NAME=eyebot
# MySQL port (default: 3306)
DB_PORT=3306
# ================================
# Health Monitoring (Optional)
# ================================
# How often to collect system metrics (milliseconds)
HEALTH_MONITOR_INTERVAL_MS=10000
# How often to send heartbeat requests (milliseconds)
HEARTBEAT_INTERVAL_MS=60000
# URL to send heartbeat POST requests (prevents host shutdown)
HEARTBEAT_URL=https://your-monitoring-endpoint.com/heartbeatWhere to find these values:
| Variable | How to Obtain |
|---|---|
DISCORD_TOKEN |
1. Go to Discord Developer Portal 2. Select your application 3. Go to "Bot" tab 4. Click "Reset Token" and copy the new token |
CLIENT_ID |
Found in "General Information" tab of your Discord application |
GUILD_ID |
Right-click your Discord server → "Copy Server ID" (requires Developer Mode enabled) |
DB_* |
Your MySQL installation credentials |
HEARTBEAT_URL |
Your monitoring service endpoint (e.g., UptimeRobot, custom server) |
Create the database in MySQL:
CREATE DATABASE eyebot CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;Or use the MySQL command line:
mysql -u root -p -e "CREATE DATABASE eyebot CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"npm run migrateThis will create all necessary tables:
migrations- Migration trackingtracer_users- Albion character registrations
npm run registerThis registers all slash commands with Discord's API.
npm run buildDevelopment Mode (with auto-reload):
npm run devProduction Mode:
npm startWith PM2 (recommended for production):
pm2 start ecosystem.config.js| Command | Description | Example |
|---|---|---|
/register <pseudo> |
Register your Albion Online character | /register MyCharName |
/update |
Update your character information from Albion API | /update |
/verify <character> |
Verify a character (admin only) | /verify PlayerName |
| Command | Permission Required | Description |
|---|---|---|
/updateall |
Manage Nicknames | Updates all registered members' nicknames from Albion API |
/verify |
Administrator | Verifies a user's Albion character claim |
npm run dev # Run bot with ts-node (development)
npm run watch # Compile TypeScript in watch mode
npm run build # Compile TypeScript to dist/
npm run clean # Clean dist/ directorynpm start # Run compiled bot from dist/npm run migrate # Run all pending migrations
npm run migrate:rollback # Rollback last migration
npm run migrate:list # List executed migrationsnpm run register # Register slash commands with Discord APIEyeBOT includes a comprehensive health monitoring system designed to prevent shutdown by hosting providers that terminate idle processes (e.g., O2Switch).
System Metrics:
- CPU usage (%)
- Memory usage (total, used, percentage)
- Heap memory (Node.js)
- Process uptime
- System load averages
Discord Metrics:
- Number of guilds
- Total users across all guilds
- Channel count
- WebSocket ping (latency)
- Connection status
When HEARTBEAT_URL is configured, the bot sends periodic POST requests with the following JSON payload:
{
"timestamp": "2025-01-05T10:30:00.000Z",
"status": "healthy",
"uptime": 3600,
"memory": {
"percentage": "45.23",
"used": "512.00 MB"
},
"cpu": {
"usage": "12.50"
},
"discord": {
"guilds": 5,
"users": 1250,
"ping": 45,
"status": "READY"
}
}Headers sent:
Content-Type: application/json
User-Agent: EyeBOT-HealthMonitor/1.0
-
Set environment variables:
HEARTBEAT_URL=https://your-endpoint.com/heartbeat HEARTBEAT_INTERVAL_MS=60000 # Send every 60 seconds
-
Use with monitoring services:
- UptimeRobot: Create HTTP monitor pointing to your endpoint
- Pingdom: Set up transaction check
- Custom server: Create endpoint that receives POST requests
-
Example Node.js heartbeat receiver:
app.post('/heartbeat', (req, res) => { console.log('Heartbeat received:', req.body); // Store metrics, trigger alerts, etc. res.status(200).send('OK'); });
Metrics are logged every 10 seconds (configurable):
📊 Health | CPU: 12.34% | RAM: 45.67% | Heap: 89.12 MB/256.00 MB | Uptime: 1h 23m 45s | Guilds: 5 | Users: 1250 | Ping: 45ms
Alerts are triggered when:
- CPU usage > 80%
- Memory usage > 80%
EyeBOT/
├── src/
│ ├── core/ # Core bot framework
│ │ ├── Bot.ts # Main bot orchestrator
│ │ ├── BaseCommand.ts # Abstract command class
│ │ └── BaseEvent.ts # Abstract event class
│ │
│ ├── features/ # Feature modules
│ │ └── tracer/ # Albion character tracking
│ │ ├── commands/ # Slash commands
│ │ ├── models/ # TypeScript interfaces
│ │ ├── services/ # Business logic
│ │ └── utils/ # Utilities
│ │
│ ├── shared/ # Shared services
│ │ └── services/
│ │ ├── DatabaseService.ts # MySQL wrapper
│ │ ├── LoggerService.ts # Logging
│ │ ├── HealthMonitorService.ts # Health monitoring
│ │ └── ServiceContainer.ts # DI container
│ │
│ ├── database/ # Database layer
│ │ ├── migrations/ # Schema migrations
│ │ ├── Migration.ts # Migration interface
│ │ └── MigrationService.ts
│ │
│ ├── scripts/ # Utility scripts
│ │ ├── register-commands.ts
│ │ ├── run-migrations.ts
│ │ ├── rollback-migration.ts
│ │ └── list-migrations.ts
│ │
│ └── index.ts # Entry point
│
├── dist/ # Compiled JavaScript (generated)
├── .env # Environment variables (not in git)
├── package.json
├── tsconfig.json
└── README.md # This file
Stores Albion Online character registrations.
| Column | Type | Description |
|---|---|---|
id |
INT (PK) | Auto-incrementing ID |
discord_id |
VARCHAR(20) | Discord user ID |
albion_id |
VARCHAR(255) | Albion character ID |
albion_name |
VARCHAR(255) | Albion character name |
kill_fame |
BIGINT | Character kill fame |
death_fame |
BIGINT | Character death fame |
guild_name |
VARCHAR(255) | Guild name (nullable) |
alliance_name |
VARCHAR(255) | Alliance name (nullable) |
is_main |
TINYINT(1) | Main character flag |
is_verified |
TINYINT(1) | Verification status |
registered_at |
TIMESTAMP | Registration timestamp |
updated_at |
TIMESTAMP | Last update timestamp |
-
Create
src/features/<feature>/commands/MyCommand.ts:import { BaseCommand } from '../../../core/BaseCommand'; import { ChatInputCommandInteraction, SlashCommandBuilder } from 'discord.js'; export default class MyCommand extends BaseCommand { public name = 'mycommand'; public description = 'My command description'; public buildCommand(): SlashCommandBuilder { return new SlashCommandBuilder() .setName(this.name) .setDescription(this.description); } public async execute(interaction: ChatInputCommandInteraction): Promise<void> { await interaction.reply('Hello!'); } }
-
Build and register:
npm run build npm run register
-
Create
src/database/migrations/YYYYMMDD_HHMMSS_description.ts:import { Migration } from '../Migration'; import mysql from 'mysql2/promise'; export const migration: Migration = { name: '20250105_120000_add_new_table', async up(connection: mysql.PoolConnection): Promise<void> { await connection.query(` CREATE TABLE my_table ( id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(255) NOT NULL ); `); }, async down(connection: mysql.PoolConnection): Promise<void> { await connection.query('DROP TABLE my_table'); } };
-
Export in
src/database/migrations/index.ts -
Run:
npm run migrate
-
Install PM2 globally:
npm install -g pm2
-
Create
ecosystem.config.js:module.exports = { apps: [{ name: 'eyebot', script: './dist/index.js', instances: 1, autorestart: true, watch: false, max_memory_restart: '1G', env: { NODE_ENV: 'production' } }] };
-
Start:
pm2 start ecosystem.config.js
-
Useful PM2 commands:
pm2 status # Check status pm2 logs eyebot # View logs pm2 restart eyebot # Restart bot pm2 stop eyebot # Stop bot pm2 delete eyebot # Remove from PM2
For O2Switch Node.js hosting:
-
Enable health monitoring in
.env:HEARTBEAT_URL=https://your-domain.com/heartbeat HEARTBEAT_INTERVAL_MS=60000
-
Use PM2 to keep the bot running
-
The heartbeat will prevent the host from shutting down idle processes
- Check bot is online in Discord
- Verify slash commands are registered:
npm run register - Check bot has proper permissions in your server
- Review logs for errors
- Verify MySQL is running:
mysql --version - Check
.envcredentials are correct - Ensure database exists:
SHOW DATABASES; - Test connection:
npm run migrate:list
- Re-register commands:
npm run register - Wait up to 1 hour for global commands to propagate
- Use
GUILD_IDin.envfor instant testing (guild-specific commands)
- Check
HEARTBEAT_URLis set in.env - Verify endpoint is accessible:
curl -X POST <HEARTBEAT_URL> - Check logs for heartbeat errors
- Ensure firewall allows outbound HTTP requests
The bot implements automatic rate limiting for the Albion Online API:
- Batch processing:
/updateallprocesses 5 users at a time - Delays: 1 second between batches to avoid 429 errors
- Error handling: Graceful degradation on API failures
Public Project
- Author: DBcide (Olivier Français)
- Contact: contact@dbcide.fr
- Commercial use prohibited without authorization
- Modification and redistribution prohibited without authorization
- Attribution required for any authorized use
- See LICENSE.txt for full details
For issues, questions, or feature requests:
- Check existing documentation (README.md)
- Review troubleshooting section above
- Contact: contact@dbcide.fr
- discord.js - Discord API wrapper
- Albion Online - Game data API
- O2Switch - Node.js hosting platform