Server moderation is the most common reason communities build custom bots. While Discord's built-in AutoMod handles basics, custom bots provide the flexibility that growing communities need.
Discord's Built-in AutoMod
Before building custom moderation, use Discord's native AutoMod:
- Keyword filtering
- Spam detection
- Mention spam protection
- Link blocking
Configure through Server Settings → Safety Setup → AutoMod.
Custom AutoMod Features
Word Filter
const bannedWords = ['badword1', 'badword2'];
const bannedPatterns = [/discord\.gg\/[a-zA-Z0-9]+/i]; // Block invite links
client.on('messageCreate', async message => {
if (message.author.bot) return;
const content = message.content.toLowerCase();
// Check banned words
if (bannedWords.some(word => content.includes(word))) {
await message.delete();
await message.channel.send({
content: `${message.author}, that word isn't allowed here.`,
allowedMentions: { users: [message.author.id] }
});
await logModAction(message.guild, message.author, 'automod', 'Banned word detected');
return;
}
// Check patterns
if (bannedPatterns.some(pattern => pattern.test(message.content))) {
await message.delete();
return;
}
});
Spam Detection
const messageCache = new Map();
client.on('messageCreate', async message => {
if (message.author.bot) return;
const key = message.author.id;
const now = Date.now();
if (!messageCache.has(key)) {
messageCache.set(key, []);
}
const userMessages = messageCache.get(key);
userMessages.push(now);
// Keep only messages from last 5 seconds
const recent = userMessages.filter(t => now - t < 5000);
messageCache.set(key, recent);
// More than 5 messages in 5 seconds = spam
if (recent.length > 5) {
await message.member.timeout(60000, 'Spam detection');
await message.channel.send(`${message.author} has been muted for spam.`);
}
});
Raid Protection
Detect mass joins:
const joinCache = [];
client.on('guildMemberAdd', async member => {
const now = Date.now();
joinCache.push({ id: member.id, time: now });
// Clean old entries
while (joinCache.length > 0 && now - joinCache[0].time > 10000) {
joinCache.shift();
}
// More than 10 joins in 10 seconds = potential raid
if (joinCache.length > 10) {
// Enable verification level
await member.guild.setVerificationLevel(4); // VERY_HIGH
// Alert admins
const alertChannel = member.guild.channels.cache.find(c => c.name === 'mod-alerts');
if (alertChannel) {
await alertChannel.send('@here Potential raid detected! Verification level increased.');
}
}
});
Warning System
// Track warnings in database
async function warnUser(guildId, userId, moderatorId, reason) {
const warning = await db.prepare(`
INSERT INTO warnings (guild_id, user_id, moderator_id, reason)
VALUES (?, ?, ?, ?)
`).run(guildId, userId, moderatorId, reason);
// Check total warnings
const count = db.prepare(
'SELECT COUNT(*) as count FROM warnings WHERE guild_id = ? AND user_id = ?'
).get(guildId, userId).count;
// Auto-escalation
if (count >= 3) {
// Auto-timeout after 3 warnings
const member = await guild.members.fetch(userId);
await member.timeout(3600000, 'Accumulated 3 warnings');
}
return { warningId: warning.lastInsertRowid, totalWarnings: count };
}
Logging
Mod Log Channel
async function logModAction(guild, user, action, reason, moderator) {
const logChannel = guild.channels.cache.find(c => c.name === 'mod-log');
if (!logChannel) return;
const embed = {
color: action === 'ban' ? 0xFF0000 : action === 'warn' ? 0xFFAA00 : 0x00FF00,
title: `${action.toUpperCase()}`,
fields: [
{ name: 'User', value: `${user.tag} (${user.id})`, inline: true },
{ name: 'Moderator', value: moderator ? moderator.tag : 'AutoMod', inline: true },
{ name: 'Reason', value: reason || 'No reason provided' }
],
timestamp: new Date().toISOString()
};
await logChannel.send({ embeds: [embed] });
}
Audit Trail
Log every moderation action to the database for accountability and appeals:
INSERT INTO mod_actions (guild_id, target_id, moderator_id, action, reason, timestamp)
VALUES (?, ?, ?, ?, ?, CURRENT_TIMESTAMP);
Deployment
A moderation bot needs true 24/7 uptime - it can't protect your server while offline. Space-Node's Discord Bot hosting provides reliable uptime, even on the free plan, ensuring your moderation bot is always active.
For larger communities (1000+ members), consider the Middle or Large plan for the additional RAM needed to cache member data and process messages efficiently.
