Bot for managing the Discord server for Geas, the Edinburgh table-top role-playing society.
Go to file
Vivek Santayana 5bb9af12c9 Finished the bot. Requires testing.
Wrote up documentation. Readme needs finishing.
Future development needs to use global listeners for processes.
2021-07-23 15:55:27 +01:00
.vscode Updated vscode settings. 2021-07-21 12:10:15 +01:00
app Finished the bot. Requires testing. 2021-07-23 15:55:27 +01:00
.gitignore Added config checking, event listeners, etc. 2021-07-16 23:53:31 +01:00
CHANGELOG.md Issue present with Purge command 2021-07-21 23:05:13 +01:00
COMMANDS.md Finished the bot. Requires testing. 2021-07-23 15:55:27 +01:00
docker-compose.yml 15 July Build 2021-07-15 09:03:44 +01:00
LICENSE Initial commit 2021-07-07 14:16:49 +01:00
README.md Finished the bot. Requires testing. 2021-07-23 15:55:27 +01:00
resources.md Finished the bot. Requires testing. 2021-07-23 15:55:27 +01:00
TODO.md Finished the bot. Requires testing. 2021-07-23 15:55:27 +01:00

Geas Server Bot

(Currently a work in progress. The bot is still not in a state to run, and none of its features have been programmed.)

This is a bot I wrote to manage the Discord server for Geas, the Edinburgh University Table-Top Role-Playing Society, during our move to an on-line format. The bot is designed to create and manage channels and roles for gaming groups in order to replicate our in-person pitch events on a Discord space as far as possible. The bot is written in Python, and was the first Python coding project I wrote, so it has a special place in my heart. The first version I committed to the repository is version 2.1, and I previously handled the version control manually, so migrating old versions to Git would be a pain. Version 3 was the second major upgrade, taking advantage of some of the recent changes to the Discord API.

Setup

The Bot is dockerised and uses docker-compose for deployment, so it is fairly straightforward to deploy an instance of. Clone the repository, install Docker and Docker Compose, navigate to the root directory (that contains the docker-compose.yml file), and use docker-compose up -d to set up and run the bot. The bot runs on one Docker container with the instance of the app as well as storage for its data and configuration. The bot uses docker-compose to mount an external volume to allow for persisting file storage and easy migration. It no longer uses a database engine because it never really benefitted from the various database manipulation tools in the earlier version, and was not worth the complexity.

The bot authenticates using an API key, which I have kept private in a .env file that I have not uploaded to the repository. In order to set up your own instance of the bot, you will need to provide the following values in a .env file in the root directory.

You will also need this database to set up a username and password for the MongoDB database. The specific username and password don't matter as the bot refers back to the environment variable when authenticating.

The following is the template for the .env file, with the variable names as are referenced in the bot's code: .env file:

BOT_TOKEN=(API token for the production version of the bot.)
TEST_TOKEN=(API token for any test instance.)
CONFIG=(Path to config file. The bot defaults to './data/config.yml' if not provided.)
DATA=(Path to data file. The bot defaults to './data/data.yml' if not provided.)
LOOKUP=(Path to the game role lookup file. The bot defaults to './data/lookup.yml' if not provided.)
GM=(Path to the GM lookup file. The bot defaults to './data/gm.yml' if not provided.)
CATEGORIES=(Path to the channel category lookup file. The bot defaults to './data/categories.yml' if not provided.)
BOT_VERSION=(verson string)
BOT_MAINTAINER_ID=(Discord user ID of the person maintaining the bot to enable debug features.)

The correct API keys need to be entered in the environment variables in the .env file, and for a copy of this file to be placed in the root and the app directories.

N.B.: When the bot is first run, it is configured to log in as the Test Bot, and not the main Geas Server Bot, as a safety measure. To change this, navigate to the last line of the file bot.py and change the line:

client.run(os.getenv('TEST_TOKEN'))

to

client.run(os.getenv('BOT_TOKEN'))

in order for to authenticate as the correct bot.

File Structure

|--	app
|	|--	bot.py
|	|--	Dockerfile
|	|--	requirements.txt
|	|--	cogs
|	|	|--	botcommands		
|	|	|	`--	prefix.py
|	|	|-- dev
|	|	|-- events
|	|	|	|--	on_connect.py
|	|	|	|--	on_guild_channel_delete.py
|	|	|	|--	on_guild_join.py
|	|	|	|--	on_guild_remove.py
|	|	|	|--	on_guild_role_create.py
|	|	|	|--	on_guild_role_delete.py
|	|	|	|--	on_guild_role_update.py
|	|	|	|--	on_guild_update.py
|	|	|	`--	on_ready.py
|	|	`--	slashcommands
|	|	|	|--	
|	|	|	`--	
|	|--	data
|	|	|--	.gitkeep
|	|	|--	config.yml
|	|	`--	data.yml
|
|		
|--	.env
|--	.gitignore
|--	CHANGELOG.md
|--	COMMANDS.md
|--	docker-compse.yml
|--	LICENSE
|--	README.md
|--	resources.md
`--	TODO.md

GameManagement.py -- adding or kicking players
HelpNotifier.py -- notifications for Help channel
MembershipRestriction.py -- restrictions unverified users
MembershipVerification.py -- membership verification system
PitchMenu.py -- automation for generating menus for game pitches

Data Structure

The bot holds data in two .yml files, config.yml for client configurations for each guild it is in and data.yml to hold the actual data regarding game and channel set-up. I was considering merging them into one file, but given how different the two concerns were I ended up splitting the files. I had initially condsiders a .ini file for the configuration settings and .json for the data, but I decided to use .yml for both just to avoid unnecessary complexity.

config.yml Structure

This tree gives the list of various keys for the .yml dictionary as well as the types of different data expected. The entire configuration file is essentially a dictionary with other dictionaries, strings, integers, and lists as values. All values in the dictionary are referenced first by a string of the guild id integer. Remember to convert the guild ID to strings during several operations, and be careful to compare like for like in any logics.

(guild id string):
	channels:
		help: (id integer)
		mod: (id integer)
		signup: (id integer)
	configured: (boolean)
	membership:
		(type string): (id integer)
	name: (string)
	owner: (id integer)
	prefix: (string)
	roles:
		admin: (list)
			- (id integer)
		committee: (id integer)
		bots: (id integer)
		newcomer: (id integer)
		returning: (id integer)
		student: (id integer)
	timeslots: (list)
		- (string)

data.yml Structure

Just like above, the data.yml file is also a dictionary of dictionaries that is indexed by a string of the guild id. It stores only the relevant data necessary for the code to function. It only holds, for instance, ID numbers rather than user handles, Discord discriminators, or names.

(guild id string):
	(timeslot string):
		role: (role id integer)
		gm: (user id integer)
		name: (string)
		players:
			current: (integer)
			max: (integer)
			min: (integer)
		system: (string)