UvUManager Dev Notes
A collection of notes from my experience developing and deploying my first ever Discord bot: the UvUManager.
UvUManager
UvUManager is a Discord bot used for Longhorn Riichi’s special intercollegiate tournament “UTA vs UTD”. The main technical challenges are:
- Discord API (discord.py is relatively well documented but still have some ambiguities)
- Mahjong Soul API (there is no official API; I ended up using and contributing to mjsoul.py)
- Google Sheets (the Official Google Sheets API was a mess; gspread was MUCH more user-friendly)
The UvUManager repo has information on how to obtain and set up the secrets for the 3 modules above.
discord.py
- Reloading an extension doesn’t re-import the Python files (i.e., to load the changed imported file, one must restart the bot altogether)
- Restarting the application in the same process doesn’t reload the
dotenv
variables (this is likely due to the fact thatdotenv
doesn’t override existing environment variables – the environment variable values remain the same as the previous process). ephemeral
behaves different for differentInteractions
. ForComponent
interactions, the followup message can be ephemeral regardless of howephemeral
was set indefer()
, but for slash command interactions, the followup message’sephemeral
is governed by theephemeral
indefer()
. More testing may be necessary.- need to call
View.stop()
before deleting messages that have aView
, especially if theView
has a timeout (View.stop
is a clean-up that cancels timeout tasks, etc.). This requirement isn’t listed on thediscord.py
doc as of writing.
Mahjong Soul API
Reverse-engineering API
- The
.proto
file (like the one here) contains all the readable and searchable Protobuf API. Developers typically need to search here for their desired interaction message with the Mahjong Soul server (and examine the format of the Request and Response objects). - you can learn some protobuf field’s possible values with WebSocket Inspector (e.g., the fact that Twitter OAuth2 protobuf request type field should be 10). You can decode Protobuf with this online decoder, but it’s probably better to decode with
protoc
given sensitive info and that you have the.proto
file.
API discoveries
open_live
field ofcreateContestGame
doesn’t actually do anything. In fact, the same toggle on the management website doesn’t work either, as a result.- known but undocumented error:
ERROR CODE 1209
, which happens when trying to pause an already paused tournament game - mjsoul.py raises Exceptions if the response contains an Error object. I modified the relevant module locally (like this version) so
GeneralMajsoulError
has a fielderrorCode
, to help with catching and acting on specific errors (I’ll merge this change to the mjsoul.py repo soon) . - logging out through the tournament manager website (or closing the browser tab after logging in) also logs out the bot. Now the bot has to make a new WSS connection before retrying login – trying to login through the old WSS connection results in a
2504 : "ERR_CONTEST_MGR_HAS_LOGINED
. Okay this is further confirmed by the switch-contest behavior on browser – it also switched the contest for all WSS connections. It’s like there is only one state for each account no matter how many connections there are. In other words, each account can manage at most one contest at a time.
GCE VM
screen
- To run the bot without having it die on SSH disconnection, create a
screen
session. (could also usenohup
as a more lightweight solution). - while in a screen, use
^A^D
to detach from screen and let it run in the background. screen -ls
to list all screens,screen -r
to resume a session, andkillall screen
to terminate all screens.- GCE VM-specific bug: uploading files through SSH-in-browser while in a screen session crashes the SSH connection…
Develop with local SSH
I.e., not using the SSH-in-browser on Google Cloud.
Set up SSH with gcloud
gcloud auth login
gcloud compute config-ssh
it seems the default account for the GCE VM console SSH can be different from your local account: doc.
SSH with VSCode for GUI Editor
Guide here.
WARNING: VSCode can crash your server! Relevant reports: here and here.
The crash causes the SSH connection to die and prevent further SSH connections into the VM of any form (e.g., Google’s SSH-in-browser). This can be resolved by restarting the VM (STOP
and then START
).
(can we figure out a better way to edit on VM with a GUI?)