From 8e742426c9ceb6de81e145a1b13d91cb724c68ce Mon Sep 17 00:00:00 2001 From: Logan Fick Date: Sun, 5 Jul 2026 15:26:51 -0400 Subject: [PATCH] Added README. --- README.md | 171 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 171 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..9c93034 --- /dev/null +++ b/README.md @@ -0,0 +1,171 @@ +# Crabstero + +The simple nonversation Discord bot. + +Crabstero is a Discord bot that learns from messages in each channel and uses +Markov chains to generate responses when it is mentioned. + +## Overview + +Crabstero is intended for Discord servers that want a lightweight chatbot with +channel-local, randomly generated replies. It does not use a large language +model; it learns from the channels it can read and uses that history to assemble +replies when mentioned. + +This repository and README are for running your own instance of Crabstero. To +invite the official hosted instance instead of running your own bot, see the +[Crabstero project page](https://logal.dev/projects/crabstero/). + +## Features + +- Per-channel Markov chain generation for Discord messages. +- Automatic ingestion of accessible channel history and new messages. +- Mention-triggered replies based on each channel's learned message history. +- `/pingme` user control for opting into pings from generated mentions. +- `/forgetme` user data deletion and future message ingestion opt-out. +- SQLite-backed storage for learned message data. +- Optional Prometheus metrics over TCP or a Unix socket. +- systemd notification and watchdog support when run as a service. + +## Requirements + +- A Linux host or virtual machine. +- [uv](https://docs.astral.sh/uv/getting-started/installation/) for Python + management and the install/run commands below. +- A Discord application with a bot token and the Message Content intent enabled. +- Discord channel permissions to view channels, read message history, and send + messages where Crabstero should operate. + +## Discord setup + +In the [Discord Developer Portal](https://discord.com/developers/applications), +create an application, add a bot, and enable the Message Content intent for the +bot. Crabstero reads message content and embed text to learn channel-local +chains, so it cannot ingest channel history normally without that privileged +intent. + +Invite the application with these OAuth2 scopes: + +| Scope | Why Crabstero uses it | +|-------|------------------------| +| `bot` | Add the bot user to the selected server. | +| `applications.commands` | Install the `/pingme` and `/forgetme` slash commands. | + +Recommended bot permissions: + +| Permission | Why Crabstero uses it | +|------------|------------------------| +| View Channels | See the channels it should learn from and reply in. | +| Send Messages | Send generated replies when mentioned. | +| Send Messages in Threads | Reply when mentioned inside threads. | +| Embed Links | Send occasional generated embed replies. | +| Read Message History | Ingest accessible channel history on startup. | +| Use External Emojis | Preserve learned custom emoji tokens in generated replies. | + +The combined permissions integer for the recommended set is +`274878254080`. + +Example self-hosted invite URL: + +```text +https://discord.com/oauth2/authorize?client_id=YOUR_CLIENT_ID&scope=bot%20applications.commands&permissions=274878254080 +``` + +Replace `YOUR_CLIENT_ID` with the application ID from the Discord Developer +Portal. Channel permission overwrites still apply, so you can limit where +Crabstero learns and replies by restricting the bot role per channel. + +## Installation + +Create a directory for Crabstero, create a Python 3.14 virtual environment, and +install the package from the project's Gitea package index: + +```bash +mkdir crabstero && cd crabstero +uv venv --python 3.14 +uv pip install crabstero \ + --index https://git.logal.dev/api/packages/LogalDeveloper/pypi/simple/ \ + --default-index https://pypi.org/simple +``` + +## Usage + +Run Crabstero with a Discord bot token from the environment: + +```bash +TOKEN="your-discord-bot-token" uv run crabstero --database-path crabstero.db +``` + +On startup, Crabstero opens or creates the configured SQLite database, connects +to Discord, and begins ingesting channel history and new messages it can read. +Mention the bot in a channel to receive a generated reply once enough channel +data has been collected. + +## Configuration + +Crabstero is configured through CLI flags, environment variables, and systemd +credentials. CLI flags take precedence over environment defaults where both are +available. + +| Setting | CLI flag | Environment variable | Fallback/default | Description | +|---------|----------|----------------------|------------------|-------------| +| Discord token | `--token` | `TOKEN` | systemd credential `token` | Required Discord bot token. | +| Database path | `--database-path`, `--database` | `DATABASE_PATH` | `crabstero.db` | SQLite database file path. | +| Ingest-only mode | `--ingest-only` | | disabled | Ingest history and real-time messages without replying. | +| Metrics listener | `--listen-metrics` | `LISTEN_METRICS` | disabled | Prometheus metrics address, either `HOST:PORT` or `unix:/path.sock`. | +| Metrics socket mode | `--metrics-unix-socket-mode` | `METRICS_UNIX_SOCKET_MODE` | unchanged | Octal file mode for Unix socket metrics listeners. | + +When running under systemd, Crabstero can read the bot token from a credential +named `token`. It also sends readiness, stopping, and watchdog notifications +when the relevant systemd environment variables are present. + +## Development + +Clone the Git repository and use [uv](https://docs.astral.sh/uv/) to sync the +project environment from the lockfile: + +```bash +git clone https://git.logal.dev/LogalDeveloper/Crabstero +cd Crabstero +uv sync --locked +``` + +The development toolchain uses [Ruff](https://docs.astral.sh/ruff/) for +formatting and linting, [mypy](https://mypy.readthedocs.io/en/stable/) for type +checking, [codespell](https://github.com/codespell-project/codespell) for typo +detection, [pip-audit](https://github.com/pypa/pip-audit) for dependency +auditing, and [pytest](https://docs.pytest.org/en/stable/) with +[pytest-cov](https://pytest-cov.readthedocs.io/en/latest/) and +[Coverage.py](https://coverage.readthedocs.io/) for tests and +coverage reporting. + +Run the common checks: + +```bash +uv run ruff format --check --diff . +uv run ruff check . +uv run mypy . +uv run codespell +uv run pip-audit --skip-editable +uv run pytest +``` + +Run tests with coverage reporting: + +```bash +uv run pytest -v --cov --cov-report= +uv run coverage report +``` + +Tests are organized under `tests/unit` and `tests/integration`. The pytest +configuration marks tests automatically based on those directories. + +## Links + +- Project page: +- Source repository: + +## License + +Crabstero is licensed under the Apache License 2.0. See +[LICENSE.txt](LICENSE.txt) for the full license text.