Official Discord Bot for LicenseChain - License management and customer support through Discord.
- License Management - Validate, create, and manage licenses
- User Support - Handle customer inquiries and support tickets
- Analytics - View usage statistics and performance metrics
- Notifications - Real-time license events and alerts
- Ticket System - Create and manage support tickets
- Reporting - Generate reports and analytics
- Security - Secure authentication and authorization
- Easy Setup - Simple configuration and deployment
# Clone the repository
git clone https://github.com/LicenseChain/LicenseChain-Discord-Bot.git
cd LicenseChain-Discord-Bot
# Install dependencies
npm install
# Start the bot
npm start# Build the Docker image
docker build -t licensechain-discord-bot .
# Run the container with environment variables
# Option 1: Use --env-file to load from .env file
docker run -d \
--name licensechain-discord-bot \
--env-file .env \
-p 3004:3004 \
-v $(pwd)/data:/app/data \
-v $(pwd)/logs:/app/logs \
licensechain-discord-bot
# Option 2: Pass environment variables directly
docker run -d \
--name licensechain-discord-bot \
-e DISCORD_TOKEN=your-discord-bot-token \
-e LICENSE_CHAIN_API_KEY=your-api-key \
-e LICENSE_CHAIN_API_URL=https://api.licensechain.app \
-e LICENSECHAIN_APP_NAME=your-app-name \
-p 3004:3004 \
-v $(pwd)/data:/app/data \
-v $(pwd)/logs:/app/logs \
licensechain-discord-bot
# Option 3: Use docker-compose (recommended)
docker-compose up -dImportant Docker Notes:
- The
.envfile is NOT copied into the image for security reasons - You must pass environment variables using
--env-fileor-eflags - Mount volumes for
data/andlogs/to persist data between container restarts - Default port is 3004 (not 3000)
Docker Permission Issues:
If you encounter permission errors (SQLITE_CANTOPEN or EACCES), try one of these solutions:
-
Fix permissions on host (Linux/Mac):
sudo chown -R 1000:1000 ./data ./logs sudo chmod -R 755 ./data ./logs
-
Use named volumes instead of bind mounts:
volumes: - bot-data:/app/data - bot-logs:/app/logs volumes: bot-data: bot-logs:
-
Run container as root (not recommended for production):
user: "0:0"
-
On Windows: The entrypoint script will attempt to fix permissions automatically. If issues persist, ensure Docker Desktop has proper file sharing permissions enabled.
# Create .env file with your configuration
cp .env.example .env
nano .env # Edit with your values
# Start the bot
docker-compose up -d
# View logs
docker-compose logs -f
# Stop the bot
docker-compose down- Download the latest release from GitHub Releases
- Extract to your project directory
- Install dependencies:
npm install - Configure environment variables
- Start the bot:
npm start
Before you can use this bot, you need to create a Discord application and bot. Follow these steps:
- Go to the Discord Developer Portal
- Click "New Application" in the top right corner
- Enter a name for your application (e.g., "LicenseChain Bot")
- Click "Create"
- In your application, navigate to the "Bot" section in the left sidebar
- Click "Add Bot" and confirm
- Your bot has been created! You'll see the bot's username and icon
- Still in the "Bot" section, scroll down to find the "Token" section
- Click "Reset Token" if this is your first time, or "Copy" to copy your existing token
⚠️ IMPORTANT: Keep this token secret! Never share it or commit it to public repositories- Save this token - you'll need it for your
.envfile
The bot requires certain privileged intents to function properly. In the "Bot" section:
- Scroll down to "Privileged Gateway Intents"
- Enable the following intents:
- ✅ Message Content Intent - Required for reading message content
- ✅ Server Members Intent - Required for accessing guild member information
- ✅ Presence Intent - Required for presence update events
Note: These intents require verification if your bot reaches 100+ servers.
-
Navigate to the "OAuth2" → "URL Generator" section
-
Under "Scopes", select:
- ✅
bot- Required to add the bot to servers - ✅
applications.commands- Required for slash commands
- ✅
-
Under "Bot Permissions", select the following permissions:
General Permissions:
- ✅ View Channels
- ✅ Send Messages
- ✅ Read Message History
- ✅ Embed Links
- ✅ Attach Files
- ✅ Use Slash Commands
- ✅ Manage Messages (optional, for message management)
- ✅ Add Reactions (optional, for interactive features)
Text Permissions:
- ✅ Send Messages
- ✅ Send Messages in Threads
- ✅ Read Message History
- ✅ Use Slash Commands
- ✅ Embed Links
- ✅ Attach Files
- ✅ Add Reactions
-
Copy the generated "Generated URL" at the bottom of the page
-
Open this URL in your browser to invite the bot to your Discord server
-
Select the server where you want to add the bot and authorize it
In the "Bot" section, you can also configure:
- Public Bot: Enable if you want others to be able to add your bot
- Requires OAuth2 Code Grant: Usually leave this disabled unless you have specific OAuth2 requirements
# Clone the repository
git clone https://github.com/LicenseChain/LicenseChain-Discord-Bot.git
cd LicenseChain-Discord-Bot
# Install dependencies
npm install
# Copy environment file
cp .env.example .env
# Edit environment variables
nano .env # or use your preferred text editorEdit your .env file with the following variables:
# Discord Configuration
# Get your bot token from: https://discord.com/developers/applications
DISCORD_TOKEN=your-discord-bot-token-here
# Command prefix for text-based commands (default: !)
DISCORD_PREFIX=!
# LicenseChain API Configuration
# Get your API key from: https://licensechain.app
LICENSE_CHAIN_API_KEY=your-licensechain-api-key-here
LICENSE_CHAIN_API_URL=https://api.licensechain.app
LICENSECHAIN_APP_NAME=your-app-name-here
LICENSECHAIN_APP_VERSION=1.0.0
# Database Configuration
# SQLite database path (default: data/bot.db)
DATABASE_URL=data/bot.db
# Server Configuration
# Port for health check server (default: 3004)
PORT=3004
# Logging Configuration
# Log level: error, warn, info, debug (default: info)
LOG_LEVEL=info
# Node Environment
# Set to 'production' for production, 'development' for development
NODE_ENV=development# Start the bot
npm start
# Or for development with auto-reload
npm run devYou should see a message indicating the bot has logged in successfully!
- ✅
bot- Required to add the bot to servers - ✅
applications.commands- Required for slash commands
- ✅ Message Content Intent - Required for reading message content
- ✅ Server Members Intent - Required for accessing guild member information
- ✅ Presence Intent - Required for presence update events
- ✅ View Channels
- ✅ Send Messages
- ✅ Read Message History
- ✅ Embed Links
- ✅ Attach Files
- ✅ Use Slash Commands
- ✅ Add Reactions (recommended)
- ✅ Send Messages in Threads (recommended)
- ✅ Manage Messages (optional, for advanced features)
# Validate a license
!license validate <license-key>
# Get license information
!license info <license-key>
# List user's licenses
!license list
# Create a new license
!license create <user-id> <features> <expires>
# Update a license
!license update <license-key> <field> <value>
# Revoke a license
!license revoke <license-key># Get user information
!user info <user-id>
# Get user's licenses
!user licenses <user-id>
# Get user's analytics
!user analytics <user-id>
# Ban a user
!user ban <user-id> <reason>
# Unban a user
!user unban <user-id># Create a support ticket
!ticket create <subject> <description>
# List support tickets
!ticket list
# Get ticket details
!ticket info <ticket-id>
# Update ticket status
!ticket update <ticket-id> <status>
# Close a ticket
!ticket close <ticket-id># Get usage analytics
!analytics usage [timeframe]
# Get license analytics
!analytics licenses [timeframe]
# Get performance metrics
!analytics performance
# Get error statistics
!analytics errors# Get bot status
!admin status
# Get bot statistics
!admin stats
# Reload commands
!admin reload
# Set bot status
!admin status <status>
# Get bot logs
!admin logs [lines]Configure the bot through environment variables or a configuration file:
// config/bot.js
module.exports = {
discord: {
token: process.env.DISCORD_TOKEN,
clientId: process.env.DISCORD_CLIENT_ID,
guildId: process.env.DISCORD_GUILD_ID
},
licensechain: {
apiKey: process.env.LICENSECHAIN_API_KEY,
appName: process.env.LICENSECHAIN_APP_NAME,
version: process.env.LICENSECHAIN_APP_VERSION,
baseUrl: process.env.LICENSECHAIN_BASE_URL
},
bot: {
prefix: process.env.BOT_PREFIX || '!',
ownerId: process.env.BOT_OWNER_ID,
debug: process.env.BOT_DEBUG === 'true'
}
};Configure commands and their permissions:
// config/commands.js
module.exports = {
'license validate': {
permission: 'user',
cooldown: 5000,
description: 'Validate a license key'
},
'license create': {
permission: 'admin',
cooldown: 10000,
description: 'Create a new license'
},
'admin status': {
permission: 'owner',
cooldown: 0,
description: 'Get bot status'
}
};The bot supports multiple database types:
// PostgreSQL
DATABASE_URL=postgresql://username:password@localhost:5432/licensechain
// MySQL
DATABASE_URL=mysql://username:password@localhost:3306/licensechain
// SQLite
DATABASE_URL=sqlite://./database.sqlite- Discord OAuth2 integration
- Role-based command permissions
- User verification system
- Secure API key management
The bot uses a custom role-based permission system with three levels:
-
Owner - Bot owner (configured via
BOT_OWNER_IDin.env)- Highest level of access
- Can execute owner-only commands
- Configured by Discord User ID
-
Admin - Server administrators or custom admin roles
- Can execute admin commands
- Detected via:
- Discord's built-in Administrator permission, OR
- Custom admin roles (configured via
ADMIN_ROLE_IDSin.env)
-
User - Regular users
- Default permission level
- Can execute public commands
Permission Hierarchy: Owner > Admin > User
Configuration:
# Set bot owner (required for owner commands)
BOT_OWNER_ID=your-discord-user-id
# Optional: Set custom admin role IDs (comma-separated)
ADMIN_ROLE_IDS=123456789012345678,987654321098765432The bot implements comprehensive security measures:
-
Input Validation - All user inputs are validated before processing
- License keys: Format validation (alphanumeric, dashes, underscores, 10-100 chars)
- User IDs: Discord snowflake validation (17-19 digits)
- Email addresses: Format validation
- URLs: Protocol validation (HTTP/HTTPS only)
- Numbers: Range validation with min/max limits
-
XSS Protection - All text outputs are sanitized
- HTML tags removed (
<,>) - JavaScript protocols blocked (
javascript:) - Event handlers removed (
onclick=, etc.) - Character limits enforced (2000 chars for strings, 1024 for embeds)
- HTML tags removed (
-
SQL Injection Prevention - Parameterized queries with additional sanitization
- All database queries use parameterized statements
- Additional pattern filtering for SQL keywords
- Special characters sanitized
-
Secure Logging - Sensitive data is not logged
- API keys and tokens excluded from logs
- User data sanitized before logging
- Error messages don't expose internal details
// Track command usage
client.on('interactionCreate', async (interaction) => {
if (interaction.isCommand()) {
analytics.track('command_used', {
command: interaction.commandName,
user: interaction.user.id,
guild: interaction.guild?.id,
timestamp: new Date()
});
}
});// Monitor command execution time
const start = Date.now();
await command.execute(interaction);
const duration = Date.now() - start;
metrics.record('command_execution_time', duration);// Track command errors
try {
await command.execute(interaction);
} catch (error) {
errorTracker.captureException(error, {
command: interaction.commandName,
user: interaction.user.id,
guild: interaction.guild?.id
});
}// Custom error classes
class CommandError extends Error {
constructor(message) {
super(message);
this.name = 'CommandError';
}
}
class PermissionError extends Error {
constructor(message) {
super(message);
this.name = 'PermissionError';
}
}// Global error handler
client.on('error', (error) => {
console.error('Discord client error:', error);
errorTracker.captureException(error);
});
process.on('unhandledRejection', (reason, promise) => {
console.error('Unhandled Rejection at:', promise, 'reason:', reason);
errorTracker.captureException(reason);
});# Run tests
npm test
# Run tests with coverage
npm run test:coverage
# Run tests in watch mode
npm run test:watch# Test with real Discord API
npm run test:integration# Test complete command flows
npm run test:e2eSee the examples/ directory for complete examples:
basic-setup.js- Basic bot setupcustom-commands.js- Custom command exampleswebhook-integration.js- Webhook handlingdeployment.js- Deployment configuration
We welcome contributions! Please see our Contributing Guide for details.
- Clone the repository
- Install Node.js 16 or later
- Install dependencies:
npm install - Set up environment variables
- Start development server:
npm run dev
This project is licensed under the MIT License - see the LICENSE file for details.
- Documentation: https://docs.licensechain.app/discord-bot
- Issues: GitHub Issues
- Discord: LicenseChain Discord
- Email: support@licensechain.app
Made with �� for the Discord community
All endpoints automatically use the /v1 prefix when connecting to https://api.licensechain.app.
- Production: https://api.licensechain.app/v1
- Development: https://api.licensechain.app/v1
| Method | Endpoint | Description |
|---|---|---|
| GET | /v1/health | Health check |
| POST | /v1/auth/login | User login |
| POST | /v1/auth/register | User registration |
| GET | /v1/apps | List applications |
| POST | /v1/apps | Create application |
| GET | /v1/licenses | List licenses |
| POST | /v1/licenses/verify | Verify license |
| GET | /v1/webhooks | List webhooks |
| POST | /v1/webhooks | Create webhook |
| GET | /v1/analytics | Get analytics |
Note: The SDK automatically prepends /v1 to all endpoints, so you only need to specify the path (e.g., /auth/login instead of /v1/auth/login).