All projects

02 / 04 · Telegram bot

Muster

Muster is a Telegram bot for keeping a unit's parade state right. I first built it during National Service to account for my company's strength, and it has grown since. Supervisors record MCs, leave and statuses in one line or with buttons. Soldiers report sick themselves for approval, and the parade state posts itself to the group every morning. It's invite-only, with roles, and keeps medical details encrypted and out of group chats.

  • Python
  • python-telegram-bot
  • SQLite
  • AES-256-GCM
  • Pillow
  • pytest

01 / Features

What it does

01

The parade state, always right

Strength is worked out live from the roster and everyone's dates, so it's right the moment anything changes and nothing has to be cleared each morning. It posts itself to the group at a set time and can show one platoon at a time. A group never sees medical details unless an admin allows it.

  • Scheduled reports
  • Live totals
  • Privacy

02

In one line, or step by step

Type /mc lim 2d fever the way you'd write it, or send just /mc to go step by step with buttons: who, what, when (with a date picker in the chat) and why. When a name matches two people, it asks which one. Every entry can be undone.

  • Inline keyboards
  • Date picker
  • Undo

03

Report sick, get approved

Soldiers report their own MC with a photo of the slip. Their supervisors get it with Approve and Reject buttons. Once it's approved, the parade state updates and the soldier is told. Only that soldier's own supervisors can decide, however the button is pressed.

  • Approval workflow
  • Photos
  • Role checks

04

Invite-only, with roles

People join through a one-time invite link or QR code that expires in 48 hours. Members, supervisors and admins each see their own command menu. Supervisors can only change their own platoon, and anyone not on the roster gets nothing.

  • Deep links
  • Role-based access
  • Scoped menus

05

History and trends

A soldier's supervisors can see all their MCs, statuses and time out, with this year's totals. /trend charts four weeks of who was out and why, with every number written on the bars, so a bug going round a platoon stands out.

  • Charts
  • Pillow
  • Colour-blind safe

06

Roster in, records out

Send a spreadsheet to update the roster. It shows who's new, who moved and who's left before changing anything, and people who leave keep their history. Any month exports as a CSV for the office.

  • CSV import
  • Change preview
  • Export

07

Settings and morning reminders

Admins choose when the daily parade state goes out, whether it runs on weekends, and whether groups see medical details. Each morning, supervisors get a note of who's due back, who's away from today and whose status ends.

  • Scheduling
  • Reminders
  • Admin controls

02 / Compared

What it replaces

When it comes toA spreadsheet and a group chatMuster
Counting the strengthTallied by hand every morning. Platoon totals are retyped whenever someone joins or leaves.Worked out live from the roster and everyone's dates, whenever it's asked.
Recording an MCA message to whoever keeps the sheet, copied in later.One line or a few taps, or the soldier reports it themselves for approval.
Medical privacyDiagnoses end up in group chats and shared sheets.Encrypted in the database and shown only to that soldier's supervisors. Groups see no medical details.
Who can change itAnyone with the link.Invite-only. Supervisors change only their own platoon, and every change is logged.
The morning parade stateCompiled and posted by hand.Posted to the group on its own at a set time, and refreshable any time.
MistakesOverwritten cells and no history.Undo, and a full history for every soldier.

The trade-off: it needs a small computer that stays on to answer messages, and everyone needs Telegram.

03 / Screens

A closer look

The parade state posted in the group chat at 07:30, with each platoon's strength

The morning parade state

Posted to the group at 07:30, in the usual format, with statuses shown without their medical details.

A soldier's MC report with a photo of the slip, and the same report on his supervisor's phone with Approve and Reject buttons

Approve in one tap

The soldier's report on the left, and on the right the copy that reaches his supervisor.

A bar chart of people out of camp each day for four weeks, split into MC, leave and off, and other, with each day's total written on its bar

Four weeks at a glance

Out of camp each day, by reason. The run of MCs in mid-September is a stomach bug going round one platoon.

04 / Security design

How it's built

  • Every tap is checked

    Every command and button press is checked against the person's role and platoon. Telegram lets a client send any button data, so buttons are never trusted, and each step-by-step flow carries a random token so an old menu can't act on a new one.

  • Medical details, encrypted

    Diagnoses, hospitals and reasons are sealed with AES-256-GCM, each bound to its own soldier and record. The encryption key and the bot token live in the Keychain or the environment, never in the code.

  • Invites that can't be guessed

    Each invite is a 144-bit code that works once and expires in 48 hours, and only its SHA-256 hash is stored. After five wrong codes in an hour, that account has to wait.

  • Real dates, not text

    Who's in camp is worked out from real dates every time. The first version compared dates as text, so it cleared MCs on the wrong day. Tests now cover both bugs.

  • Tested like an attack

    35 automated tests run whole conversations through the real bot against a stand-in for Telegram's servers. They include strangers, forged buttons, a soldier approving his own MC and guessed invite codes. The demos on this page were recorded the same way.

  • Nothing leaks in errors

    Errors are logged, never sent to the chat, where the first version replied with the raw error. Exports neutralise spreadsheet formulas, and the logs never print the bot token.