Discord bot development commences. The first order of business is to tackle the most straightforward task which I am calling the “lobby”. We have this system working on The Wombattery server right now through the application of other bots, which I explained in a previous post here at LCHQ. The tld;dr version is that the default @everyone role is the only role invitees have when they arrive in the “lobby” channel. They have to execute a specific command — which they learn by reading the rules — in order to be automatically granted another role which gives them basic visibility and access to the more public parts of the server.
As cool as this is, I’ve seen even cooler implementations where users are asked to click reactions in order to signal acceptance or rejection of content. Kind of like this:

As a big fan of trying to require as little input from the user as possible I have set the bot to handle the heavy lifting of the process. The admin just has to enter the command “!setlobby [CHANNEL] [ROLE_TO_GRANT]” and the bot takes care of the rest. How? Glad you asked (even if you didn’t, or regret doing so).

Here’s the bulk of the code, written for Node.js using Discord.js. Sorry it’s so small; I had to fit it all into one screenshot. A lot of the header stuff is convention for making this a command module, whereas the bulk of logic is in the “execute(message, args, settings)” block and beyond.
When the admin uses the “!setlobby” command and passes the channel name and role to grant arguments into this block, we enumerate the arguments in order to determine which action to take. There will be other related commands, but if we have two arguments then we know they are passing a channel and role (because there are no other formats of the command that accept two arguments).
Naturally, we have to protect the user from him/herself so we verify the existence of both the channel and the role using the find() method and if both return results (i.e. are not empty) then we’ve got something to work with.
The key to this system is that an admin can create the “lobby” channel, set their invite to deposit new visitors into that channel, and can then write up the bylaws of the server. All roles aside from admin and @everyone are banned, and only the admin role(s) has permission to write in that channel. This prevents bots from coming into the channel and leaving spam behind. The admin will also have to ensure that there’s another role that’s one step higher than @everyone which represents the general “member” level of the server, whatever that means to the server operator. That role should have visibility access (at least) to other channels on the server that a rank-and-file member should be allowed to see and/or access. This role is provided as the second argument to the !setlobby command.
With the EULA set, the code will first delete any existing code that it recognizes as the instructions it will issue to the channel on how to self-authorize. We do this by matching the channel message that we’ll be posting. This means that the admin should not write his or her own verbiage on how to get out of the room; the bot will add it, but first will clear it so that the very last line of the text in the channel is the instructions with reaction buttons.
Once we have that set, we will add the message as the last message in the lobby channel. In addition to the text, we add two reactions: the check-mark and the “X”. If the user signals their acceptance of the EULA, they use the check. If they reject the EULA, they use the X and will be immediately kicked from the server (not shown here).
In fact, the handling of the reaction clicking is not shown here at all because it exists in the main code on account of the fact that we can’t just listen for those specific reactions in that specific channel; we have to listen to all reactions (clicks and adds) and then compare the metadata of the reaction to the type and channel and if they match what’s in our settings for the lobby, take action.
One of the most obvious gotchas is the question of what happens if the admin edits the lobby EULA and the bot text is now somewhere in the middle of the page? Or if the admin does add her or her own verbiage explaining how to use reactions — complete with new reactions? Since we look only at the last message in the channel and compare it to the message we’re going to add, anything that deviates from allowing this to happen is going to wreak havoc. This is something that I’ll need to work on and address just to make sure things work smoothly.
This issue aside, the bot is working just fine, it seems. In early tests it will remove the existing line and add a new line to the channel specified. Before I can perform further testing, however, I needed to allow for the data provided to persist so that other processes can get a hold of it for checking the reactions in the specific channel, and for granting the elevated role to those who accept the EULA. That means I need to persist the data over time and between sessions, which we’ll talk about in the next post.