A private repo that chases your unpaid invoices every morning using BadCop, on GitHub's free Actions minutes. No server, nothing to host.
- Click Use this template → Create a new repository. Make it private: your invoices will live here.
- Edit
badcop.toml: your sender identity (accounts@yourdomain), SMTP host and username, and your payment terms. Keeppassword_env = "BADCOP_SMTP_PASSWORD". - Replace
invoices.csvwith your invoices (columns are documented in the BadCop README). Or point--ledgerin the workflow at a Google Sheet published as CSV. - In the repo, open Settings → Secrets and variables → Actions:
- Secrets → New repository secret → name
BADCOP_SMTP_PASSWORD, value: your SMTP password or API token. - Nothing else yet. Leave it in dry-run mode for the first day.
- Secrets → New repository secret → name
- Open Actions → BadCop daily run → Run workflow. Read the dry-run log: every email that would have gone out is printed in full.
- Happy with the wording? Settings → Secrets and variables → Actions → Variables → New repository variable → name
BADCOP_LIVE, valuetrue. From the next run, emails are sent for real.
That's it. Every day at 08:00 UTC the workflow runs the ladder, sends what is due, and commits state.json back so nothing is ever sent twice.
- Money came in: mark the invoice
paidininvoices.csv(or runbadcop match bank.csv --applylocally and push). - New invoice: add a row. It enters the ladder from the next run.
- Pause everything: set
BADCOP_LIVEtofalse, or disable the workflow under Actions. - Change the tone: edit the files in
templates/.
The aging_report.md in this repo is refreshed on every run.