A python rewrite of the original dozer-discord-bot. Much of this project is powered by the blue alliance at https://www.thebluealliance.com/
This version of the bot also includes attendance features. This implementation uses a Google Sheets spreadsheet for storage.
The project comes with an installer script, setup.py. After cloning the
repository, one can simply:
python3 setup.py installand quickly install the project, with a guided flow.
The script is intended to be run on systemd-based Linux distributions.
It supports multiple installation targets, but the defaults should work best for most applications. It will take care of generating a virtualenv environment, dependencies and creating a systemd service.
After installing, one can also:
python3 setup.py importto import Google API keys. This also bypasses the need for a keyring.
If using the setup script, skip § Dependencies and environment.
The project requires multiple dependencies, including:
discorddotenvkeyring- various Google APIs
The package also may require a virtualenv environment to function.
First cd to the project directory, then set up like so:
virtualenv .venv
source .venv/activate # on LinuxCertain IDEs (i.e. PyCharm) have these functions condensed into a menu.
To install dependencies, run:
pip install -r requirements.txt… which will install all pip packages in requirements.txt.
If pip has the same problem with system packages, try:
./.venv/bin/python3 ./.venv/bin/pip install -r requirements.txt(which is just a more forceful way of using the virtualenv pip.)
This bot requires tokens to access several APIs. Obviously they cannot be
hardcoded, thus they are passed through environment variables in a file named
.env, which will never be checked into Git.
Entries are formatted like so:
key=value
multi_word_key="extra long entry with spaces!"A sample is provided in this project under sample.env.
Make sure to remove trailing whitespace.
If the .env file must be located in a different place (i.e. /run/secrets),
set:
DOZER_DOTENV_PATH=/path/to/.envbefore running the bot.
Additionally, certain keys are so sensitive that they cannot be stored in plaintext. Instead they are stored in a keyring (Windows Credential Manager, Gnome Secret Service or similar, or macOS's offering), where they are encrypted at rest.
Note that this only applies if
systemd-creds(from the setup script) is not used.
A keyring must be installed and unlocked for this app to function. If
- you are using macOS or Windows: you already have a keyring
- you are running a mainstream desktop flavour of Linux: you probably have a keyring manager, look for a password manager/keyring app (or similar)
- you are running a server distribution of Linux: check according to your
specific distribution. Try running:
and see if it exists. The agent must implement the Secret Service, thus GNOME keyring or KDE wallet should work for most situations.
gnome-keyring version
If you are running a version of Linux and using the installer script to run the
app, you can also store the secrets using systemd-creds. Run the installer
with the subcommand import – it will add the encrypted credentials directly
into the systemd service file. In this case, no further action is needed.
The bot requires a Discord API token and a guild ID for instant sync. Both are
stored in the .env file.
To create an app:
- Go to the discord developer's portal.
- Click on 'new application', and give it a name.
- Go to the 'Bot' tab and generate/copy the bot's token. Paste it into
.envas below.
To find a server's guild_id:
- Enable developer mode (Settings > Advanced > Developer mode).
- Right click on a server.
- Click 'Copy ID'. Paste it into
.envas below.
To install the app into the server:
- In the developer's portal, go to 'Installation'.
- Make sure it has the
applications.commandsscope. - Copy the auth link and paste it into the browser.
- Grant access to the server you want.
A dev_guild_id line can be added for development. Commands will sync to both
the production and dev guilds; the dev guild can be used to avoid clogging the
prod server with commands.
Add your credentials to the file in this form:
# long Base64 token
token=YourTokenHere
# long integer (longer than shown here), accessible from the Discord client
# (guild is API-speak for server)
guild_id=12345678
# like above, but a different server for dev purposes
dev_guild_id=87654321To test it, run:
python3 main.py --disable-attendanceIt should authenticate and provide most of the commands.
The attendance host requires various Google API features to store verification history. This takes the form of a Google Cloud service account that has a spreadsheet shared with it.
To set it up:
- Set up a Google Cloud project. Go to the console and create a project, and give it a useful name.
- Enable the required APIs, which include:
- Drive API
- Sheets API
- Go to IAM/Admin > Service Accounts and create a new service account. Give it a convenient name and email address.
- Click on the options menu next to the account, manage its keys, and create a new key.
- Download this key to a safe place on a trusted client. Do not compromise this key. Always keep an encrypted copy on hand - not plaintext, and not on the server.
If using a plain install (no setup.py):
-
Transfer the key (in plaintext) to the server. Move it to the bot's project root and name it
secrets.json.(Optional) Add the following line to
.envif the secrets file has a different path:secrets_json_path=/path/to/secrets-file.json
-
Run
main.pywith the argument--import-secrets. -
Securely delete the plaintext key, as it is no longer needed:
shred -u /path/to/secrets.json
-
Add the following lines to
.env:# service account just created service_account=[email protected] # the owner of this email will own the main sheet and share it with the # service account allowable_owner=[email protected]
If using setup.py and systemd-creds:
- Transfer the key (in plaintext) to the server. Move it somewhere
convenient, like
/home/user/secrets.json - Run setup.py with the subcommand
import. Choosesystemd-creds. - Restart the dozer service.
- Securely delete the plaintext key, as it is no longer needed:
shred -u /path/to/secrets.json
- Using the
allowable_owner's associated Google account, create a spreadsheet. Name it anything, but add the suffix "[attendance-bot]" to the end. Avoid editing this sheet as the app stores metadata and state in some parts. - Start up the server.
- Expose an attendance client on the same network, using the associated Java package. The two should discover each other automagically.
The bot takes the following command-line parameter(s):
--disable-attendance: disable all attendance features. The server will not be started and the OAuth tokens will not be used/verified.--import-secrets: Import the secrets fromsecrets.jsoninto the keyring. The program will immediately terminate after success/failure. Always secure the tokens, do not leave an unsecured copy on the server (keep an encrypted copy on a different host). Must not be specified with--disable-attendance.
Launch main.py with python3 to run the app.
If using a simple (manual) installation, nothing is needed. The bot does not
install files outside of its directory, unless setup.py was used. Note that
some keyring remnants may remain; those can be removed without harm (as long as
they are not lost permanently).
If using setup.py, run:
python3 setup.py uninstall... which will do everything automatically. Keyring entries will remain as
above. Make sure that secrets in .env are not permanently lost.
Note: Make sure there is another copy of the tokens in
.env, because they might be permanently lost after uninstallation. The uninstaller will give you an option to copy it to a directory of your choice.
If the setup script cannot uninstall the bot automatically, it can be removed manually.
WARNING: This set of instructions will permanently delete your
.envfile, which could mean your Discord token is lost. Make sure a copy is stored somewhere else.
-
Locate the installation directory. If you forget, look in the following folders for a directory named 'dozerbot':
/usr/local/share/opt~/.local/share
-
Delete the folder.
-
If using either
/usr/local/shareor~/.local/share, remove the broken symlinks.The files
main.py,start.shand.envare linked into[...]/local/binandetcasbin/dozermain,bin/dozerstartandetc/dozer.env. Unlink those withunlink. -
Delete the
systemdunits and configuration, with:systemctl [--user] disable dozer.service
Use
--userif the bot was installed into the home directory.Then, delete:
<sysd>/dozer.service<sysd>/dozer.service.d/(the whole folder, if it exists)
...where
<sysd>is~/.config/systemd/userif installed into the home directory, or/etc/systemd/systemotherwise (most cases). -
(Optional) Clean the logs. If set up to use a logfile, you can delete it from
~/.config/dozer.logor/var/log/dozer.log(alongside any logrotate artifacts).
-
If the bot throws an error about a locked keyring, exit it and unlock the keyring before trying again.
-
If the bot produces "unauthorized" or "forbidden" errors, check the tokens. Specifically, that they aren't expired and that the correct scopes are selected.
-
If the bot raises a
ValueErrorabout how no valid sheet was found, make sure that there is a sheet that:- is shared with the designated service account;
- is named with the appropriate suffix (no quotes or extra spaces); and
- is editable/visible.
Requires the discord.py, statbotics, requests, pillow, and dotenv libraries (as well as attendance libraries mentioned before)
- Implement caching TBA responses with the ETag, If-None-Match and Cache-Control headers (see https://www.thebluealliance.com/apidocs)
- Implement the following slash commands:
- Alliances
- Rankings
- EPA Rankings
- Events
- Match
- Schedule