# Mastomation
`mastomation` is a small Elixir CLI for Mastodon account workflows.
It can:
- inspect and export thread content
- delete your posts with safety defaults
- download and search your private profile notes
For delete workflows, it **keeps pinned, bookmarked, and favourited (by you) statuses** and only deletes the rest.
## Warning
This tool performs destructive actions against your account.
- Deletions are permanent.
- Start with `--dry-run` to verify which statuses would be removed.
- Use a dedicated access token with only the permissions you need.
## Requirements
- Elixir `~> 1.18`
- Network access to your Mastodon instance
- A Mastodon access token able to delete statuses
## Create a Mastodon access token
1. Open your instance app page:
- `https://<your-instance>/settings/applications/new`
2. Create a new application (name can be anything, e.g. `mastomation`).
3. Enable these permissions/scopes:
- `read`
- `write`
- `profile`
4. Save the application and copy the generated access token.
5. Configure these environment variables:
- `MASTODON_INSTANCE_URL`
- `MASTODON_ACCESS_TOKEN`
Examples:
Bash:
```bash
export MASTODON_INSTANCE_URL="https://mastodon.social"
export MASTODON_ACCESS_TOKEN="YOUR_TOKEN"
```
Fish:
```fish
set -x MASTODON_INSTANCE_URL "https://mastodon.social"
set -x MASTODON_ACCESS_TOKEN "YOUR_TOKEN"
```
You can also pass them as CLI options (`--instance-url` and `--access-token`).
## Installation
### Nix (one-shot local install)
This repository includes a `shell.nix` that provides:
- `beam28Packages.erlang` (required so `escript` works correctly)
- `beam28Packages.elixir_1_19`
- tools needed for install flow
Run everything (deps + escript install + fish completion install) in one command:
```bash
nix-shell --run ./scripts/nix-install-local.sh
```
After that, run the binary from local install path:
```bash
./.mix/escripts/mastomation --help
```
If you want it globally in your current shell session:
```bash
export PATH="$PWD/.mix/escripts:$PATH"
```
Install from source:
```bash
git clone https://codeberg.org/maikelthedev/mastomation.git
cd mastomation
mix deps.get
```
Build the escript:
```bash
mix escript.build
```
Install it:
```bash
mix escript.install
```
After installation, the executable is available under:
```bash
~/.mix/escripts/mastomation
```
Add `~/.mix/escripts` to your `PATH` so you can run `mastomation` directly.
If you prefer running from source in the project folder:
```bash
iex -S mix
```
Then call modules directly:
```elixir
Mastomation.run(["delete", "--dry-run"])
Mastomation.run(["thread", "see", "https://mastodon.social/@me/123456789012345678"])
```
## Usage
Run without arguments to see help:
```bash
mastomation
```
Deletion is explicit, and credentials can be passed as flags or environment variables:
```bash
mastomation delete all
```
Or, without env vars:
```bash
mastomation delete all --instance-url https://mastodon.social --access-token YOUR_TOKEN
```
### Options
`delete all` subcommand options:
- `-i`, `--instance-url INSTANCE_URL`: Mastodon instance URL
- `-t`, `--access-token ACCESS_TOKEN`: access token
- `-d`, `--delay-ms MILLISECONDS`: delay between deletions (default: `60000`)
- `--keyword KEYWORD` (repeatable): delete only statuses containing keyword(s)
- `--override-instance-url INSTANCE_URL`: override target instance for this run
- `--override-access-token ACCESS_TOKEN`: override token for this run
- `--dry-run`: print what would be deleted, but do not delete
- `--no-backup`: skip backup export before delete
- `--frontmatter`: include YAML frontmatter in backup markdown files
By default, delete operations backup statuses before deleting. Backups are written under `./export/backups` (relative to where you run `mastomation`).
`delete thread` command:
```bash
mastomation delete thread https://mastodon.social/@me/123456789012345678
```
`delete thread` uses the same auth/backup/keyword flags as `delete all`, includes the source toot if authored by you, and caps delay at 2 seconds between deletions because thread batches are typically shorter and less likely to hit Mastodon's default delete rate limit (30 deletions per 30 minutes).
### Thread subcommands
Inspect a joined thread from a source toot (same author only), including replies/subtoots in order.
```bash
mastomation thread see https://mastodon.social/@me/123456789012345678
```
Export the thread to markdown and media files under `./export`:
```bash
mastomation thread export https://mastodon.social/@me/123456789012345678
```
Thread auth options:
- `-i`, `--instance-url INSTANCE_URL`
- `-t`, `--access-token ACCESS_TOKEN`
- `--frontmatter`: include YAML frontmatter in exported markdown
- `--override-instance-url INSTANCE_URL`
- `--override-access-token ACCESS_TOKEN`
### Notes subcommands
Download private profile notes for accounts you follow and that follow you:
```bash
mastomation notes download
```
Search downloaded notes:
```bash
mastomation notes search "project"
mastomation notes search --term ops --term infra
```
Optional notes flags:
- `--path FILE_PATH`: custom notes JSON location
Default notes file location:
- `$XDG_DATA_HOME/mastomation/notes.json` (or `~/.local/share/mastomation/notes.json` when `XDG_DATA_HOME` is unset)
`notes download` also supports auth override flags:
- `-i`, `--instance-url INSTANCE_URL`
- `-t`, `--access-token ACCESS_TOKEN`
- `--override-instance-url INSTANCE_URL`
- `--override-access-token ACCESS_TOKEN`
Notes search profile links use `MASTODON_INSTANCE_URL`. If `MASTODON_UI=DECK`, links are rendered as `/deck/@handle` (for example `https://vmst.io/deck/@nik@toot.teckids.org`).
Compatibility aliases still supported:
- `mastomation thread <URL_OR_ID>` behaves like `mastomation thread see <URL_OR_ID>`
- `mastomation delete` behaves like `mastomation delete all`
- `mastomation delete --thread-source <URL_OR_ID>` behaves like `mastomation delete thread <URL_OR_ID>`
## Examples
Delete all with default backup:
```bash
mastomation delete all
```
Delete by keyword only:
```bash
mastomation delete all --keyword projectx --keyword launch
```
Delete your replies in a thread:
```bash
mastomation delete thread https://mastodon.social/@me/123456789012345678
```
## Behavior
The tool:
1. Resolves your account ID via `/api/v1/accounts/verify_credentials`
2. Fetches statuses in pages (`limit=40`) from `/api/v1/accounts/:id/statuses`
3. Filters out pinned/bookmarked/favourited statuses
4. Deletes each remaining status via `/api/v1/statuses/:id`
5. Waits `delay_ms` between deletions to reduce rate-limit pressure
## Development
Run tests:
```bash
mix test
```
Format and lint:
```bash
mix format
mix credo
```
## Shell completions
Fish completion file:
- `completions/mastomation.fish`
### Install Fish completions
If you used the Nix one-shot installer above, fish completion is already installed automatically at:
- `~/.config/fish/completions/mastomation.fish`
Copy-based install:
```bash
mkdir -p ~/.config/fish/completions
cp completions/mastomation.fish ~/.config/fish/completions/mastomation.fish
```
Symlink-based install (recommended during development):
```bash
mkdir -p ~/.config/fish/completions
ln -sf "$PWD/completions/mastomation.fish" ~/.config/fish/completions/mastomation.fish
```
Reload fish (or open a new shell):
```bash
exec fish
```
## Versioning and changelog
- Semantic versioning policy: `SEMVER.md`
- Change history: `CHANGELOG.md`
## Telemetry events
Mastomation emits telemetry events you can attach to:
- `[:mastomation, :http, :get, :start]` / `:stop` (metadata includes `url`)
- `[:mastomation, :http, :delete, :start]` / `:stop` (metadata includes `url`, `attempt`)
- `[:mastomation, :delete, :all, :start]` / `:stop`
- `[:mastomation, :delete, :thread, :start]` / `:stop` (metadata includes `thread_source`)
- `[:mastomation, :thread, :export, :start]` / `:stop` (metadata includes `dry_run`)