cordify-plus
v1.0.0
Published
Premium Discord bot framework with plugin system, advanced event handling, and comprehensive logging
Maintainers
Readme
Cordify+ 🚀
Cordify+ is a premium Discord bot framework with advanced plugin architecture, comprehensive event handling, and professional-grade logging. Built for developers who need a robust, extensible foundation for Discord bots.
✨ Features
- 🔐 Authentication System - Secure username/password authentication for authorized users only
- 🧩 Plugin/Extension System - Auto-discovery and hot-reload support for modular bot features
- ⚡ Advanced Event System - EventEmitter-based architecture wrapping Discord.js events
- 📝 Professional Logging - Winston-based logging with configurable levels and outputs
- ✅ Config Validation - Joi schema validation ensuring proper configuration before startup
- 🎯 Command Management - Support for both prefix and slash commands
- 🧪 Testing Utilities - Mock Discord entities for unit testing
- 🔄 Plugin Lifecycle - Clean initialization, loading, and unloading of plugins
📦 Installation
npm install cordify-plus🚀 Quick Start
Note: The authentication system is a feature for bot operators to control who can run their bot. It does NOT affect npm installation - anyone can install this package normally with
npm install cordify-plus.
1. Create a Bot Instance
const { CordifyClient } = require('cordify-plus');
const bot = new CordifyClient('./config.json');
bot.start().catch(error => {
console.error('Failed to start bot:', error);
process.exit(1);
});2. Configure Your Bot
Create a config.json:
{
"discord": {
"token": "YOUR_DISCORD_BOT_TOKEN",
"prefix": "!",
"intents": ["Guilds", "GuildMessages", "MessageContent"]
},
"auth": {
"enabled": true,
"usersFile": "authorized-users.json"
},
"logging": {
"level": "info"
},
"plugins": {
"directory": "plugins",
"autoLoad": true
}
}3. Set Up Authentication (Optional)
Authentication is disabled by default. To enable it, set auth.enabled: true in your config and create authorized-users.json:
{
"users": [
{
"username": "your-username",
"password": "your-password",
"note": "Main admin"
}
]
}When authentication is enabled, you'll be prompted for credentials when starting the bot.
🧩 Creating Plugins
Plugins are the core of Cordify+. Each plugin is a self-contained module in the plugins/ directory.
Plugin Structure
plugins/
└── my-plugin/
└── index.jsExample Plugin
module.exports = {
name: 'my-plugin',
version: '1.0.0',
description: 'My awesome plugin',
dependencies: [],
async init(context) {
const { client, logger, eventSystem, config, registerCommand, on, emit } = context;
logger.info('My plugin is initializing!');
// Register a command
registerCommand({
name: 'hello',
description: 'Say hello',
execute: async (message, args) => {
await message.reply('Hello from my plugin!');
}
});
// Listen to events
on('ready', (client) => {
logger.info(`Plugin ready! Connected as ${client.user.tag}`);
});
on('messageCreate', (message) => {
if (message.content.includes('hello')) {
logger.debug('Someone said hello!');
}
});
},
async destroy(context) {
context.logger.info('My plugin is shutting down...');
}
};📚 Plugin Context API
When your plugin's init() function is called, it receives a context object with:
| Property | Description |
|----------|-------------|
| client | The Discord.js client instance |
| logger | Logger instance for your plugin |
| eventSystem | Event system for emitting/listening to events |
| config | Your plugin's configuration from config.json |
| registerCommand(cmd) | Register a prefix or slash command |
| on(event, listener) | Listen to an event |
| emit(event, ...args) | Emit a custom event |
🎯 Command Types
Prefix Commands
registerCommand({
name: 'ping',
description: 'Check bot latency',
aliases: ['p'],
execute: async (message, args) => {
const latency = Date.now() - message.createdTimestamp;
await message.reply(`Pong! ${latency}ms`);
}
});Slash Commands
registerCommand({
type: 'slash',
name: 'greet',
description: 'Greet a user',
options: [
{
name: 'user',
description: 'User to greet',
type: 'USER',
required: true
}
],
execute: async (interaction) => {
const user = interaction.options.getUser('user');
await interaction.reply(`Hello, ${user}!`);
}
});🎪 Events
Cordify+ emits various events you can listen to:
Discord.js Events
ready- Bot is readymessageCreate- New message receivedinteractionCreate- Interaction receivedguildMemberAdd- Member joined a guildguildMemberRemove- Member left a guild
Cordify+ Events
commandInvoked- Prefix command was executedslashCommandInvoked- Slash command was executedcommandError- Error in command executionpluginLoaded- Plugin was loadedpluginUnloaded- Plugin was unloadedallPluginsLoaded- All plugins finished loadingshutdown- Bot is shutting down
🧪 Testing
Cordify+ includes testing utilities for unit testing your plugins:
const { TestUtils } = require('cordify-plus');
const { createMockMessage, createMockChannel, simulateCommand } = TestUtils;
describe('My Plugin', () => {
test('ping command responds', async () => {
const channel = createMockChannel();
const message = createMockMessage('!ping', null, channel);
// Your command logic here
await message.reply('Pong!');
expect(channel.getLastMessage().content).toBe('Pong!');
});
});📝 Logging
Use the logger provided in your plugin context:
logger.error('Something went wrong!');
logger.warn('Warning message');
logger.info('Info message');
logger.debug('Debug details');Set log level via environment variable:
LOG_LEVEL=debug node bot.js⚙️ Configuration Schema
Cordify+ validates all configuration at startup. Required fields:
{
discord: {
token: string (required),
intents: string[] (optional),
prefix: string (default: '!')
},
auth: {
enabled: boolean (default: true),
usersFile: string (default: 'authorized-users.json')
},
logging: {
level: 'error' | 'warn' | 'info' | 'debug' (default: 'info'),
file: string | null (default: null)
},
plugins: {
directory: string (default: 'plugins'),
autoLoad: boolean (default: true),
hotReload: boolean (default: false)
}
}🔄 Plugin Lifecycle
- Discovery - Cordify+ scans the plugins directory
- Load - Each plugin's
index.jsis required - Validate - Plugin metadata is checked
- Initialize - Plugin's
init()function is called - Register - Commands and event listeners are registered
- Ready - Plugin is active and running
To unload/reload a plugin programmatically:
bot.getPluginManager().unloadPlugin('my-plugin');
bot.getPluginManager().reloadPlugin('my-plugin');🛡️ Error Handling
Cordify+ automatically:
- Catches and logs plugin errors without crashing the bot
- Wraps command execution in try/catch
- Handles unhandled promise rejections
- Gracefully shuts down on SIGINT/SIGTERM
🌟 Environment Variables
DISCORD_TOKEN=your_token_here
LOG_LEVEL=info
NODE_ENV=development📖 Examples
Check the example/ directory for:
- Complete bot setup
- Sample configuration
- Example plugin demonstrating best practices
🤝 Contributing
To create a new plugin:
- Create a folder in
plugins/ - Add an
index.jswithname,version,init() - Register commands and event listeners in
init() - Test thoroughly
- Share with the community!
📄 License
MIT
🔗 Links
Made with ❤️ for the Discord bot development community
