Zum Hauptinhalt springen

Eigene Skripte

Die eingebauten Skripte decken die üblichen Abläufe ab. Wenn Sie etwas brauchen, das sie nicht bieten — einen Schritt in anderer Reihenfolge, einen Bildschirm, den sie nie berühren, oder eine App, die weder TikTok noch Instagram ist — können Sie es selbst in einer beliebigen Sprache schreiben und sich von TikMatrix das Telefon überlassen lassen.

Voraussetzungen

Lizenzvoraussetzung

Eigene Skripte erfordern einen Pro-, Team- oder Business-Tarif. Der Starter-Tarif hat keinen Zugriff.

Die Gerätezahl Ihres Tarifs ist zugleich das Nebenläufigkeitslimit: Ein Pro-Tarif (20 Geräte) kann 20 Telefone gleichzeitig steuern — ob über eingebaute Aufgaben, eigene Skripte oder eine Mischung aus beidem.

Zwei Wege, ein Skript auszuführen

Eigenständig

Sie starten Ihr Programm selbst. TikMatrix leiht Ihnen nur die Geräte.

from tikmatrix import TikMatrix

client = TikMatrix()

for device in client.devices():
if device["busy"]:
continue
with client.device(device["serial"], label="my crawler") as d:
d.press("home")
print(d.info())

Gut für einmalige Aufgaben, Datenerfassung und alles, was Sie aus Ihrem eigenen Scheduler heraus starten wollen.

Verwaltet

Sie registrieren das Programm in TikMatrix, und es wird zu einer Aufgabe wie jede andere. Es bekommt die Aufgabenwarteschlange, die tarifabhängige Nebenläufigkeit, automatische Wiederholungen, das Aufgabenprotokoll und Zeitplanvorlagen. TikMatrix least das Gerät, bevor es Ihr Programm startet, und übergibt die Lease-ID über die Umgebung.

from tikmatrix import TikMatrix

with TikMatrix.from_env() as d: # Gerät ist bereits geleast
d.click(text="Log in")
print("done") # diese Zeile landet im Aufgabenprotokoll

Gut für alles, was wiederholt, zeitgesteuert oder auf vielen Geräten laufen soll.

Was wählen?

EigenständigVerwaltet
Wer startetSieDie Aufgabenwarteschlange von TikMatrix
Geräte-LeaseSie holen sieBeim Start bereits vorhanden
Wiederholungen, Zeitpläne, ProtokollSelbst bauenEnthalten
Ausführung auf vielen GerätenSchleife selbst schreibenEine Aufgabe pro Gerät, parallel verteilt
Am besten fürErkundung, Crawler, einmalige AufgabenAlles, was Sie wiederholen wollen

Sie können eigenständig anfangen, während Sie den Ablauf zurechtbiegen, und dieselbe Datei dann als verwaltetes Skript registrieren — die einzige Zeile, die sich ändert, ist TikMatrix.from_env().

Erste Schritte

1. Client-Bibliothek installieren

pip install requests

Kopieren Sie dann tikmatrix.py aus dem SDK-Verzeichnis neben Ihr Skript. Die Bibliothek ist eine einzelne Datei ohne weitere Abhängigkeiten.

Sie müssen sie nicht verwenden — die API ist schlichtes JSON über HTTP, und die rohen Endpunkte sind unten dokumentiert.

2. Skript schreiben

from tikmatrix import TikMatrix

client = TikMatrix()
with client.device("192.168.1.5:5555") as d:
d.press("home")
d.adb("shell", "am", "start", "-a", "android.settings.SETTINGS")
d.wait_for(text="Settings", timeout=15)
d.screenshot("settings.png")

Führen Sie es bei geöffnetem TikMatrix und angeschlossenem Telefon aus. Wenn ein Wörterbuch mit Geräteinformationen ausgegeben wird, ist alles verdrahtet.

3. Registrieren (nur verwalteter Modus)

Gehen Sie zu Geräte → Eigene Skripte → Skript hinzufügen:

