Matrix-Nutzer per Terminal auflisten: Echte Konten von Bots und Bridges trennen

Ich wollte eigentlich nur wissen, wie viele echte Benutzer noch auf meinem Matrix-Server aktiv sind. Der erste Aufruf der Synapse-API war da wenig hilfreich. Telegram-, Discord- und andere Bridge-Konten füllten die Liste. Nachdem ich meinen jq-Filter ergänzt hatte, kam allerdings gar nichts mehr.

Kurz dachte ich, ich hätte die falsche API erwischt. Das Problem war am Ende viel kleiner: Mein Filter verlangte ein Feld, das in der Antwort gar nicht vorhanden war.

Token einlesen und erst einmal nichts filtern

Für die Admin-API brauche ich ein Zugriffstoken eines Serveradministrators. Ich schreibe es nicht direkt in den Befehl, weil es sonst im Shell-Verlauf landet:

read -rsp "Matrix-Admin-Token: " MATRIX_TOKEN; echo
MATRIX_URL="https://matrix.example.de"Code-Sprache: PHP (php)

Die Beispieladresse ersetze ich natürlich durch meine eigene Matrix-Domain. Danach lasse ich mir zunächst die unveränderte Liste ausgeben:

curl -s \
  -H "Authorization: Bearer $MATRIX_TOKEN" \
  "$MATRIX_URL/_synapse/admin/v3/users?limit=1000" \
| jq -r '.users[] | .name'Code-Sprache: JavaScript (javascript)

Nun sehe ich, was Synapse wirklich liefert. Bridge-Konten erkennt man oft an Präfixen wie @telegram_…. Diese Namen sind aber nicht überall gleich. Deshalb nehme ich die Muster aus meinen eigenen Appservice-Konfigurationen und nicht aus irgendeiner fremden Liste.

Warum mein erster Filter alles verschwinden ließ

In meinem ersten Versuch stand select(.suspended == false). Klingt erst einmal logisch. Fehlt suspended in der Antwort, ist der Wert für jq aber null und nicht false. Damit flog jedes Konto aus der Auswahl.

Welche Felder wirklich vorhanden sind, sehe ich so:

jq '.users[0] | keys'Code-Sprache: JavaScript (javascript)

Bei optionalen Wahrheitswerten ist select(.deactivated != true) für diesen Zweck robuster. Es lässt sowohl false als auch ein fehlendes Feld durch.

Aktive Konten ohne Bots und Appservices

Mein grundlegender Filter sieht nun so aus:

curl -s \
  -H "Authorization: Bearer $MATRIX_TOKEN" \
  "$MATRIX_URL/_synapse/admin/v3/users?limit=1000" \
| jq -r '
  .users[]
  | select(.deactivated != true)
  | select((.user_type // "") != "bot")
  | select((.appservice_id // "") == "")
  | .name
'Code-Sprache: PHP (php)

Auch das ist kein Zauberfilter. Wenn die Listenantwort keine appservice_id enthält, kann diese Bedingung Bridge-Konten nicht erkennen. Dann ergänze ich gezielt die Namensräume meiner eigenen Bridges. So ist die Gefahr kleiner, versehentlich einen echten Benutzer mit einem ähnlich klingenden Namen auszublenden.

Sind das wirklich alle Konten?

Die Antwort kann einen next_token enthalten. Dann wartet noch eine weitere Seite und der nächste Aufruf benötigt diesen Wert als Parameter from. Bei meiner überschaubaren Installation reichen 1.000 Einträge, kontrollieren möchte ich den Token trotzdem.

Für längere Terminalarbeiten nutze ich gern eine Sitzung, die einen Verbindungsabbruch überlebt. Das habe ich in meiner tmux-Anleitung für Einsteiger beschrieben.

Der wichtigste Schritt war diesmal übrigens nicht der fertige Filter, sondern der Blick auf die echte JSON-Antwort. Habt ihr in euren Matrix-Listen auch mehr Bridge-Konten als Menschen?

Wie ist deine Meinung?
Schreib gern einen Kommentar unter dem Artikel oder diskutiere mit anderen im Matrix-Kanal: #dasnetzundich:matrix.org

Schreibe einen Kommentar