156 lines
7.7 KiB
Markdown
156 lines
7.7 KiB
Markdown
# reminder-rs
|
|
|
|
Reminder Bot for Discord.
|
|
|
|
## How do I use it?
|
|
|
|
I offer a hosted version of the bot. You can invite it with: **https://invite.reminder-bot.com**.
|
|
The catch is that repeating
|
|
reminders are paid on the hosted version of the bot. Keep reading if you want to host it yourself.
|
|
|
|
You'll need rustc and cargo for compilation. To run, you'll need Python 3 still (due to no suitable
|
|
replacement for dateparser in Rust)
|
|
|
|
### Build APT package
|
|
|
|
Recommended method.
|
|
|
|
By default, this builds targeting Ubuntu 20.04. Modify the Containerfile if you wish to target a
|
|
different platform. These instructions are written using `podman`, but `docker` should work too.
|
|
|
|
1. Install container software and Make: `sudo apt install podman make`.
|
|
2. Install database server: `sudo apt install mysql-server-8.0`. Create a database called
|
|
`reminders`
|
|
3. Install SQLx CLI matching the project's SQLx version: `cargo install sqlx-cli --version 0.8.2 --locked`.
|
|
4. Install the local build requirements (Rust, Node.js/npm, GCC, CMake, pkg-config, and OpenSSL
|
|
development headers), then install dashboard dependencies: `npm ci --prefix reminder-dashboard`.
|
|
5. Export the URL of your build/test database:
|
|
`export DATABASE_URL="mysql://user[:password]@localhost/reminders"`.
|
|
6. From the source code directory, execute `sqlx migrate run`.
|
|
7. Run `make` (or `make build`). This prepares SQLx query metadata in `.sqlx`, runs the Rust tests,
|
|
builds the `reminder-rs` container image, and runs `cargo deb` inside it. The resulting package is
|
|
written to `target/debian/`.
|
|
|
|
Preparation and database-dependent tests use the local database. The container packaging step uses
|
|
the prepared `.sqlx` metadata with `SQLX_OFFLINE=true`, so it does not need database access, including
|
|
when a `.env` file is present in the mounted source directory.
|
|
|
|
The stages can also be run separately: `make prepare`, `make test` (includes preparation), and
|
|
`make image` (includes preparation and tests). Override `IMAGE` to change the container image tag,
|
|
or `PODMAN` to use another container command, for example `make PODMAN=docker`.
|
|
|
|
### Compiling for other target
|
|
|
|
1. Install requirements:
|
|
`sudo apt install gcc gcc-multilib cmake libssl-dev build-essential python3-dateparser`
|
|
2. Install rustup from https://rustup.rs
|
|
3. Install the nightly toolchain: `rustup toolchain default nightly`
|
|
4. Install database server: `sudo apt install mysql-server-8.0`. Create a database called
|
|
`reminders`.
|
|
5. Install `sqlx-cli`: `cargo install sqlx-cli`.
|
|
6. Run migrations: `sqlx migrate run`.
|
|
7. Set environment variables:
|
|
- `DATABASE_URL` - the URL of your MySQL database (`mysql://user[:password]@domain/database`)
|
|
8. Build: `cargo build --release`
|
|
|
|
### Configuring
|
|
|
|
Reminder Bot reads a number of environment variables. Some are essential, and others have hardcoded
|
|
fallbacks. Environment variables can be loaded from a .env file in the working directory.
|
|
|
|
**Required Variables**
|
|
|
|
- `DATABASE_URL` - the URL of your MySQL database (`mysql://user[:password]@domain/database`)
|
|
- `DISCORD_TOKEN` - your application's bot user's authorization token
|
|
|
|
**Other Variables**
|
|
|
|
- `MIN_INTERVAL` - default `600`, defines the shortest interval the bot should accept
|
|
- `LOCAL_TIMEZONE` - default `UTC`, necessary for calculations in the natural language processor
|
|
- `SUBSCRIPTION_ROLES` - default `None`, accepts a list of Discord role IDs that are given to
|
|
subscribed users
|
|
- `CNC_GUILD` - default `None`, accepts a single Discord guild ID for the server that the
|
|
subscription roles belong to
|
|
- `PYTHON_LOCATION` - default `/usr/bin/python3`. Can be changed if your Python executable is
|
|
located somewhere else
|
|
- `THEME_COLOR` - default `8fb677`. Specifies the hex value of the color to use on info message
|
|
embeds
|
|
|
|
### Dashboard image uploads
|
|
|
|
Image URL inputs offer an **Upload image** button when all of these settings are supplied:
|
|
|
|
- `S3_BUCKET` — destination bucket name.
|
|
- `S3_REGION` — bucket region, for example `eu-west-2`.
|
|
- `S3_ACCESS_KEY_ID` and `S3_SECRET_ACCESS_KEY` — credentials with `s3:PutObject` and
|
|
`s3:DeleteObject` permissions for the bucket's `uploads/` prefix.
|
|
- `S3_PUBLIC_URL` — public base URL for the bucket or CDN, for example
|
|
`https://my-bucket.s3.eu-west-2.amazonaws.com`. Objects must be publicly readable through
|
|
this URL; the application does not change bucket policies or set object ACLs.
|
|
|
|
`NSFW_CHECK_ENABLED` defaults to `true`, and enables the use of a small model to block uploading
|
|
of NSFW images. Set it to `false` to skip NSFW moderation and model initialization. Empty or
|
|
unrecognized values keep checks enabled.
|
|
|
|
The Debian package includes `reminder-rs-clean-images.timer`, an hourly cleanup job. Enable it
|
|
after configuring S3 and starting the bot (which applies database migrations):
|
|
|
|
```sh
|
|
sudo systemctl enable --now reminder-rs-clean-images.timer
|
|
```
|
|
|
|
Each run records the first observed orphan time in `image_uploads.orphaned_at` (UTC). An upload
|
|
is orphaned when neither a reminder (including archived reminders) nor a template uses its URL
|
|
as an avatar, image, thumbnail, author icon or footer icon. Referenced uploads have this timestamp
|
|
cleared. `IMAGE_UPLOAD_ORPHAN_RETENTION_SECONDS` controls the additional retention time after
|
|
detection; it defaults to `604800` (seven days) and must be a positive integer. Unsaved uploads
|
|
are also covered. Cleanup rechecks references before deleting and removes the tracking row only
|
|
after S3 confirms deletion; failed deletions are retried on later runs. Each run attempts up to
|
|
1,000 expired uploads from the configured public URL's `uploads/` prefix.
|
|
|
|
For other deployments, schedule `/path/to/reminder-rs clean-images` hourly with cron, using the
|
|
same working directory and configuration as the bot. The command requires no Discord token
|
|
and skips NSFW model initialization. With no S3 settings it exits successfully without work;
|
|
partial S3 settings or invalid retention values fail the job.
|
|
|
|
## Running with Docker
|
|
|
|
### RustFS for local development
|
|
|
|
Start the local object store and initialize the image upload bucket:
|
|
|
|
```sh
|
|
docker compose --env-file conf/rustfs.env -f compose.rustfs.yaml up -d
|
|
```
|
|
|
|
Add the settings from `conf/rustfs.env` to your local `.env`, then restart the bot running on
|
|
your host. RustFS serves the S3 API at `http://127.0.0.1:9000` and its console at
|
|
`http://127.0.0.1:9001`. Log into the console with the access key and secret key from
|
|
`conf/rustfs.env`. Both ports bind to localhost. The named data volume persists across restarts.
|
|
|
|
The initializer creates `reminder-images` if needed and permits anonymous reads of its
|
|
`uploads/` objects. Uploads, deletes and bucket listing require credentials. These settings
|
|
enable dashboard image uploads locally; `NSFW_CHECK_ENABLED` keeps its configured value.
|
|
`S3_ENDPOINT` uses path-style addressing for RustFS, and `S3_PUBLIC_URL` includes the bucket
|
|
name because the browser fetches objects through that public URL.
|
|
|
|
```sh
|
|
docker compose --env-file conf/rustfs.env -f compose.rustfs.yaml logs rustfs-init
|
|
docker compose --env-file conf/rustfs.env -f compose.rustfs.yaml down
|
|
```
|
|
|
|
`down` keeps the data volume. This development stack is separate from the bot/database stack
|
|
below. The [RustFS Docker documentation](https://docs.rustfs.com/en/installation/container/docker)
|
|
describes the upstream container configuration.
|
|
|
|
A `compose.yml` file is provided to aid in running the bot agnostically using docker.
|
|
|
|
- Populate a `.env` file as in `conf/default.env`
|
|
- Add the additional variable `ROCKET_SECRET_KEY` with a key generated from
|
|
`head -c64 /dev/urandom | base64`
|
|
- Run `docker compose up`
|
|
|
|
Please note that this is _not_ production-ready when run via compose. We do not offer a way for
|
|
backing up of your data, or a way to run the dashboard securely via HTTPS, which is required for
|
|
OAuth.
|