FeldBedeutung
NameErscheint in der Skriptliste und im Aufgabenprotokoll
BefehlDie auszuführende Programmzeile, z. B. python C:/scripts/my_flow.py
ArbeitsverzeichnisOptional. Wo das Programm startet
PlattformSiehe Plattformmodi unten
ZeitlimitSekunden, bis das Skript beendet und die Aufgabe als fehlgeschlagen markiert wird. Standard 1800
Zusätzliche UmgebungsvariablenOptionales JSON-Objekt, das in die Programmumgebung eingemischt wird
AktiviertEin Skript abschalten, ohne es zu löschen. Ein deaktiviertes Skript kann nicht verteilt werden

Drücken Sie dann ▶ in der Skriptzeile und wählen Sie Ihre Geräte — genau wie bei einem eingebauten Skript.

Lassen Sie es den Assistenten schreiben

Der KI-Assistent kann aus einer Beschreibung in normaler Sprache ein eigenes Skript entwerfen und es in einem Schritt registrieren. Er zeigt Ihnen die ganze Datei, bevor irgendetwas auf die Festplatte geschrieben wird.

Geräte-Leases

Ein Telefon kann immer nur von einer Sache gesteuert werden. Es zu leasen sagt TikMatrix, dass das Gerät belegt ist, sodass:

  • die Aufgabenwarteschlange keine Aufgabe auf denselben Bildschirm schickt, und
  • Ihre JSON-RPC-Aufrufe den Agent-Zustand genauso melden wie ein eingebautes Skript, sodass der Watchdog einen beschäftigten statt eines stummen Agents sieht.

Eine Lease belegt außerdem einen Geräteplatz Ihres Tarifs.

Leases laufen ab — standardmäßig nach 120 Sekunden, maximal nach 600. Die Python-Bibliothek erneuert Ihre in einem Hintergrund-Thread und gibt sie beim Verlassen des with-Blocks frei, sodass ein abgestürztes Skript sein Gerät binnen Sekunden freigibt, statt es bis zum Neustart der App zu blockieren. Wenn Sie die API direkt ansprechen, müssen Sie die Heartbeats selbst senden.

Alle aktiven Leases sehen — und zwangsweise freigeben — können Sie unter Einstellungen → Developer API → Aktive Gerätesitzungen.

Plattformmodi

Ein registriertes Skript gibt an, worauf es zielt:

Generic — das Gerät wird unangetastet übergeben. Es wird keine App gestartet, kein Konto gewechselt, keine Eingabemethode geprüft, und hinterher wird nichts geschlossen. Verwenden Sie dies, um alles zu automatisieren, was nicht TikTok oder Instagram ist.

TikTok / Instagram — die App wird geöffnet und das Konto gewechselt, bevor Ihr Programm startet, und die App wird am Ende geschlossen — genau wie bei einem eingebauten Skript. TIKMATRIX_PACKAGE sagt Ihnen, welches Paket aufgelöst wurde. Verwenden Sie dies, um einen Schritt zu ergänzen, den die eingebauten Skripte nicht abdecken.

Umgebungsvariablen

Ein verwaltetes Skript erhält:

VariableBedeutung
TIKMATRIX_API_BASEServer-URL, z. B. http://127.0.0.1:50809
TIKMATRIX_SESSION_IDDie bereits für Sie gehaltene Lease
TIKMATRIX_SERIALDas Gerät, an das diese Aufgabe verteilt wurde
TIKMATRIX_PACKAGEAufgelöstes App-Paket
TIKMATRIX_PLATFORMtiktok, instagram oder generic

TikMatrix.from_env() liest all das für Sie.

Eigenständige Skripte bekommen nichts davon — leasen Sie ein Gerät explizit.

Was Sie unter Zusätzliche Umgebungsvariablen eintragen, wird darüber gemischt. Das ist der übliche Weg, einem registrierten Skript laufabhängige Einstellungen zu geben, ohne die Datei zu ändern.

Referenz der Python-Bibliothek

TikMatrix — die Verbindung

AufrufWas er tut
TikMatrix(base_url=None, timeout=30.0)Verbindet. Fällt zurück auf TIKMATRIX_API_BASE, dann http://127.0.0.1:50809
client.devices()Online-Geräte, jeweils mit serial, real_serial und busy
client.sessions()Alle aktiven Leases, auch die anderer Prozesse
client.device(serial, label=..., ttl_secs=120)Least ein Gerät und liefert ein Device
TikMatrix.from_env()Übernimmt das Gerät, mit dem ein verwaltetes Skript gestartet wurde

