The History of Ren Bot

Four and half years later, I outline some of the adventures behind Ren bot with respect to the SFU Anime Discord server, and where we're headed next.

The Days of Ren (Red) v2

When we first started using Ren, she was based off of (what is now dubbed as) version two of Red-DiscordBot (note: Ren and Red might be used interchangeably in the post, but ultimately refer to the same thing). It used a pre-stable version of discord.py (v 0.16.x), which is what allows the bot to communicate with Discord. They were both written in a programming language called Python, which, at the time, I knew pretty much nothing about. We had a few custom modules that Julian found, and there were things that I didn’t like about it, so I started out modifying things here and there for it. Below is a chronological order of when some of the relevant things began.

A Web Portal for Ren

One of the first things we started to work on was a web portal for Ren’s data. For those of you that were in Fall 2016, dubbed as SAD Season 1, you’ll remember the #bot-spam economy frenzy, where many people, including myself, spammed renpayday and renslot 100 in hopes to be at the top of the leaderboard, which you could view with the renleaderboard command. Unfortunately, what you could see was pretty limited: you could only see the top 10 users, and nobody else. The goal of the web portal was to show the read-only data of the club’s leaderboard on who had the most currency on the server. I followed by adding a similar page of duels, a cog that allowed you to randomly battle it out with other users, and for games.

We played around with Ren’s local playlist ability, which lets you upload songs to the bot in the backend and play songs from there. We did add the ability to upload songs from the web, but that was super sketchy on the security-side, so we ended up taking that down and only listing the available playlists from the server:

This web portal still exists today, but it’s pretty much no longer maintained because I wasn’t a fan of doing UX design, and nobody else picked it up. (but honestly, it was cause I sucked at it :D)

For those that are interested, the portal is accessible at ren.injabie3.moe or ren.sfuani.me.

System Backups

As Ren was hosted locally, having a backup in case of a catastrophic failure is super important. I had fortunately learned about backing up virtual machines in my co-op position prior, so I was able to add Ren to my ongoing weekly backups. We eventually moved to monthly backups, cause weekly was a bit overkill and required me to free up a lot of space.

A log from one of the first backups created for Ren.

I am a big fan of transparency where possible, so I eventually hooked it up to our backend so that mods and execs would know when backups were happening.

Webhooks notifying SAD when a backup was occuring.

Uptime Checks

The -status channel for our uptime checks, on a separate server.

As Ren was starting to become more prominent on the server, we decided to hook up the server to an uptime checker. The one we used was called StatusCake, which I actually found Dean Herbert, the creator of osu!, using back then. Essentially, StatusCake tries to access an IP address and its corresponding port to see if it’s responding, and if it’s not, we get notified within 5 minutes. Huge shoutout to StatusCake’s free tier that lets us have quite a few uptime checks with 5 minute intervals (you can pay to have shorter ones, but because we’re a club and I was a broke student, we stuck with the free tier).

Eventually, we migrated the check to check a public facing webpage, that would be updated by a Heartbeat cog that I would make in early 2018.

Having uptime checks has proven to be quite useful, as we weren’t always on the Discord server. This allowed us to typically respond within 10 to 15 minutes if we were alerted and awake at the time. As a user, we expose the status page to you, which is viewable at status.injabie3.moe and status.sfuani.me.

Our First Cog

In February 2017, I created my first cog called catgirl. The idea came about because there was another bot (Yuki) that did something similar. Essentially, all it did was post a random image of a catgirl from a database that I curated. I stored the images on my own server, and referenced them from the bot. Below is a sample output from back in the day:

The first version of the catgirl cog.

In terms of Python code, this was the first time we started to use git to manage our code changes. We kept the changes in a separate repository: one that I called lui-cogs. I look back at my commit messages, and definitely see my old self still learning how to use git. Nonetheless, I remember being super fascinated by seeing my own code run on the Discord server for the first time. Python was pretty easy to pick up, and I had lots of reference code to look at for help.

The Start of More Features

At this point, sedruk and I were starting to get the hang on how to make cogs. sedruk helped add RSS feeds into the server, which is what you’ll see in -news. It was intended to replace Tatsumaki’s version with ours. It didn’t support adding RSS feeds from within Discord: you had to manually edit a file and reload it in order to get new feeds in.

