My Custom Discord bot, with a Hint of Ventrilo
Back when I was in high school I used to game [A LOT] with a group of guys. We gathered together, virtually, from different parts of the world to play some of the best titles of that era (CS 1.5, COD1, COD2, COD4, etc.)
Before tools like Discord popped onto the scene we used Ventrilo to communicate in and out of game. We hosted our own server, a place where we got together to hang out and play competitively.
Fast forward 10-15 years, we've all grown up and one-by-one began to gather once again.
Two of the original members (myself included) started a private Discord server, a few years later, we have ~60 active members at any given time.
Ventrilo's best feature
We quickly realized Discord was missing 1 major feature we loved from Ventrilo, that of the Channel Announcer. We would typically run Ventrilo in the background while we gamed in the foreground. When someone would join or leave a channel you were in, Ventrilo would announce that person's name, this way you could tell who it was (duh).
Discord has an in-game overlay that visually shows you who's in the channel, but, we typically disable it (in order to improve in-game performance).
Discord has an awesome API, so I decided to build a bot to replicate that old channel announcing feature we loved from Ventrilo. I wrote the bot in Javascript/Node and it works great!
Here's a bit of the code that listens for voiceStatusUpdates:
1client.on('voiceStateUpdate', (oldMember, newMember) => {2 // ...3 if (4 newMember.voiceChannel &&5 client.voiceConnections.find(6 (item) => item.channel === newMember.voiceChannel,7 )8 ) {9 announce.sayJoin(newMember)10 } else if (11 oldMember.voiceChannel &&12 client.voiceConnections.find(13 (item) => item.channel === oldMember.voiceChannel,14 )15 ) {16 announce.sayLeave(oldMember)17 }18})
The announce module has sayJoin and sayLeave methods that synthesize the member's name + their phrases using a text to speech service. The bot then caches the resulting .wav file for future events.
I took it a step further and allow users to modify their join/leave phrase in order to introduce some personalization.
This bot also announces when a member mutes, deafens, or starts streaming (which can all optionally be turned off).
Stats
I love a good stat dashboard as much as the next person, and i've been really keen on using Grafana for everything lately.
I setup a Prometheus extractor to read from the bot's database and report (every 15s) on a few stats, in realtime.
- CPU, Memory & Heap usage of the Docker process.
- Total number of servers the bot is in.
- Total number of actions responded to (join/leave events).
- Total number of phrases directly edited by users.
Ventrilo Inspired Commands
1// Customize the default join/leave phrase for the server2!default34// Disable the announcement of a specific events5!disable-event67// Enable the announcement of a specific events8!enable-event910// List the state of all announcement events (if they are enabled or not)11!events1213// Joins the user's current voice channel14!join1516// Leaves the user's current voice channel17!leave1819// A list of phrases added for this server20!list2122// Add a join or leave phrase for a member23!phrase2425// Rejoin the user's current voice channel26!rejoin2728// Reset a user's join/leave phrase to the default server value29!reset3031// Says a phrase in the users current voice channel32!say3334// Sends a test phrase to the bot's current voice channel35!test3637// Sets the server's voice. Use the voices command for a list of all available voices.38!voice3940// A list of available voices you can choose from.41!voices
Additional Miscellaneous Commands
1// Lists all command groups2!groups34// Enables a command or command group5!enable67// Disables a command or command group. (good for disabling a command if it's being abused)8!disable910// Displays a list of available commands, or detailed information for a specified command11!help1213// Shows or sets the command prefix14!prefix1516// Checks the bot's ping to the Discord server17!ping1819// How long the bot process has been running.20!uptime
Admin Commands
1// Forces the bot to disconnect and reconnect to discord2!restart
What Next?
Currently the bot is private, but i've been getting requests from others who want to add it to their server as well (awesome!).
I've got some refactoring to do (ideally a re-write in Typescript) and enable sharding so it can scale to hundreds of servers.
I'll most likely open-source it as well. Stay tuned!
Edit 2020:
I've completely re-written this bot in Typescript using the latest Discord.js library. It has been submitted to top.gg (a Discord bot search directory), so that anyone can install it on their own server for free.
Edit 2021:
I've renamed this bot to KITT
(shout out to Knight Rider) and the
code is up on Github . This bot
was also verified by Discord for surpassing 100 servers and now sports the
verified-check badge!