Welcome Contributors
Thank you for your interest in contributing to RaidBot! This guide will help you get started with development, code standards, and the contribution process.
Getting Started
Prerequisites
Install Node.js
RaidBot requires Node.js 18 or higher. node --version
# Should output v18.0.0 or higher
Download from nodejs.org
Create Discord Bot
Go to Discord Developer Portal
Create a new application
Go to “Bot” section and create a bot
Copy the bot token (you’ll need this later)
Enable these intents:
Server Members Intent
Message Content Intent
Clone and Setup
Fork and Clone
Install Dependencies
Configure Bot
Run Bot
# Fork the repository on GitHub first, then:
git clone https://github.com/YOUR_USERNAME/wizbot.git
cd wizbot
Use allowedGuildIds to restrict the bot to your test server during development.
Development Environment
Recommended tools:
Editor: VS Code with ESLint extension
Terminal: Any modern terminal with Node.js support
Git Client: Command line or GitHub Desktop
Discord: Desktop app for testing
Code Standards
Style Guide
RaidBot follows JavaScript Standard Style with some modifications.
Indentation and Formatting
Variables/Functions: camelCase
Constants: UPPER_SNAKE_CASE
Classes: PascalCase
Files: camelCase or kebab-case
// Variables and functions
const raidData = getRaidData ( messageId )
function calculateStats ( userId ) { }
// Constants
const MAX_RAID_SIZE = 50
const DEFAULT_TIMEOUT_MS = 30000
// Classes
class RateLimiter { }
class CircuitBreaker { }
Add JSDoc comments for public functions: /**
* Calculate user statistics for a guild
* @param {string} guildId - Discord guild ID
* @param {string} userId - Discord user ID
* @returns {Object} Statistics object with raid counts and roles
*/
function getUserStats ( guildId , userId ) {
// Implementation
}
Always handle errors gracefully: // Good
try {
const message = await channel . messages . fetch ( messageId )
await message . edit ({ embeds: [ embed ] })
} catch ( error ) {
logger . error ( 'Failed to update raid embed' , {
error ,
messageId ,
channelId: channel . id
})
// Graceful fallback or user notification
}
// Bad
const message = await channel . messages . fetch ( messageId )
await message . edit ({ embeds: [ embed ] }) // No error handling
Prefer async/await over Promise chains: // Good
async function createRaid ( interaction ) {
const channel = await getChannel ( channelId )
const message = await channel . send ({ embeds: [ embed ] })
await addReactions ( message )
}
// Bad
function createRaid ( interaction ) {
return getChannel ( channelId )
. then ( channel => channel . send ({ embeds: [ embed ] }))
. then ( message => addReactions ( message ))
}
Project Conventions
Use the structured logger for all logging: const { logger } = require ( './utils/logger' )
logger . info ( 'Raid created' , { raidId , guildId , userId })
logger . warn ( 'Rate limit approaching' , { userId , requests })
logger . error ( 'Database error' , { error , context: 'saveRaid' })
Never use console.log() in production code.
Always use prepared statements: // Good
const stmt = prepare ( 'SELECT * FROM raids WHERE guild_id = ?' )
const raids = stmt . all ( guildId )
// Bad - SQL injection risk
const raids = db . prepare ( `SELECT * FROM raids WHERE guild_id = ' ${ guildId } '` ). all ()
Use state.js functions for all state operations: const { setActiveRaid , getActiveRaid , deleteActiveRaid } = require ( './state' )
// Don't directly manipulate activeRaids Map
// Use the provided functions instead
setActiveRaid ( messageId , raidData )
Wrap Discord API calls with circuit breaker: const { fetchWithBreaker , sendDMWithBreaker } = require ( './utils/circuitBreaker' )
const user = await fetchWithBreaker (
() => client . users . fetch ( userId ),
null // fallback value
)
const sent = await sendDMWithBreaker ( user , 'Message content' )
Development Workflow
Feature Development
Create feature branch
git checkout -b feature/my-new-feature
Branch naming:
feature/ - New features
fix/ - Bug fixes
refactor/ - Code improvements
docs/ - Documentation updates
Write tests first (TDD)
const test = require ( 'node:test' )
const assert = require ( 'node:assert/strict' )
test ( 'should do something useful' , () => {
const result = myNewFunction ()
assert . equal ( result , expected )
})
See the Testing Guide for details.
Implement feature
Write the minimum code to make tests pass. /**
* Brief description of what this does
* @param {string} input - Description
* @returns {string} Description
*/
function myNewFunction ( input ) {
// Implementation
}
module . exports = { myNewFunction }
Test thoroughly
# Run tests
npm test
# Test in Discord
node bot.js
# Use your test server to verify functionality
Commit changes
git add .
git commit -m "feat: add new feature for X"
Use Conventional Commits :
feat: - New feature
fix: - Bug fix
refactor: - Code refactoring
docs: - Documentation
test: - Test changes
chore: - Maintenance
type(scope): brief description
Longer explanation if needed.
Explain WHY this change was made, not WHAT was changed.
Fixes #123
Examples:
feat(raids ): add automatic waitlist promotion
When a user removes their signup, the next person on the waitlist
is automatically promoted and notified via DM.
Fixes #45
fix(database ): prevent race condition in concurrent signups
Added mutex locks per raid to ensure atomic signup operations.
This prevents duplicate signups when multiple users react simultaneously.
Fixes #67
refactor(logger ): switch to structured logging
Replaced console.log calls with structured logger for better
production debugging and log aggregation.
Pull Request Process
Before Submitting
Submit Pull Request
Push to your fork
git push origin feature/my-new-feature
Create PR on GitHub
Go to the original repository
Click “New Pull Request”
Select your branch
Fill out the PR template
PR Description Template
## Description
Brief description of what this PR does.
## Changes
- Added X feature
- Fixed Y bug
- Refactored Z module
## Testing
- [ ] Unit tests added/updated
- [ ] Tested in Discord server
- [ ] Edge cases covered
## Screenshots
(If UI changes, add screenshots)
## Related Issues
Fixes #123
Related to #456
Address review feedback
Make requested changes and push updates: git add .
git commit -m "fix: address review feedback"
git push origin feature/my-new-feature
PR Review Checklist
Reviewers will check:
Code quality and readability
Test coverage
Error handling
Performance implications
Security considerations
Documentation completeness
Common Contributions
Adding a New Command
Create command file
const { SlashCommandBuilder } = require ( 'discord.js' )
module . exports = {
data: new SlashCommandBuilder ()
. setName ( 'mycommand' )
. setDescription ( 'What this command does' ),
requiresManageGuild: true , // Optional
async execute ( interaction ) {
// Implementation
}
}
Register in index.js
module . exports = [
require ( './availability' ),
require ( './create' ),
require ( './mycommand' ), // Add here
// ...
]
Add tests
const test = require ( 'node:test' )
const assert = require ( 'node:assert/strict' )
const { execute } = require ( '../commands/mycommand' )
test ( 'should handle valid input' , async () => {
// Test implementation
})
Adding a Database Migration
Add migration to runMigrations()
const migrations = [
// Existing migrations...
{
table: 'raids' ,
column: 'my_new_column' ,
sql: 'ALTER TABLE raids ADD COLUMN my_new_column TEXT'
}
]
Update schema.sql
CREATE TABLE IF NOT EXISTS raids (
message_id TEXT PRIMARY KEY ,
-- existing columns...
my_new_column TEXT
);
Test migration
# Delete test database
rm data/wizbot.db *
# Restart bot to run migrations
node bot.js
# Verify schema
sqlite3 data/wizbot.db "PRAGMA table_info(raids);"
Fixing a Bug
Write failing test
Reproduce the bug in a test: test ( 'should handle edge case correctly' , () => {
// This test should fail initially
const result = functionWithBug ( edgeCase )
assert . equal ( result , expected )
})
Fix the bug
Make the minimal change to fix the issue: function functionWithBug ( input ) {
// Add null check
if ( ! input ) return null
// Rest of logic
}
Verify fix
npm test
# All tests should pass
Issue Guidelines
Reporting Bugs
Use the bug report template:
**Description**
Clear description of the bug.
**Steps to Reproduce**
1. Run command `/create`
2. Enter invalid date
3. See error
**Expected Behavior**
Should show helpful error message.
**Actual Behavior**
Bot crashes with unhandled exception.
**Environment**
- Node.js version: v20.0.0
- Discord.js version: 14.24.2
- Operating System: Ubuntu 22.04
**Logs**
[2026-03-03T10:30:00] [ERROR] Unhandled error…
Feature Requests
**Feature Description**
Clear description of the proposed feature.
**Use Case**
Who would benefit and how?
**Proposed Implementation**
(Optional) How you think it could work.
**Alternatives Considered**
Other solutions you thought about.
Code Review
What We Look For
Does the code do what it’s supposed to?
Are edge cases handled?
Are there any logic errors?
Are there tests for new functionality?
Do tests cover edge cases?
Do all tests pass?
Is the code easy to understand?
Are variable names descriptive?
Is the logic clear and simple?
Are user inputs validated?
Are SQL queries using prepared statements?
Are Discord permissions checked?
Giving Feedback
When reviewing code:
Be respectful and constructive
Explain WHY something should change
Suggest alternatives when criticizing
Acknowledge good solutions
Good feedback:
Consider using a Map instead of an array here for O(1) lookups. With 100+ raids, the array.find() could become a bottleneck.
Bad feedback:
This is slow, use a Map.
Getting Help
Documentation: Start with these developer guides
Issues: Search existing issues on GitHub
Discord: Join the community server (link in README)
Recognition
Contributors are recognized in:
GitHub contributors page
Release notes for significant contributions
In-bot /changelog command
License
By contributing, you agree that your contributions will be licensed under the ISC License.
Quick Reference
Architecture Understand the system design
Project Structure Navigate the codebase
Testing Guide Write and run tests
Commands Reference See all available commands
Thank You
Thank you for contributing to RaidBot! Every contribution, whether it’s code, documentation, bug reports, or feature requests, helps make the bot better for everyone.