When making a community server on Social Media platform like Discord, we would want a moderation application which can look after day to day duties, there are a wide variety of applications which can help with different functionality and many with unused features which creates a overwhelming feeling while surfing through their commands and other features.
Facing a similar problem, I have decided to start my programming journey by building a discord application for the Writer Community - Nova Archives, Arlo, which can manage day to day moderation duties on the server and other community related commands tirelessly throughout the server.
Arlo is purely built on JavaScript, being able to react to messages when called out, to banning members on the will of the moderators. It's a widely customizable bot, with action logging features.
Decisions During Development
Every project has moments where you could have gone one way and chose another. These are the ones that actually shaped how Arlo works.
Splitting the Files
The first version of Arlo was a single index.js file that did everything — message creation logic, slash commands logic, bot startup, all of it in one place. It worked perfectly, but every time I needed to find something specific to edit a small typo or to implement a small change I was scrolling through hundreds of lines looking for the right block. The moment I added the report command and the availability toggle in the same week, the file became genuinely difficult to navigate.
I restructured it into an events folder with separate files — messageaction.js for everything Arlo responds to in messages, slashcom.js for every slash command and buttonhandlers.js for button logic. index.js now just starts the bot and loads everything else. The actual code didn't change at all. But the moment I needed to debug something, I knew exactly which file to open. That's the whole point of structure — not performance, not best practice for its own sake, just not wasting your own time later.
Why report commands opens a thread automatically under the Embed
The basic version of a report command sends an embed to the respective staff channel and that's it. Mods see it, handle it, move on. I built it that way first.
The problem is that "handle it" has no paper trail. Who responded? What was decided? When was it closed? A channel full of lifeless report embeds with no conversation attached to them is just noise — you can't tell at a glance which ones were resolved and which ones were ignored.
Making Arlo open a thread on every report embed changed the whole workflow. The discussion about the reporting of a user happens inside the opened thread, the resolution gets posted inside the thread and later closing the thread signals completion. Six months from now if someone asks "what happened with that report about X," the answer is findable because the thread exists. I didn't plan this upfront — I noticed the problem after about a week of using the simpler version and it just took one afternoon to fix. But it's probably the decision that made the most practical difference to how the server actually runs.
The availability toggle removing mod roles instead of just adding one
When I built the "Shelved Editor" toggle button that lets staff mark themselves as unavailable — my first instinct was to just add a role. Press button, get role, everyone can see you're unavailable. Simple.
Then I thought about what actually happens when a mod is marked unavailable but still has their mod role visible. When the moderator roles are pinged by other moderators or Arlo when opening threads, the moderator gets pinged anyway if they still had their role on their profile. So I made the toggle remove the active mod roles when it adds the unavailable one, and restore them after it's toggled off. Now the member list tells the truth — if you don't see a mod role, that person genuinely isn't available right now. The role isn't cosmetic anymore, it's functional. One extra line of code, completely different meaning.
What Arlo Taught Me
The biggest thing this project taught me was that Discord's interaction model punishes you immediately for not understanding async — everything that felt like a bot problem was actually a timing problem.
Arlo isn't finished. Honestly, I'm not sure it ever will be — and I think that's the point. Nova Archives needed a librarian. I needed a project that would fight back. We found each other.
Top comments (0)