folly of my youth
Add archived pajama-socks code to git repo


browse  log 



You can also use your local clone with git send-email.


A scalable Discord bot framework that you shouldn't use.

Some time ago, fairly early in my programming journey, I discovered a
fascinating construct known as a websocket. At that time I used Discord to talk
to internet people a lot, and I was curious about how large bots on 100,000s of
servers could support heavy operations without collapsing, so I set about to
create a scalable bot service myself, one that was easy to extend with new sets of
commands without additional configuration.

I didn't really understand that there was such a thing as system design at this
time, and I hadn't really grokked the concept of APIs. Because of this, the
design of pajama-socks is...unique.

The frontend of the bot is a thin wrapper with a few functions for system
administration. On command input from a Discord channel, it queries a database
of valid commands and the message context they require, as well as possible
Discord permission requirements the user calling the command must meet. It then
opens a socket to the server associated with that command, sends the necessary
data, and processes what is returned.

It supports some neat stuff I wanted such as whitelisting and blacklisting
commands or groups of commands on a server-by-server basis, and makes it very
easy to add new commands using Python wrappers, as well as groups of commands,
see modules/ to see what you would expect to find on each server. It's all nice
and async, has a cute ORM in peewee, which I highly recommend, and the Discord
API is very nice to use and has great docs, as well as the discord.py wrapper.

The uniqueness is in how it totally abuses how everything in Python is basically
a dictionary and can have new attributes thrown at it whenever you like during
runtime. Loading and retrieving commands from the database is a fascinating
abuse of getattr, and functions are fully treated like mutable objects. The API
also doesn't really differentiate between different "types" of commands - the
module server will respond with the action to take, and the frontend will
literally check if what it received is a Discord API function, and call it with
the args and kwargs it got from the server. Naturally, this is not exactly
security-forward thinking.

Regardless, I have a strange pride in it. It's a very cute little program and
I've kept it around for a long time now.

Please enjoy!