Introduction
This is a simple bot you can spin up and watch your stats for the Advent of Code competition. It uses the JSON API for private leaderboards.
Description
This bot is supposed to be fast, low-overhead (saves money on server hosting) and easy to use. It has one purpose, to help show stats for the AoC challenges in your Discord.
Configuration
This section explains the configuration options available in the auth.toml and log.toml files as well as environment variables as alternative source of settings.
- Authentication configuration for required login information for both Advent of Code as we as Discord.
- Logging configuration for terminal and file logging.
- Environment Variables as overrides or alternative to the TOML files.
File location
The bot expects both auth.toml and log.toml to be located in a config
folder in the
current working directory. For example, let's say the current directory is /apps/aoc_bot
, the
structure would be as follows:
apps/
aoc_bot/ <-- current directory
config/
auth.toml <-- Authentication settings
log.toml <-- Logging settings
Authentication
Authentication is needed for the Advent of Code API to get leaderboard statistics as well as the Discord API to send messages as a bot. The configuration is located in config/auth.toml
and this
bot will look for it in the current working directory from where it was executed.
aoc
- Advent of Code related settings
This section contains all information required to fetch leaderboard statistics from the Advent of Code website.
board_id
This is the board ID from the private leaderboard the bot should fetch information from. This can be found by opening a leaderboard from the AoC page. Once opened the ID is the digits at the end of the URL.
For example, if we would want the ID from the following leaderboard URL, the ID would be 12345
:
https://adventofcode.com/2020/leaderboard/private/view/12345
└─┬─┘
leaderboard ID
session_cookie
The session cookie is the login cookie of a user that the AoC website uses to for its authentication
on all pages. To extract it, log in on the website and open the storage inspector of your
browser, locate the cookies area and look for an entry named session
.
For example in Firefox this can be done by first opening Hamburger menu -> Web Developer ->
Storage Inspector. Then expand the cookies entry, click on the single entry within it and
double click on the cell in for the session
entry labelled Value and lastly to copy it
(CTRL+C).
event_year
This setting is to use the wanted AoC year, the API currently accepts the values 2015
, 2016
,
2017
, 2018
, 2019
, 2020
and 2021
. That is, every year from the first AoC event until today.
discord
- Discord related settings
This section contains all authentication details needed to send send messages as a bot in Discord through the service's API.
bot_token
The only required setting is this bot token which allows to authenticate as a bot. It can be retrieved from the Discord Developer Portal as follows:
- First navigate to the Discord Developer Portal and log in if you haven't yet.
- Create a new application or use an existing one and open it.
- In the navigation select the Bot area. Here you can find your bot token that you need for this setting.
- To enable the application for a Discord Server, navigate to the OAuth2 section to generate a
URL for the authorization process.
- In Scopes select the
bot
scope. - In Bot Permissions select the
Text Messages
andRead Message History
permission. - Copy the link from the Scopes section and open it in a tab.
- Select the server where you want to install the application.
- In Scopes select the
schedule
The bot allows to set a recurring automated leaderboard message without request from a user first.
To enable it crate a sub-section [discord.schedule]
in the config/auth.toml
file and set both of
the following fields.
interval
The interval describes how often the automated leaderboard should be sent, defined as a cron-job
string. For example to send the leaderboard every 2 hours you can use 0 0 */2 * * * *
as value.
This format basically defines the following time slots for each value, separated by spaces:
0 0 */2 * * * *
│ │ │ │ │ │ │
│ │ │ │ │ │ └─ year
│ │ │ │ │ └─ day of week
│ │ │ │ └─ month
│ │ │ └─ day of month
│ │ └─ hours
│ └─ minutes
└─ seconds
For further help and examples have a look at crontab guru, although the website has a simpler version without the seconds and year fields.
channel_id
The channel ID is the Discord channel where the leaderboard should be posted. In contrast to a user sent command, where the reply is sent in the same channel as the user's command, the channel is fixed as there is no way of determining the channel dynamically.
This ID can be found in Discord opening the context menu of a channel (right click) and selecting Copy ID to copy it into the clipboard.
To see this option the developer mode must be enabled in the settings under App Settings > Advanced > Developer Mode.
Examples
Below are some example configuration for reference. Please note that you still must replace the authentication related fields with real values to make the setup work.
Basic
This is a sample configuration without any optional settings.
[aoc]
board_id = "12345"
session_cookie = "001122aabbcc"
event_year = 2021
[discord]
bot_token = "abcdef"
Full
The following is a complete configuration file with all optional settings enabled.
[aoc]
board_id = "12345"
session_cookie = "001122aabbcc"
event_year = 2021
[discord]
bot_token = "abcdef"
[discord.schedule]
# sec min hour day of month month day of week year
# 0 0 0 * * * *
interval = "0 0 0 * * * *"
channel_id = 100
Logging
The bot logs several messages while it is running that can help to understand its current state and aid in debugging errors. This logging section controls where this information is written to and at what verbosity level.
In addition, logs can be written to different backend at the same time. Further details are written below for each supported backend.
To disable any of the backends, comment out or remove the whole section of a backend.
Filter levels
The filter defines the verbosity of error messages. For a production setup it's recommended to set
it to warn
for the terminal output and info
for the file output. This default configuration can
be found at the project's config/log.toml
.
This setting is available to all log backends and the following values are accepted, ranked from least to most verbose:
error
: most silent version, only log critical errors.warn
: log critical errors and warnings.info
: log informative messages, warnings and errors.debug
: write messages helpful for debugging purposes and all above type of messages.trace
: most verbose, logs very detailed information plus all the other levels.
terminal
- Terminal output
This backend writes logs directly to the terminal where the bot is running. It has only one setting,
the filter
. Refer to the Filter levels area for possible values.
file
- File output
This backend writes logs to a file instead of the terminal and has two settings, the filter
and
the path
. Refer to the Filter levels area for possible values of the filter
field.
path
This setting defines the path of a file that the backend will append logs to. If the file is missing it will be automatically created.
Examples
Terminal only
Only terminal output is enabled, with debug or worse logs, and no log file will be created.
[terminal]
filter = "debug"
File only
The terminal output will be completely silent and debug or worse logs will be logged to the file
aocbot.log
.
[file]
filter = "debug"
path = "aocbot.log"
Both
A combination of the above examples, logging only warnings and errors to the terminal and more detailed logs to the aocbot.log
file.
[terminal]
filter = "warn"
[file]
filter = "debug"
path = "aocbot.log"
Environment variables
In addition (or as replacement) for configuration files, all possible settings can be done through environment variables. For details about each option, please refer to the appropriate section of the config files.
Available values
The following sections list the available environment variables with links to the respective config file settings.
Advent of Code
These are the AoC related settings from the auth.toml
file.
AOC_BOARD_ID
:aoc.board_id
AOC_SESSION_COOKIE
:aoc.session_cookie
AOC_EVENT_YEAR
:aoc.event_year
Discord
These are the Discord related settings from the auth.toml
file.
DISCORD_BOT_TOKEN
:discord.bot_token
DISCORD_SCHEDULE_INTERVAL
:discord.schedule.interval
DISCORD_SCHEDULE_CHANNEL_ID
:discord.schedule.channel_id
Please note: DISCORD_SCHEDULE_INTERVAL
and DISCORD_SCHEDULE_CHANNEL_ID
must both be set
together. Setting only one won't have any effect.
Logging
These are the logging related settings from the log.toml
file.
LOG_TERMINAL_FILTER
:terminal.filter
LOG_FILE_FILTER
:file.filter
LOG_FILE_PATH
:file.path
Please note: LOG_FILE_FILTER
and LOG_FILE_PATH
must both be set together. Setting only one
won't have any effect.
Using an .env
file
The application allows to set environment variables through a file call .env
. This is a common
approach that allows to configure applications through env vars without having to define them every
time before execution.
Contents of the file are pairs of env var names and values, separated by an equal sign =
and each
entry separated by newlines \n
. Comments can be added by prefixing values with a #
. For example:
# .env file contents
AOC_BOARD_ID=12345
AOC_SESSION_COOKIE=00112233aabbccdd
environment variables are automatically loaded from this file if it can be found in the current working directory. Any already defined env var will not be overriden by this file.
Commands
The main feature of this bot is the !aoc
command, but it supports some other commands as
well. Some of them are related to AoC and some are just for fun or testing purposes.
!ping
The ping command allows to check how long the bot needs to interact with the Discord APIs. After receiving the user's command the bot will respond with a simple message initially and then update it immediately afterwards to measure the time it takes between sending 2 commands to Discord.
!aoc
The main command, giving a large overview of the current members in the configured leaderboard. It renders a list of all members, sorted by their star count together with several statistics.
!top3
This command renders a top 3 stair case with the first 3 members that have the highest star count. Currently the stair case is rendered as ASCII art.
!42
A fun command, for people who read or watched the The Hitchhiker's Guide to the Galaxy book/movie.
Docker
The easiest way to deploy this bot is through Docker. It allows to run it independent of the
software installed on the system as Docker isolates its containers from the host. This project
comes with a Dockerfile
so you only need to build it and are good to go.
Building
Creating the image is straight forward and the same as for any typical Dockerfile. Just navigate to the root of the project and run the following command to build the image:
docker build -t aoc_bot .
This will create the image, tagged with the name aoc_bot
. You can choose any name you like.
Running
The built image can be run either directly through Docker, Docker Compose or by other systems that integrate with Docker (for example Terraform, Ansible, Kubernetes, ...).
For example ,the following command runs the bot, assuming all settings are configured through the authentication and logging files.
docker run --rm -it \
-v $PWD/config/auth.toml:/data/config/auth.toml:ro \
-v $PWD/config/log.toml:/data/config/log.toml:ro \
aoc_bot
The following version is an alternative using an .env
file to configure the bot as described in
the environment variables section.
docker run --rm -it --env-file .env aoc_bot
Docker compose
The project comes with a basic Docker Compose configuration that can be used to run this bot through Docker. It is an equivalent to the above commands but allows easier execution without having to remember all necessary command line options.
docker-compose up --build
It will build the image if it isn't available in the local storage and then execute the bot. Settings are loaded by mounting the config files as well as using the env var file to load environment files for configuration.