The first rendition of Ren’s RSS feed poster.

He also got the earliest version of our Highlight cog working. For those that aren’t familiar with Highlight, it allows you to subscribe to words of interest, and Ren will notify you if its mentioned in a text channel, allowing you to jump into conversations that interest you. Apparently, it’s similar to a feature in Slack, but since I haven’t used Slack very much, I can’t confirm. I definitely use it to keep tabs on things I’m interested in, like figures:

The first version of Ren’s highlight cog.

While sedruk worked on that, I worked on the welcome cog. When a user joined the server, it would send a direct message to them, and we would log it in a moderator channel in case we needed to reference it in the future. We would also log when a user left for the same reason.

The first version of the welcome DM from Ren.
How we keep tabs on who joins and leaves the server.

As you can probably tell, many of the features we created were utility-related. They were meant to help simplify various things, such as making it easier to join in on conversations when it’s about a topic you’re interested in, getting the latest anime news, or making sure people see server information in their DMs. I’m not really a game person, so I never really opted to create anything that resembled a game into Ren. Maybe that will change in the future.

The Infamous Word Filter

Before we had Ren doing filtering, Mee6 did the filtering for us. We employed the use of a filter in order to deter people from talking about topics not suited for a safe, university environment. At the time, when Mee6 detected a filtered out word in a large message, it would just delete the entire message and ping you to watch your language.

While we were working on Highlight and Welcome above, sedruk also worked on this utility cog. The main goal was for Ren to only remove the censored word in general, but preserve the rest of the message. He added some regex replacements, and we ended up with the first rendition of better filtering by Ren. Shortly after ironing out some other small issues and converting it into an embed, we disabled the Mee6 filter. Good riddance!

One of the first renditions of Ren’s smarter word filtering.
We even have a video dedicated to annihilating Mee6’s LANGUAGE filter, courtesy of Hish.

Starboard

Aside from creating things on our own, we also incorporated things from other developers. For example, there’s a feature named starboard that allows users to react to messages with a specific emote which would have it appear in a separate channel with the emoji count. This way, the channel would contain messages that others found interesting and would let others see it. We essentially took Rapptz‘s RoboDanny implementation (back in 2017) and went with it. Note that Rapptz is the person behind the discord.py library. We called it a highlight reel (not to be confused with the highlights cog above).

As I don’t have a screenshot from back in the day, here’s how it looks like today:

How starboard looks (though this is a v3 screenshot, but it was very similar in v2).

Tags and Custom Commands

Another feature that Ren had was custom commands, which was maintained by the upstream developers under the CustomCommand cog. The moderators on admins on the server used this quite a bit, adding short, little commands that others used.

While we got Starboard into Ren, sedruk and I found that Rapptz’s RoboDanny also had Tags, which did the same thing, except with a few nice additions:

  • There was a sense of ownership: you could see who created a tag and when it was created.
  • There was tag usage information: you could see how many times a tag was being used

Naturally, we added into Ren, but we faced resistance in having it replace CustomCommand, as many people liked typing renhbd as opposed to rentag hbd. As such, we restricted its usage to moderators and above while we played around with it.

In October 2017, we modified CustomCommand so that the Sensei role could add custom commands. This was a nice addition to the server, as it allowed members of our community to create bot commands that had the bot repeat things back to us instead of having to go through a moderator or exec. Unfortunately, as time passed, issues began to arise. Although we allowed members with the Sensei role to add commands, they had no way of actually editing or removing such commands. This meant that if they messed up adding a custom command, they would have to contact a mod or exec in order to get it fixed.

As more and more people got the Sensei role, having moderator intervention was no longer feasible to do. In 2018, after discussing with those in the club, we wanted more flexibility with it. We wanted people to be able to add, remove, and edit their own custom commands without having to bug a moderator. Since tags essentially had everything we needed, we just had to somehow “hook” it in with shorter commands After tinkering around with it some more, we managed to couple Tags with the built-in Alias cog. As its name implies, Alias allows you to create a [command] alias that can call another command. We managed to alias renhbd to rentag tbd, and had a strong case for moving to it.

