malandereideen

Eine App, die andere Apps bedient

·Software & KI

Angefangen hat das mit einer simplen Frage. Wie poste ich auf Instagram, TikTok, WhatsApp und YouTube in einem Rutsch, ohne fünfmal dasselbe zu klicken? Die Recherche war ernüchternd. Auf dem iPhone geht Fernsteuerung grundsätzlich nicht, und bei den zwei Kanälen, die wirklich klemmen, fehlt am Mac schlicht die Funktion. Eigentlich hätte ich es dabei belassen können. Aber im Job hab ich genau sowas gebaut, Software die andere Software fernbedient. Im Industrieumfeld heißt das RPA, Programme die andere Programme steuern. Kommerzielle Werkzeuge wie UiPath oder AutoIt machen nichts anderes. Warum also nicht selber. Daraus wurde AppWorker, eine App in Rust mit einer Oberfläche über Tauri. Sie bedient andere Programme über feste Abläufe. Das Ding startet das Zielprogramm selbst, an fester Position und in fester Größe. So ist der Ausgangszustand bei jedem Lauf gleich und der Ablauf wiederholbar. Ändert sich das Zielprogramm, muss ich den Ablauf anfassen. Den Preis zahl ich bewusst.

Erst messen, dann bauen

Meine Grundannahme kam aus dem Lehrbuch. Klick nicht auf Pixel, sondern sprich die Bedienelemente über ihre Kennung an. Jeder Knopf hat intern einen Namen, der bleibt auch wenn sich das Fenster verschiebt oder die Sprache wechselt. Klingt erst mal logisch. Also hab ich erst gemessen statt geraten. Ein kleines Werkzeug, das den Bedienbaum echter Programme ausliest. Das ist der Accessibility-Baum, über den macOS jedes Fenster für Hilfstechnik beschreibt. Getestet an vier Programmen: Finder, Bambu Studio, meiner eigenen kleinen App und Blender. Das Ergebnis hat den Plan umgeworfen. Über alle vier zusammen hatte genau ein einziger Knopf so eine feste Kennung. Einer. Bambu Studio hat 299 Elemente im Baum, davon 27 von 32 Knöpfen ganz ohne Namen. Blenders Baum ist praktisch leer, da findet man nichts zum Anklicken. Adressieren über Kennungen war auf dem Mac also tot. Zwei Funde haben den Tag gerettet. Der erste: sichtbarer Text ist fast immer da. Ein Knopf heißt “Exportieren”, das kann ich abgreifen. Der Haken ist die Sprache. Ein Ablauf, der nach “Exportieren” sucht, läuft auf einem englischen System ins Leere. Für eine deutsche Zielgruppe kein Drama, international schon. Der zweite war der eigentliche Gewinn: die Menüleiste. Die ist etwas ganz anderes als der Bedienbaum, ein eigener Kanal, und der ist erstaunlich vollständig. Jeder Befehl ist über seinen Pfad erreichbar und drücken lässt er sich auch. Sogar Blender, das im Baum nichts hergibt, hat 108 Menübefehle. Der stabilste Hebel von allen, und vorher gar nicht auf meinem Zettel. Am Ende steht statt der geratenen dreistufigen Adressierung eine mit sechs Stufen. Kennung, Menübefehl, sichtbarer Text, Baumpfad, Bildvergleich, Koordinate. Von oben nach unten durchprobiert. Rutscht ein Klick auf eine tiefere Stufe als geplant, ist das die Frühwarnung, dass gleich was bricht.

Vom Format zum Node-Editor

Tag eins ging fürs Fundament drauf. Das Dateiformat für einen Ablauf, der Abspieler mit drei Betriebsarten (Trockenlauf ohne einen einzigen Klick, Vorführen mit sichtbarer Maus und Erklärung, einfach Machen), die Bildanker, ein Rekorder. Drei echte Abläufe liefen durch, einer davon gleich beim ersten Versuch fehlerfrei. Das ist der Moment, wo aus einem Versuchsaufbau ein Werkzeug wird. Tag zwei war anders. Da hab ich zusammen mit Claude live einen visuellen Editor gebaut, so wie man ihn von n8n kennt. Knoten auf einer Fläche, mit Linien verbunden, jeder Knoten ein Schritt. Statt eine Liste zu tippen zieht man sich den Ablauf zusammen. Beim Bauen findet man Sachen, die man beim Planen übersieht. Zwei Fehler haben uns aufgehalten. Der erste: Lade ich einen gespeicherten Ablauf und setze dann einen neuen Knoten dazu, bekommen beide dieselbe interne Nummer. Der Zähler für neue Knoten startete stur bei 100 und guckte nicht, welche Nummern der geladene Ablauf schon belegt hatte. Ich klicke einen Knoten an, zwei werden markiert. Ich verschiebe einen, der falsche bewegt sich. Nervig zu finden war das, der Fix dann eine Zeile. Der zweite hat länger gedauert. Ein Schritt soll beim Lauf fragen, welchen Text er tippen soll. Der blieb einfach stehen und blinkte vor sich hin. Die Frage kam nie im Fenster an. Der Grund: die App schickt so eine Frage als Live-Ereignis ans eigene Fenster, und in meinem Aufbau kamen die dort nicht an. Der Fortschritt läuft nämlich über ein Protokoll, das das Fenster alle 400 Millisekunden abfragt. Sobald die Frage auch dort reingeschrieben wurde, ging es. Die Lehre steht jetzt dick in meinen Notizen. Alles Interaktive über das Protokoll, nie über Live-Ereignisse. Am Abend kamen noch ein paar Bausteine dazu. Eine Weiche, bei der der Mensch am Bildschirm den Weg per Menü wählt. Eine Notiz, die man auf die Fläche pinnt. Sprungmarken, um lange Ketten zu zerteilen. Unterroutinen mit Rücksprung, damit ein Ablaufstück, das man öfter braucht, nur einmal existiert.

Stand jetzt

Der TextEdit-Ablauf, den wir am Abend gebaut haben, läuft komplett durch. Von Null. Programm starten, im Öffnen-Dialog auf “Neues Dokument” klicken, Fenster setzen, Text tippen, fertig. Der Klick auf “Neues Dokument” ging sogar über eine echte Kennung. Die Öffnen-Dialoge von macOS sind also sauber benannt, anders als fast alles andere. Ehrlich beim Rest. Weiche und Unterroutinen sind gebaut und der Code kompiliert, aber ich hab sie noch nicht in einem echten Durchlauf gesehen. Der nächste Schritt ist entsprechend unspektakulär. App neu bauen und die zwei Sachen an einem kleinen Testfall durchspielen. Eine Weiche mit zwei Wegen, eine Unterroutine, die an zwei Stellen aufgerufen wird. Eine Grundregel steht seit dem ersten Tag fest. API, wenn es eine gibt. AppWorker ist der Notausgang für den Fall, dass keine da ist. Ein Klick-Roboter auf einer fremden Webseite verstößt gegen deren Bedingungen und riskiert das Konto. Dafür ist das Ding nicht gemacht.

Entwurf mit KI aus meinen Projektnotizen, redigiert von mir.Wie diese Texte entstehen