Device — das Telefon

AufrufWas er tut
d.info()UIAutomator2-Geräteinformationen
d.window_size()(Breite, Höhe)
d.screenshot(path=None)PNG-Bytes, optional nach path geschrieben
d.hierarchy()Der aktuelle UI-Baum als XML
d.find(text=, resource_id=, description=, class_name=)Passende Knoten, jeweils mit bounds und center
d.exists(**criteria)Ob irgendetwas passt
d.wait_for(timeout=10.0, interval=1.0, **criteria)Wartet aufs Erscheinen und liefert es zurück
d.click(timeout=10.0, **criteria)Wartet auf ein Element und tippt auf dessen Mitte
d.click_xy(x, y)Tippt auf eine Koordinate
d.swipe(sx, sy, ex, ey, steps=20)Wischt
d.press(key)back, home, recent, enter, …
d.input_text(text)Tippt über die mitgelieferte Schnelleingabe ins fokussierte Feld
d.jsonrpc(method, params=None, timeout=10)Beliebige UIAutomator2-Methode
d.adb(*args, timeout_ms=None)Führt einen ADB-Befehl aus
d.release()Gibt die Lease frei. with erledigt das für Sie

find sucht im ausgelesenen UI-Baum. Wenn ein Selektor danebengeht, können Sie also print(d.hierarchy()) aufrufen und genau sehen, worin gesucht wurde. Der Element-Inspektor in der Geräteansicht zeigt denselben Baum visuell — meist der schnellste Weg, eine resource-id zu finden.

input_text benötigt ADB

Es sendet einen Broadcast an die mitgelieferte Eingabemethode, was über adb shell läuft. Aktivieren Sie den ADB-Zugriff, bevor Sie es verwenden, sonst schlägt es mit 403 fehl.

Fehler

Die Bibliothek wirft zwei Ausnahmen, beide Unterklassen von RuntimeError:

AusnahmeWann
DeviceBusyErrorHTTP 409 — das Gerät ist bereits geleast, oder Ihr Tarif hat keinen freien Geräteplatz
TikMatrixErrorAlles andere: zu niedriger Tarif, abgelaufene Lease, ADB deaktiviert, Selektor hat nie gepasst
from tikmatrix import TikMatrix, TikMatrixError, DeviceBusyError

client = TikMatrix()
try:
with client.device("192.168.1.5:5555") as d:
d.click(text="Log in", timeout=20)
except DeviceBusyError:
print("dieses Telefon hat gerade jemand anderes — nehmen Sie ein anderes")
except TikMatrixError as exc:
print("fehlgeschlagen:", exc)

In einem verwalteten Skript ist es meist richtig, die Ausnahme durchzulassen: Der Exit-Code ungleich null markiert die Aufgabe als fehlgeschlagen, und der Traceback landet im Aufgabenprotokoll.

HTTP-Endpunkte

Geräteoperationen benötigen einen x-session-id-Header, der eine aktive Lease benennt. Es gibt keinen API-Schlüssel: Wie der Rest der lokalen API sind diese Endpunkte nicht authentifiziert — die Zugangskontrolle besteht darin, die Maschine im Netz überhaupt zu erreichen. Sie senden keine CORS-Header, rufen Sie sie also aus einem Programm auf (curl, Python, beliebiger serverseitiger Code) statt aus einer Seite im Browser.

MethodePfadZweck
GET/api/v1/rpc/devicesOnline-Geräte auflisten und ob sie belegt sind
POST/api/v1/rpc/sessionGerät leasen → session_id
POST/api/v1/rpc/session/{id}/heartbeatLease verlängern
DELETE/api/v1/rpc/session/{id}Lease freigeben
GET/api/v1/rpc/sessionAktive Leases auflisten
POST/api/v1/rpc/jsonrpcEine UIAutomator2-Methode aufrufen
POST/api/v1/rpc/adbEinen ADB-Befehl ausführen
GET/api/v1/rpc/hierarchy?serial=Aktueller UI-Baum als XML
GET/api/v1/rpc/screenshot?serial=Aktueller Bildschirm als PNG