In late-April 2018, we managed to convert all custom commands into tags, and aliased everything with the following little code snippet that I didn’t commit to git. With that, we were free of CustomCommands and into the world of Tags!

[git:V2/prod] ren@LuiV-Silica:~/github/Ren/scripts$ ls -al
 | grep cc
-rwxrwxrwx 1 ren ren  953 Apr 30  2018 cc_to_tags.py
[git:V2/prod] ren@LuiV-Silica:~/github/Ren/scripts$ cat cc_to_tags.py
from cogs.utils.dataIO import dataIO

importedData = dataIO.load_json("data/customcom/commands.json")
tagsData = {}
aliasData = {}
serverID = "222841664585072641"
userID = "233118137313132544"

tagsData[serverID] = {}
tagsData["generic"] = {}
aliasData[serverID] = {}

for key, value in importedData[serverID].items():
    tagsData[serverID][key] = {}
    tagsData[serverID][key]["location"] = serverID
    tagsData[serverID][key]["name"] = key
    tagsData[serverID][key]["__tag__"] = True
    tagsData[serverID][key]["uses"] = 0
    tagsData[serverID][key]["created_at"] = 1491877678.977568
    tagsData[serverID][key]["owner_id"] = userID
    tagsData[serverID][key]["content"] = value

    aliasData[serverID][key] = "tag {}".format(key)


dataIO.save_json("data/tags/tags.json", tagsData)
dataIO.save_json("data/alias/aliases.json", aliasData)

print("CustomCom converted to Tags and Alias.")

TempChannels: the birth of #dark-hour

After a year since the inception of SAD, in September 2017, we received a request from Julian to create a temporary text channel that would last for around 8 hours, and be automatically deleted at the end of those 8 hours. This channel was previously known #dark-hour, and is now replaced by #after-hours. I won’t dive into the details of it, so here’s a screenshot of when it was first announced:

The broader announcement post
The aftermath of dark-hour day 1 (slightly unrelated, but because TempChannels is behind it, here it is)

Its implementation spanned a week during the start of my 4th year, where I treated it like a hackathon project. It required creating a text channel, overriding the channel permissions so that only certain roles could see it, and then deleting the channel at the end of its duration. We got it up and running within a week, and its implementation is still being used today. Surprisingly, there haven’t been too many issues with this cog. Below is a GIF of us doing some initial testing before going live.

Testing out TempChannels on my alt account to see if the NFSW prompt appeared.

SFU Courses?

In 2018, we noticed that Brendan Chan, who was part of SFU’s Computing Science Student Society, had an API for accessing SFU courses through SFU’s externally facing API. We ended up taking his implementation and adding it to Ren, with some tweaks to make it work. We added it to our GitHub repository about half a year later, in November.

You can look up SFU courses within Discord!

The Snowpocalypse at SFU

For those that were on campus in the Spring 2019 semester, you’ll remember that the snowfall was particularly brutal. In February, we had a lot of snowfall come down overnight, and many people were wondering if school would be closed.

Luckily for us, SFU has public webcams available. Because we didn’t want to leave Discord, and modern problems require modern solutions, we added SFU cameras into Ren, which basically downloaded the public webcam image and reposted it on SAD. We couldn’t link it directly because Discord would cache the image, and the image updates every 15 seconds, hence the reposts.

SFU also has another API for road reports, which we added the following day. Really neat to bring in school status reports and what not into the Discord server. Now there’s one less thing to switch tabs for!

Another addition to Ren’s growing capabilities.
The SFU Road Report, posted on SAD.

Other Cogs

Some other cogs that we made include, and are not limited to:

  • Birthday: a cog that applies a special role on your birthday so everyone on the server knows!
  • RoleAssigner: a cog that assigns special colour roles to members, which we use for special occasions, such as Halloween or Christmas.
  • Spoilers: A reaction-based spoiler cog before the days of integrated Discord ||spoilers||.
  • Ranks: An old Mee6 copycat. Used it as a basis for trying out some database concepts I was learning back in my third year of school.
  • Triggered: A cog that basically performs image transformations on a user’s avatar.
The wonderful product of the Triggered cog.
Injabie3
Injabie3

Just some guy on the Internet that writes code for fun and for a living, and also collects anime figures.

Articles: 266

3 Comments

Feel free to leave a reply