Miki Sayaka Devblog 001: Off to A Strong Start!

October 13, 2024


I got really bored one day and I decided, hey, let's get another Discord bot rolling. I haven't been having time to maintain larger-scaled projects, including Katsumi (repo private for now, hehe~) and Tairitsu, so I ended up somewhat ""derusting"" (for the lack of a better term) by creating another bot for my own Discord server! And thus, after a week or two of work, Miki Sayaka was born!

This is merely me writing my thoughts and process as I developed Sayaka, and this is no way a tutorial or "best practices" guide at writing Rust or developing a Discord bot! Nonetheless, I hope any readers find this interesting and educational!

Starting steps

Of course, for every Discord bot I make, I start with deciding my language and library of choice. I felt like writing more Rust, so I ended up choosing the poise framework, built on top of the serenity library.

Why Rust? I feel like I can grasp the language decently well, as well as write idiomatic code fast enough in it. Of course, I have my own qualms about it regarding async Rust as well as how ugly it gets when you want something like global states… but that's for another time.

On top of this, I feel like I should learn to write my own command engine and everything… but for now, we'll stick with Poise. Poise is opinionated, yes, but it is neat in the sense that for most, if not all of my use cases, it works and I don't have to think too much about the structure of everything, similar to how Tairitsu was.

Planning features

I've always wanted to make something that can manage the self-assignable roles in my server. I have a few of them set up - colors, gaming pings, free games notifications, etc. Setting them up through Tatsu feels like a pain - and guiding people to use them isn't the easiest either. That's why I felt like making my own to see what's the best way to get the user experience right.

On top of this, I also want to manage new chapter uploads from MangaDex, as well as a recommendation list for manga. I've had ideas about it for a good while, making a crowd-sourced list of manga that we can say "oh yeah our server endorse this, this is pretty nice", something in those lines. Using a Google spreadsheet feels very manual, though it definitely shines when you want someone to add their comments for a certain title, for example.

So, in short, we have two things to do.

  1. Self-assignable roles
    • Display a list
    • Add and remove roles
  2. MangaDex chapter tracking
    • Display list of tracked manga
    • Add manga to tracked list
    • Send notifications whenever a new chapter is out for the titles on the list

Getting to work

Well… Looking at the two above planned features, for starters, the self-assignable roles look much more simple to implement, and that's where I started first.

Self-assignable roles

I prepared a little database table with two columns, role_name and role_id. The role's name is for display purposes through Discord's select menu, and the role_id is… well, for assigning it to the user through Poise, of course.

Of course, with hindsight, I could always only store the role ID, and use the Discord API to fetch the role name for displaying purposes. This way, I wouldn't need to trust myself (out of all people!) to keep the role names correct and updated. But at the same time, we haven't changed any of our self-assignable roles in a good while, maybe a year or two now, so this is the least of my concerns.

Seems simple enough, right? Whatever roles I wanted to setup, I'll fill in the name and the role ID into the database. Then, the role list command would fetch everything from the database and display it in a neat little embed. Similarly, role add would display that same list and having a dropdown to select a role. role remove would display the list of self-assignable roles you have, and allowing you to pick one to remove from your own roles.

Sure enough, implementing this was simple and it didn't take long to get it working. I don't have to worry about managing multiple servers and everything - after all, this was meant to be a personal Discord bot! That's the reason why a lot of supposedly scalable design decisions were skipped - no tracking of what server ID the roles are from, no real interface to add roles to the database from the bot, and so on.

Manga tracking

Now this is the fun part. Thanks to the mangadex-api crate, I have a neat API client for MangaDex that I could use to fetch stuff from. But, now what? Where do we start?

Once again, I started with managing the manga list, which also doubles up as our crowd-sourced recommendations list. Database-wise, it's just a simple table with two columns: manga_dex_id and last_updated. The MangaDex UUID of the manga will be stored alongside the latest date we checked for new updates.

Of course, of course, "But but "last updated" means the last date the manga was updated", I hear you say. Yes, the naming could be better, but who cares? I might change it when I feel like it confuses me enough, but for now, the field existing at all is what I really care about.

A manga list command is available to render the entire list. As of this point, I was really lazy so I didn't bother with pagination or anything. I only have a few titles in the list, so it's not like it's going to be a problem, right?

The manga add command is up next - I'll let users input either a MangaDex URL or the UUID of the manga on MD, and we'll add it to the database. At the same time, the bot takes a MDList UUID and for every manga added it will attempt to sync the database to the MDList.

Skipping the remove for now because… truth be told I cannot figure out a good UX to remove stuff… I'll just hook straight into the database and remove entries I guess.

Closing thoughts

As of right now, Miki Sayaka is up and running pretty neatly! Of course, there's still plenty more to do - paginating the lists, actually notifying new chapters, and so on. But for now, this is a good starting place for Sayaka! Source code for the bot is always available on the GitHub repo, feel free to check it out! Thanks a lot for reading!