JSON-Antworten verwenden dieselbe Hülle wie der Rest der lokalen API — {"code": 0, "message": "success", "data": ...}, mit code ungleich null im Fehlerfall. hierarchy und screenshot liefern stattdessen den rohen Body.

Beispiel

# Gerät leasen
curl -X POST http://127.0.0.1:50809/api/v1/rpc/session \
-H "Content-Type: application/json" \
-d '{"serial":"192.168.1.5:5555","label":"curl test","ttl_secs":120}'

# {"code":0,"message":"success","data":{"session_id":"ff3ae079-...","serial":"192.168.1.5:5555", ...}}

# Steuern
curl -X POST http://127.0.0.1:50809/api/v1/rpc/jsonrpc \
-H "x-session-id: ff3ae079-..." \
-H "Content-Type: application/json" \
-d '{"serial":"192.168.1.5:5555","method":"deviceInfo","params":[]}'

# Während der Arbeit am Leben halten
curl -X POST http://127.0.0.1:50809/api/v1/rpc/session/ff3ae079-.../heartbeat \
-H "Content-Type: application/json" \
-d '{"ttl_secs":120}'

# Zurückgeben
curl -X DELETE http://127.0.0.1:50809/api/v1/rpc/session/ff3ae079-...

Fehler

StatusBedeutung
403Tarif unter Pro, keine Lease, Lease abgelaufen oder ADB-Zugriff deaktiviert
409Gerät bereits geleast, oder Ihr Tarif hat keinen freien Geräteplatz

In einer anderen Sprache schreiben

Nichts hiervon ist Python-spezifisch. Jede Laufzeitumgebung, die eine HTTP-Anfrage stellen kann, funktioniert — der Vertrag des verwalteten Modus lautet nur: „lies drei Umgebungsvariablen, beende mit 0 bei Erfolg".

// my_flow.js — registrieren mit: node C:/scripts/my_flow.js
const base = process.env.TIKMATRIX_API_BASE || "http://127.0.0.1:50809";
const serial = process.env.TIKMATRIX_SERIAL;
const session = process.env.TIKMATRIX_SESSION_ID;

async function jsonrpc(method, params = []) {
const res = await fetch(`${base}/api/v1/rpc/jsonrpc`, {
method: "POST",
headers: { "content-type": "application/json", "x-session-id": session },
body: JSON.stringify({ serial, method, params }),
});
const body = await res.json();
if (!res.ok || body.code !== 0) throw new Error(body.message || res.statusText);
return body.data;
}

console.log(await jsonrpc("deviceInfo"));

Wenn der Interpreter nicht im PATH liegt, geben Sie den vollen Pfad im Feld Befehl an, z. B. C:/Program Files/nodejs/node.exe C:/scripts/my_flow.js.

Ein eigenes Skript über die API auslösen

Registrierte Skripte lassen sich auch über die Aufgaben-API starten, sodass ein Skript Folgearbeiten einreihen kann:

curl -X POST http://127.0.0.1:50809/api/v1/task \
-H "Content-Type: application/json" \
-d '{
"serials": ["192.168.1.5:5555"],
"script_name": "custom_script",
"script_config": {
"custom_script_id": 1,
"custom_script_platform": "generic"
}
}'

custom_script_id ist die ID des von Ihnen registrierten Skripts.

ADB-Zugriff

/api/v1/rpc/adb gibt Ihren Skripten eine Geräte-Shell — nötig zum Übertragen von Medien, Installieren von APKs und Ändern von Systemeinstellungen. Weil das eine vollwertige Shell auf einem Endpunkt ohne API-Schlüssel ist, wird sie deaktiviert ausgeliefert. Aktivieren Sie sie unter Einstellungen → Developer API → ADB-Befehle erlauben, sobald Sie ein Skript haben, das sie braucht; UI-Automatisierung über /rpc/jsonrpc funktioniert auch ohne.

Solange sie aus ist, antwortet /api/v1/rpc/adb mit 403, und der Rest der API arbeitet normal weiter. Jeder ADB-Befehl, den ein Skript ausführt, wird in Ihre Protokolldatei geschrieben.

