Engauge

rust typescript react full stack discord bot

2020 - present

Engauge is a Discord bot I started working on in early 2020. It is used to track member participation by means of message and voice activity and consequently quantifying this data with video game-like levels and experience. It is one of my most feature-rich projects to date, with a bot backend and web API written in Rust and a frontend written with React and TypeScript.

Old landing page, TODO: replace with new one when it's finished

I am the sole developer of this project, having built its backend and designed its frontend (as well as its logo). It is my primary passion project and I hope I can maintain and scale it for a broader userbase.

Architecture

The output of tokei, a line counting tool, on Engauge's codebase as of August 17, 2021. There are about 4,800 lines of Rust and 700 lines of TypeScript/TSX.

As briefly mentioned above, Engauge is built on a stack composed primarily of elements written in Rust and in TypeScript. Engauge itself is based on three moving parts: the Discord bot (the "bot"), the web API (the "web"), and the frontend UI (the "frontend"). Moreover, it stores data using a PostgreSQL database that the former two components query regularly.

Bot

The bot component is written entirely in Rust. This component has been rewritten three times, the initial two iterations being written in C#. I have since migrated to Rust for performance and memory safety reasons.

The bot component makes use of the Discord library twilight for interfacing Discord's API. It has been designed to handle large amounts of activity from thousands of servers in real time, listening to information like messages sent, voice channel activity, member joins, and more. This component is arguably the most important piece of Engauge, as it allows Engauge to complete its task: gauging and rewarding members for their activity.

In the latest iteration of this component, I became acquainted with Rust technologies like sqlx and tokio.

Web

In previous iterations of Engauge, the web and frontend components were designed as one. Originally, this component was written in Crystal, using server-side rendering and templating to present the user with dynamic information. Since, I have split this component into two distinct pieces.

The current iteration of the web component is a REST API backend for the frontend component to interface with. It supports authentication with Discord using OAuth2 and a variety of RESTful API endpoints, with an eventual goal of exposing this API to users of Engauge to write their own interfaces to Engauge's API. The backend uses actix-web, a fast web framework for Rust.

Frontend

The frontend component is currently in its first iteration. Engauge is the first real project of mine to use React, and I've really started to enjoy using it. I have completely redesigned the original interface from earlier iterations of Engauge, as well as moved from vanilla, templated JavaScript to dynamic React components for page interactivity.

I started to write this component using the Rust technology yew, which is effectively a UI framework similar to React that allows you to write Rust code that compiles to WebAssembly. I eventually backed away from using this in production as it is still obviously experimental technology, but I am very intrigued by the idea. I am certainly looking forward to using this in a future project when it feels more production-ready.

Writing this component allowed me to grasp React much more strongly. I am definitely interested in working on more projects that use React for interface interactivity after seeing how vastly ergonomics improved switching from server-side rendering.

History

Engauge started out as a niche bot I named Leeky, after a friend's server bearing a similar name, Leeky Legends. Previously, they'd been using another Discord leveling bot, Mee6, to track activity and expose a level. Jokingly, my friend told me that I should "make Mee6, but with voice activity too." I found this idea very appealing, so I set out to build the initial iteration of Leeky, which I'd completed in about a day or two.

Engauge's logo.

I spent some time polishing the interface and adding features before I released it into the wild for anyone to use. Before I publicized it, I renamed it to Engauge, which is a play on the words "engage" and "gauge": engage and gauge your server members. I also designed the logo at this time, which is an E with an arrow pointing up, representing two key concepts: a level up, and increased engagement (hence the E).

Gradually Engauge's userbase grew, but ultimately growth was stunted due to a poor, slow codebase and inefficient database implementation. I'd planned a full rewrite and a migration from MongoDB to PostgreSQL, but this took much longer than expected due to time conflicts with my senior year of high school and my part-time job. Eventually however, I finished rewriting the entire codebase of Engauge in the same language it was originally written with its database migrated to Postgres, and speeds were lightning fast.

More recently, I rewrote the entire codebase again, moving from the old stack of C#, Crystal, and JavaScript, to Rust and TypeScript. This rewrite is still in progress, and has taken much longer than the previous one, but has a much more organized codebase and has already proved to be much faster.