TeX-Bot, but back in Python! This is a Discord bot used for managing a community group's Discord guild.
Featured in the CSS Discord guild.
Confusingly, Discord uses the term "guild" to refer to a Discord "server", when communicating with developers. Therefore, the same terminology ("guild") will be used across all documentation in this project. (See the Discord developer docs & Pycord's docs for more information.)
The term "main guild" is used throughout the code in this repository to refer specifically to your community group's main Discord guild.
In the context of Discord itself, a "user" object represents a Discord account not connected to any specific guild. Therefore, it can be messaged via DM or be retrieved via its snowflake ID, but little else can be done with it. (See the Discord developer docs & Pycord's docs for more information.)
In contrast, a Discord "member" object is a user attached to a specific guild. Therefore, it can have roles, be banned & have many other actions applied to it. (See the Discord developer docs & Pycord's docs for more information.)
In the context of your community group's membership structure, a "member" is a person that has purchased a membership to join your community group. This is in contrast to a "guest", which is a person that has not purchased a membership. Guests often can only attend events that are open to anyone (i.e. not members only), and have limited communication/perks within your Discord guild. Some commands may require you to create roles within your Discord guild, to differentiate between these different types of users.
In some other contexts, the term "user" may be used to refer to any person/organisation making use of this project. (E.g. the description within the "Error Codes" section.)
Users of TeX-Bot may encounter an error code when executing a slash-command fails. If a user encounters any of these errors, please communicate the error to the committee member that has been assigned to upkeep & deployment of your instance of TeX-Bot. The meaning of each error code is given here:
-
E1011
- The value for the environment variableDISCORD_GUILD_ID
is an ID that references a Discord guild that does not exist -
E1021
- Your Discord guild does not contain a role with the name "@Committee". (This role is required for the/writeroles
,/editmessage
,/induct
,/strike
,/archive
,/kill
,/delete-all
&/ensure-members-inducted
commands) -
E1022
- Your Discord guild does not contain a role with the name "@Guest". (This role is required for the/induct
,/stats
,/archive
&/ensure-members-inducted
commands) -
E1023
- Your Discord guild does not contain a role with the name "@Member". (This role is required for the/makemember
&/ensure-members-inducted
commands) -
E1024
- Your Discord guild does not contain a role with the name "@Archivist". (This role is required for the/archive
command) -
E1025
- Your Discord guild does not contain a role with the name "@Applicant". (This role is required for the/make-applicant
command and respective user and message commands) -
E1026
- Your Discord guild does not contain a role with the name "@Committee-Elect". (This role is required for the/handover
command) -
E1031
- Your Discord guild does not contain a text channel with the name "#roles". (This text channel is required for the/writeroles
command) -
E1032
- Your Discord guild does not contain a text channel with the name "#general". (This text channel is required for the/induct
command) -
E1041
- The community group member IDs could not be retrieved from theMEMBERS_LIST_URL
. (It is likely that yourMEMBERS_LIST_URL_SESSION_COOKIE
is invalid. If your community group is a Guild of Students society, the community group member IDs will be a list of UoB IDs) -
E1042
- The reference to the@everyone
role could not be correctly retrieved. Try running the command that caused this error again. If the error persists, please file an issue on this project's bug tracker, including the details of what command was run to create this error -
E1043
- A button callback interaction did not contain the related user. Try pressing the button that caused this error again. If the error persists, please file an issue on this project's bug tracker, including the details of what command was run to create this error -
E1044
- An interaction was denied because the Discord permissions for TeX-Bot were not set correctly
When an error occurs, a log entry will be created. One of these possible error levels will be associated with that log entry. Below are the explanations of what effects/causes each log-level represents:
-
WARNING
- An error occurred that did not result in any failure to complete the current request/interaction. However, some minor inconsistencies/data loss may have occurred. This may require some changes to the deployment configuration or an issue about a bug to be raised -
ERROR
- The current request/interaction could not be completed due to a major error. The problem that caused the error should be addressed immediately, or otherwise TeX-Bot should be manually shut down to prevent further errors -
CRITICAL
- An unrecoverable error occurred. This level of error will cause TeX-Bot to shut down, as the problem can only be solved by fixing one or more of the configuration environment variables
Repeated Tasks Conditions
The configuration variables SEND_INTRODUCTION_REMINDERS
& SEND_GET_ROLES_REMINDERS
determine whether their related tasks should run.
However, because these are rather annoying/drastic actions to be executed automatically, there are additional conditions that must be met on a per-member basis for the action to trigger.
The conditions for each task are listed below, along with the additional environment variables that can be used to configure the conditions to suit your needs.
Task Name | Enable/Disable | Per-Member Conditions | Scheduled Interval |
---|---|---|---|
introduction_reminder |
SEND_INTRODUCTION_REMINDERS :* Once - Only send the introduction reminder once (even if they later delete the message)* Interval - Send an introduction reminder at a set interval* False - Do not send introduction reminders |
* The Discord member has not been inducted (does not have the "@Guest" role) * The time since the Discord member joined your community's guild is greater than SEND_INTRODUCTION_REMINDERS_DELAY * The Discord member has not opted out of introduction reminders * The Discord member has not yet been sent an introduction reminder. (Only applies when SEND_INTRODUCTION_REMINDERS is set to the value Once ) |
The interval of time between this task running is determined by SEND_INTRODUCTION_REMINDERS_INTERVAL . (When SEND_INTRODUCTION_REMINDERS is set to the value Once , all Discord members will still be checked at this interval, just not sent a message if they have already been sent an introduction reminder). The default interval is to send messages every 6 hours |
get_roles_reminder |
SEND_GET_ROLES_REMINDERS :* True - A single reminder for the Discord member to get roles will be sent to them only once (even if they later delete the message)* False - Do not send any reminders for Discord member to get roles |
* The Discord member has been inducted (has the "@Guest" role) * The Discord member does not have any of the opt-in roles. (E.g. "@First Year" or "@Anime".) (Having the green "@Member" role or even the "@Committee" role makes no difference) * The time since the Discord member was inducted (gained the "@Guest" role) is greater than SEND_GET_ROLES_REMINDERS_DELAY * The Discord member has not yet been sent a reminder to get roles |
The interval of time between this task running is determined by ADVANCED_SEND_GET_ROLES_REMINDERS_INTERVAL . It is unlikely that this value will need to be changed from the default of 24 hours |
The only supported way to deploy TeX-Bot in production is by using our pre-built docker container.
It is built automatically when new changes are made to the main
branch, and can be pulled from the GitHub Container Registry with this identifier: ghcr.io/CSSUoB/tex-bot-py-v2:latest
.
(An introduction on how to use a docker-compose deployment can be found here.)
Before running the container, some environment variables will need to be set.
These can be defined in your compose.yaml
file.
The required environment variables are explained within the "Setting Environment Variables" section.
- Ensure that you have Poetry installed
- Navigate to this project's repository root folder
- To install the required dependencies, execute the following command:
poetry install --no-root --sync
-
The
--no-root
flag installs the dependencies without installing the root project as a package. Poetry attempts to install the project as a package by default because Poetry is often used to develop library packages, which need to be installed themselves. -
The
--sync
flag uninstalls any additional packages that have already been installed in the local environment, but are not required in thepyproject.toml
Activating the Poetry Environment
To use the installed dependencies, the environment they were installed within must be activated. The easiest way to do this (as described by Poetry's guide) is with the below command:
poetry shell
If you do not want to activate the virtual environment, every command can be run prepended with poetry run
, to run the given command within the Poetry context.
(Every command within the documentation within this project will include the poetry run
prefix for convenience.
It can be excluded if you have already activated the virtual environment.)
Creating Your Bot
A full guide on how to create your bot's account can be found here; on Pycord's wiki.
You'll need to create a Discord bot of your own in the Discord Developer Portal. It's also handy if you have an empty guild for you to test in.
You can retrieve the correct invite URL to use by navigating to the root folder, then running the following command:
poetry run python -m utils generate_invite_url {discord_bot_application_id} {discord_guild_id}
-
{discord_bot_application_id}
must be replaced by the application ID of your bot -
{discord_guild_id}
must be replaced by the snowflake ID of your community group's guild
Setting Environment Variables
You'll also need to set a number of environment variables before running TeX-Bot:
-
DISCORD_BOT_TOKEN
: The secret token for the instance of TeX-Bot you created. (The token is available on your bot page in the Developer Portal.) -
DISCORD_GUILD_ID
: The ID of your community group's Discord guild. -
DISCORD_LOG_CHANNEL_WEBHOOK_URL
: The webhook URL of the Discord text channel where error log messages should be sent. (This setting is optional. Error logs will always be sent to the console, this setting allows them to also be sent to a Discord log channel.) -
MEMBERS_LIST_URL
: The URL to retrieve the list of IDs of people that have purchased a membership to your community group. (The CSS' members-list is currently found on the Guild of Students website. If your members-list is also found on the Guild of Students website, ensure the URL includes the "sort by groups" option, so that all members are visible without pagination.) -
MEMBERS_LIST_URL_SESSION_COOKIE
: The members-list URL session cookie. (If your group's members-list is stored at a URL that requires authentication, this session cookie should authenticate TeX-Bot to view your group's members-list, as if it were logged in to the website as a Committee member. This can be extracted from your web-browser, after logging in to view your members-list yourself. It will probably be listed as a cookie named.ASPXAUTH
.)
You can put these variables in a .env
file in the root folder, as python-dotenv is used to collect all environment variables.
There is an .env.example
file in the repo that you can rename and populate.
There are also many other configuration settings that can be changed to alter the behaviour of TeX-Bot.
These are all listed in the .env.example
file, along with the behaviours that will be affected.
Any variables, in the .env.example
file, marked with # !!REQUIRED!!
must be set before running TeX-Bot.
All other variables are optional and their default values are shown as the example value for each variable in the .env.example
file.
Once everything is set up, you should be able to execute the following command to automatically run TeX-Bot & connect it to your Discord guild:
poetry run python -m main
Contributions are welcome!
If you want to contribute, please create a pull request, and we'll review, test and (likely) merge it. Please comment on any issues you'd like to work on, to prevent duplication of work. If you find any bugs/problems or have any feature suggestions, please create an issue.
Before making contributions, it is highly suggested that you read CONTRIBUTING.md
.
This will ensure your code meets the standard required for this project and gives you the greatest chances of your contributions being merged.