Discord Bot Auto-Role and Verification Systems in 2026
Discord raid attacks — waves of bot accounts joining to spam, mass-ping, or post malicious content — are a constant threat for growing servers. A verification system filters genuine users from automated accounts. Auto-role makes the legitimate path frictionless.
Simple Reaction Role Verification
The simplest approach: new members must react to a rules message before getting the Member role and channel access.
// On guild member join: put them in #welcome (only channel they see)
client.on('guildMemberAdd', async (member) => {
const welcomeChannel = member.guild.channels.cache.get(WELCOME_CHANNEL_ID);
await welcomeChannel.send(
`Welcome ${member}! React with ✅ to verify you've read the rules and gain access.`
);
});
// On reaction: grant Member role
client.on('messageReactionAdd', async (reaction, user) => {
if (user.bot) return;
if (reaction.message.channelId !== WELCOME_CHANNEL_ID) return;
if (reaction.emoji.name !== '✅') return;
const member = await reaction.message.guild.members.fetch(user.id);
const memberRole = reaction.message.guild.roles.cache.get(MEMBER_ROLE_ID);
await member.roles.add(memberRole);
});
CAPTCHA Verification
For servers frequently targeted by bot attacks, upgrade to CAPTCHA verification using discord-captcha:
const captcha = require('@haileybot/captcha-generator');
client.on('guildMemberAdd', async (member) => {
const cap = new captcha();
// DM the user a CAPTCHA image
try {
const dm = await member.createDM();
await dm.send({
content: `Welcome to ${member.guild.name}! Type the code shown to verify:`,
files: [cap.JPEGStream]
});
// Wait for their response
const filter = m => m.author.id === member.id;
const response = await dm.awaitMessages({ filter, max: 1, time: 120000 });
if (response.first().content === cap.value) {
await member.roles.add(MEMBER_ROLE_ID);
await dm.send('✅ Verified! Welcome to the server.');
} else {
await member.kick('Failed CAPTCHA verification');
}
} catch (e) {
// DMs disabled - fall back to channel verification
}
});
Auto-Role Without Verification (Fast Tracks)
For servers that want automatic role assignment on join (no verification):
client.on('guildMemberAdd', async (member) => {
const defaultRole = member.guild.roles.cache.get(DEFAULT_ROLE_ID);
if (defaultRole) await member.roles.add(defaultRole);
// Auto-assign roles based on account age
const accountAge = Date.now() - member.user.createdTimestamp;
if (accountAge > 30 * 24 * 3600 * 1000) { // 30 days old
const trustedRole = member.guild.roles.cache.get(TRUSTED_ROLE_ID);
await member.roles.add(trustedRole);
}
});
Account age filtering silently blocks most new bot accounts (created fresh for raids) from getting server access.