HOME ABOUT ME ARTICLES

Discord Chatbot

Hey o/

This project started almost 10 years ago; some of the algorithms used can be seen as outdated. The writing style is also quite different from the other article, as I'm not focusing on how the program works, but instead, why and what is in the program.

Introduction

At a time when Discord did not exist, my peers and I used Skype to communicate. Skype was missing quite a few commands, and I wanted to customize every interaction I could have with it. The solution I came upon was to create a Chatbot that would allow me to add custom commands and, with that, new functionality to Skype.

As I worked on this project for almost 10 years, it went through many changes, the most noticeable being when we migrated to Discord. There have been quite a few refactorings, and it would not be interesting to focus on this project to see how every line of code works. To still have an idea of what is and what is not inside this project, we will expand on every milestone.

Image search

After some implementation of static commands (in a really, really messy way, without any software architecture, no design pattern, just pure spaghetti code), the need to have something that would be able to search for an image and return it into the conversation arose.

As we loved to add image reactions, having a command that would be able to scrape them from the internet and send them to the conversation would simplify our research a lot. To do so, I opted to implement some API searches, allowing me to learn how web APIs worked and how to parse JSON or XML.

The command that emerged the most from these API implementations was the one that could allow us to search on Tenor, enabling us to search for GIFs without having to go directly to the website.

More API implementation

Following this, I was looking for more APIs to implement, and this led to the creation of one of them: DTC API, which could scrape from the DTC website (a collection of quotes from IRC, kind of like bash.org).

This also led to the implementation of the OSU API, as my friends and I were avid players at the time. This implementation would allow us to have a few commands to see other profile data and best maps but would also update us automatically when one of us would rise in rank.

This would be particularly interesting for me, as I needed to take into account refresh rates, storing data for when the bot was down (and not spamming on restart), and allowing me to improve my understanding of the OAuth2 protocol.

Transition to Discord

During the transition to Discord, as it was a more structured API with an implementation already in place in Java (JDA), I decided to refactor all my code. As I was pursuing my Associate Degree in Computer Science, I was learning new design patterns and tried to have a more suitable structure for my code. This led to the use of the Commands Design Pattern, which would allow me to add more commands more quickly.

I also decided to add an analysis of the users' actions, recording time in vocal chat, messages sent, and activities to create a profile for each user and induce further interactions, with levels, stats, and money. This would be slowly abandoned, as it didn't achieve the interactions wanted.

Chatbot

During this time, I started to be interested in NLP and decided to implement a way for my bot to chat with users. I prefer to note here that this was done in early 2018. The first LLM was created during this time, in June 2018, and I was not in the capacity to recreate or use it.

To do so, I parsed all the conversations we had in Skype and Discord and created a Markov chain for each word. By doing so, each word had children that were weighted by the number of times they appeared after the current word. For example, the word 'je' could be followed by 'suis' with a higher weight than the word 'taquine,' which was rarer in our conversation. Each sentence started with the token __START__ and finished with the token __END__ to stop any recursion.

With this Markov chain, I tried multiple ways to create sentences that made sense, with the Minimax algorithm, Quickselect, or anything that could allow me to choose the word best suited for the situation. Unfortunately, as I didn't think of taking into account the sentences the user was saying, this didn't go well, and the sentences were mostly random.

It did create some coherent answers, however, that I will translate here:

Answer

User : @Djeff Thanks for distracting me

Djeff : Do not ask too much of me

Answer

Djeff : This software is dangerous

User : But User : You are the software @Djeff

Djeff : Please ?

Refactoring

As the code was becoming more and more of a mess, I decided to refactor it again, working on a better structure, organizing the program by module and commands, and allowing me to quickly access a part of the code. This, unfortunately, led to the loss of a few commands, as I did not recreate the ones that were not being used.

The second objective of this refactoring was to have a more global bot that would have different commands by server, different logs, and would not mix chats between these servers, allowing me to add the bot to other servers with people who would not speak to the first server.

RSS Feed

Some of the websites I used to visit regularly were arXiv, by the University of Cornell, which would list scholarly articles in many fields. To allow me to be notified when a new article was being published, I decided to access the RSS feed of the website and publish it on Discord.

Instead of following the messy way I did when connecting to the Osu API, I decided to broaden my vision and allow the addition of any RSS feed, given the link to the bot. The bot would then query the server regularly to notify the server of new content.

Music

This project started at the beginning of the transition to Discord; however, as it is a constant fight between me and YouTube, it is also the most requested command by my users and the most updated over time. The objective was to allow users to listen to music directly in the voice channel by linking the music they wanted to the bot.

Using the GitHub project LavaPlayer, this was quite an easy task at first, requiring me to update it and my code quite often, as YouTube does not like what it considers bot accounts. It was fun nonetheless, as it required me to have a FIFO list and allow users to add, remove, pass, or any command you would think of with music bots.

Unfortunately, I lost the war as the latest version of Lavaplayer requires the bot to be in a Docker environment to switch through different virtual environments to scrape YouTube videos and avoid being banned. The VPS my bot is running on doesn't have the resources to run a Docker environment, and so this part has been on hold since 2024.

Discord Wrapped.

With the keen interest in the yearly wrapped content these last years, I decided to create custom videos for each of my users generated based on the different data I harvest on their servers: time spent in vocal chat, time muted, messages sent, commands used, and so on.

The video was generated directly with Java, saved in case the user tried to ask the bot multiple times to generate the same video, and uploaded when asked.