Discord.js
Node.js
Supabase
Automation
Discord Bot Automation for PoliTo Organization
Automated role assignment system for 200+ member university Discord server, reducing manual management time by 95%
200+
Active Members
95%
Time Saved
1000+
Assignments
99.9%
Uptime
The Challenge
The PoliTo student organization managed a Discord server for 200+ engineering students. Each semester, new students joined and needed appropriate course-specific roles for access to private channels. The manual process was time-consuming and error-prone:
- 2 hours per week spent manually assigning roles
- Human errors leading to incorrect permissions
- Delayed access - new members waited hours or days for roles
- No audit trail - difficult to track role changes
- Scalability issues - process didn't scale with growing membership
The Solution
I developed a Discord bot that automates the entire role assignment process with real-time synchronization and audit logging.
Architecture
- Discord.js Bot - Listens for member joins and command interactions
- Supabase Backend - Stores member data, role mappings, and audit logs
- Role Verification System - Validates university email addresses
- Automated Assignment - Assigns roles based on course enrollment
Key Features
- Self-service role selection via slash commands (
/roles) - Email verification with university domain checking
- Bulk operations for administrators
- Real-time sync with Supabase for role state management
- Audit logging - all role changes tracked with timestamps
- Error recovery - automatic retry logic for failed operations
Technical Implementation
// Slash command handler
client.on('interactionCreate', async (interaction) => {
if (!interaction.isCommand()) return
if (interaction.commandName === 'roles') {
const courses = await supabase
.from('courses')
.select('*')
.eq('active', true)
const embed = new EmbedBuilder()
.setTitle('Select Your Courses')
.setDescription('React with emojis to get course roles')
.addFields(
courses.data.map(course => ({
name: course.code,
value: course.name
}))
)
await interaction.reply({ embeds: [embed] })
}
})
// Role assignment with error handling
async function assignRole(member, roleId) {
try {
await member.roles.add(roleId)
// Log to Supabase
await supabase.from('role_assignments').insert({
user_id: member.id,
role_id: roleId,
assigned_at: new Date().toISOString()
})
return { success: true }
} catch (error) {
console.error('Role assignment failed:', error)
return { success: false, error }
}
}Results & Impact
Time Savings
- ✅ Manual assignment time: 2 hours/week → 5 minutes/month
- ✅ New member onboarding: 24 hours → instant
- ✅ Role updates: Manual → Automated
Quality Improvements
- ✅ Assignment errors: ~10/week → 0
- ✅ Uptime: 99.9% (monitored via UptimeRobot)
- ✅ Member satisfaction: Significant increase
Lessons Learned
- Start with MVP - Initially built basic role assignment, then added features based on user feedback
- Error handling is critical - Discord API rate limits and network issues required robust retry logic
- Audit logs save time - When issues arise, logs make debugging 10x faster
- User experience matters - Slash commands are more intuitive than text commands
- Documentation is key - Good README reduced support questions by 80%
Tech Stack
Discord.js v14
Node.js 18
Supabase
PostgreSQL
Docker
Interested in automation solutions?
I'd love to discuss how automation can solve your team's challenges.
Get in Touch