Skripte schreiben, die weiter funktionieren

  • Warten Sie auf den Bildschirm, statt dafür zu schlafen. d.wait_for(...) kehrt zurück, sobald das Element da ist; ein festes Sleep ist entweder langsamer als nötig oder an einem schlechten Tag zu kurz.
  • Prüfen Sie, bevor Sie tippen. Ein d.exists(...) auf einen Einwilligungsdialog oder ein „Nicht jetzt" kostet einen Baumabzug und rettet einen Lauf, der sonst ins Leere getippt hätte.
  • Geben Sie aus, was Sie getan haben. Im verwalteten Modus ist stdout das Aufgabenprotokoll und damit die einzige Spur eines Laufs, den niemand beobachtet hat.
  • Machen Sie einen erneuten Lauf sicher. Eine Wiederholung führt das ganze Programm erneut aus; ein Skript, das postet, sollte prüfen, ob es bereits gepostet hat, statt anzunehmen, es beginne bei null.
  • Ein Skript, eine Aufgabe. Nebenläufigkeit gilt pro Gerät: Zehn kleine Aufgaben auf zehn Telefonen sind weit schneller fertig als ein Skript, das zehn Telefone in einer Schleife abarbeitet.

Hinweise und Grenzen

  • Der Befehl wird direkt ausgeführt, nicht über eine Shell; && und | gelten daher als Argumente, nicht als Operatoren. Registrieren Sie cmd /c "..." (Windows) oder sh -c "..." (macOS), wenn Sie Shell-Verhalten wollen.
  • Setzen Sie Pfade mit Leerzeichen in Anführungszeichen: "C:/Program Files/Python/python.exe" my_script.py.
  • Ein Skript, das sein Zeitlimit überschreitet, wird beendet und die Aufgabe als fehlgeschlagen markiert.
  • Ein Exit-Code ungleich null markiert die Aufgabe als fehlgeschlagen; alles, was das Skript auf stdout und stderr schreibt, landet im Aufgabenprotokoll.
  • Skripte laufen mit denselben Rechten wie TikMatrix selbst. Registrieren Sie nur Programme, die Sie geschrieben haben oder denen Sie vertrauen.

Fehlerbehebung

API access requires Pro or higher plan (403) Die Lizenz auf dieser Maschine ist Starter oder inaktiv. Prüfen Sie Einstellungen → Lizenz.

Verbindung auf 127.0.0.1:50809 abgelehnt TikMatrix läuft nicht oder unter einem anderen Benutzer. Den Server gibt es nur, solange die App geöffnet ist.

409 bei jedem Lease-Versuch Entweder ist das Telefon tatsächlich belegt — nachsehen unter Einstellungen → Developer API → Aktive Gerätesitzungen — oder alle Geräteplätze Ihres Tarifs sind schon von laufenden Aufgaben belegt.

Die Lease läuft mitten in einem langen Schritt ab Der Standard-TTL beträgt 120 s und die Bibliothek erneuert ihn im Hintergrund; das bedeutet also meist, dass das Skript seinen Haupt-Thread länger als den TTL blockiert hat. Erhöhen Sie ttl_secs (bis 600) oder verlagern Sie die lange Arbeit aus diesem Thread.

d.adb(...) schlägt mit 403 fehl Der ADB-Zugriff ist aus. Schalten Sie ihn unter Einstellungen → Developer API → ADB-Befehle erlauben ein.

Ein Selektor passt nie print(d.hierarchy()) zeigt genau den Baum, den find durchsucht hat. Text wird exakt verglichen; ein zusätzliches Leerzeichen oder eine übersetzte Beschriftung ist die übliche Ursache. Über resource_id zu suchen ist stabiler als über text.

Die Aufgabe gilt als fehlgeschlagen, das Telefon sieht aber gut aus Lesen Sie das Aufgabenprotokoll. Ein Exit-Code ungleich null — auch eine unbehandelte Ausnahme am Ende eines erfolgreichen Laufs — lässt die Aufgabe scheitern, selbst wenn die Automatisierung funktioniert hat.

Nächste Schritte