A small, production-minded Rust CLI that:
- Reads a dataset file (CSV/text) or a list of lines,
- Selects an item (optionally deterministic via
--seed), - Renders a message (optional
--template), and - Posts to a Mastodon instance β or prints output in
--dry-runmode.
This repo is designed to be safe to automate (GitHub Actions / cron), with quality gates (fmt/clippy/tests) and sane defaults.
- CLI-first UX (
--dry-run,--file,--limit) - Safe automation: never logs tokens, easy secret configuration
- Deterministic runs via
--seed(useful for testing) - Template support for message formatting
- GitHub Actions CI + scheduled βDaily Tootβ example workflow
- Rust (stable) + Cargo
- A Mastodon account on your target instance
- An access token permitted to create statuses
Copy .env.example to .env and fill values:
cp .env.example .envRun once:
cargo run -- --dry-run --file ./data/example.txt --limit 1Post for real:
cargo run -- --file ./data/example.txt --limit 1This tool reads config from (in order):
- CLI flags
- Environment variables (including
.env)
MASTODON_BASE_URL(e.g.,https://botsin.space)MASTODON_ACCESS_TOKEN(treat like a password)- Optional defaults:
INPUT_FILE(default dataset path)TOOT_TEMPLATE(default template)
mastodon-toot-client [OPTIONS]
Options:
-f, --file <PATH> Input file path (falls back to INPUT_FILE env var)
-l, --limit <N> Max number of posts to emit in this run [default: 1]
--template <STRING> Message template (falls back to TOOT_TEMPLATE env var)
--seed <N> Deterministic seed (useful for tests)
--dry-run Print output without posting
--verbose Enable more logs
-h, --help Print helpThe template supports these placeholders:
{item}β the selected line/record{idx}β the index selected (0-based){total}β total candidate items
Example:
cargo run -- \
--dry-run \
--file ./data/example.txt \
--template "Today: {item} (#{idx}/{total})"This repo includes a scheduled workflow example: .github/workflows/schedule-toot.yml.
Set these under: Settings β Secrets and variables β Actions
MASTODON_BASE_URLMASTODON_ACCESS_TOKEN
Optional:
INPUT_FILE(if you want to pass a path; otherwise commit a dataset file underdata/)TOOT_TEMPLATE
Run locally:
cargo fmt --all -- --check
cargo clippy --all-targets --all-features -- -D warnings
cargo test --allCI runs the same checks on every PR.
- Never commit
.envor tokens. - Use GitHub Secrets for automation.
- Tokens must be scoped to the minimum required permissions.
See SECURITY.md.
- CSV schema support (e.g., city name + country fields)
- Rate limit/backoff and retry strategy
- Multi-status batching with interval (
--limit N --sleep-ms M) - Optional media uploads
- Release binaries via GitHub Releases
MIT β see LICENSE.