RoosterBot is a Discord bot that allows users to see information on any schedule. Currently, it exists in the Discord server for the Gamedev/artist course I am attending, and allows the students to instantly see their upcoming classes from inside Discord.

The gist

Users can look up information about their classes, their teachers’ classes, or any room. It supports some autocorrection when looking up teachers.

The bot is written entirely in C# and the source code can be found on GitHub. It is currently running on Amazon AWS, and deployment of new versions is automated. While it is currently only connected to one Discord server it could be deployed to other servers with only minor modifications, and it could work with more than just school schedules.

It has been a living project since September 2018 and I intend support it until at least after I finish the course, and it will continue to exist even after that.

In February 2019 I released a new feature that lets people plan a train journey from within Discord. This uses the public API of the NS Reisplanner, and the C# interface to this API was built entirely by myself.

In April 2019 I released a beta feature that uses IBM Watson Assistant to let users ask the bot questions in natural language. Instead of learning commands like “!dag 2gd1 woensdag”, you could say “@RoosterBot wat heeft 2gd1 op woensdag” and get the same answer. This stops new users from having to learn commands, making it easier to use.

In the same update, I made it possible for users to register their class, so that they no longer have to enter their class every time they use a command. This uses a very simple NoSQL database running on Amazon DynamoDB, which could easily be extended to support much more information for individual users.

The code

The entire code can be found on Github, but here are some of the highlights. Given the changing nature of all the code, I will link to individual files here, but place extensive explanations.

Editable commands

The abstract class RoosterModuleBase together with the CommandResponseService give a command functionality that I have yet to see in other Discord bots: when you send a command, and then edit that message, the bot will pick that up and re-execute your command, editing its response instead of sending a new message. The class also detects when users delete their commands, and deletes the response as well. This allows users to fix typos in their commands without re-typing the whole thing.

This is done using a ConcurrentDictionary with the command ID as the key, and a pair of a command message and response message as the value. Every time a message is updated, the class searches for its ID in the dictionary, and if it finds one, it will execute the new value of the message. The Reply function called by the command functions will also update the initial response, instead of sending a new message.

“And then?”

After receiving any schedule information, users can use the “daarna” command which shows them the schedule record that comes right after the last thing they were shown. This is done using the LastScheduleCommandService, which keeps track of the last piece of information served per-user, in a way similar to the CommandEditService. I didn’t merge the two classes, though, because of a design choice: there are commands that should not have the editability feature, and not all commands are related to schedules.