Eigen scripts
De ingebouwde scripts dekken de gebruikelijke stromen af. Wanneer je iets nodig hebt wat ze niet bieden — een stap in een andere volgorde, een scherm dat ze nooit aanraken, of een app die geen TikTok of Instagram is — kun je het zelf schrijven in elke taal en laat TikMatrix je de telefoon overhandigen.
Vereisten
Eigen scripts vereisen een Pro-, Team- of Business-abonnement. Het Starter-abonnement heeft geen toegang.
Het aantal apparaten in je abonnement is tevens de gelijktijdigheidslimiet: een Pro-abonnement (20 apparaten) kan 20 telefoons tegelijk aansturen, via ingebouwde taken, eigen scripts of een mix van beide.
Twee manieren om een script te draaien
Zelfstandig
Je start je programma zelf. TikMatrix leent je alleen apparaten uit.
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())
Geschikt voor eenmalige klussen, dataverzameling en alles wat je vanuit je eigen planner wilt starten.
Beheerd
Je registreert het programma in TikMatrix en het wordt een taak als alle andere. Het krijgt de takenwachtrij, gelijktijdigheid volgens abonnement, automatische nieuwe pogingen, het takenlogboek en planningssjablonen. TikMatrix least het apparaat voordat het je programma start en geeft het lease-id mee in de omgeving.
from tikmatrix import TikMatrix
with TikMatrix.from_env() as d: # apparaat is al geleased
d.click(text="Log in")
print("done") # deze regel belandt in het takenlogboek
Geschikt voor alles wat je herhaaldelijk, volgens schema of op veel apparaten wilt draaien.
Welke kiezen
| Zelfstandig | Beheerd | |
|---|---|---|
| Wie start het | Jij | De takenwachtrij van TikMatrix |
| Apparaatlease | Neem je zelf | Al in handen bij de start |
| Nieuwe pogingen, planning, logboek | Bouw je zelf | Inbegrepen |
| Draaien op veel apparaten | Je schrijft zelf de lus | Eén taak per apparaat, parallel verdeeld |
| Het meest geschikt voor | Verkennen, crawlers, eenmalige klussen | Alles wat je wilt herhalen |
Je kunt zelfstandig beginnen terwijl je de stroom afstemt en daarna hetzelfde bestand registreren als beheerd script — de enige regel die verandert is TikMatrix.from_env().
Aan de slag
1. Installeer de clientbibliotheek
pip install requests
Kopieer daarna tikmatrix.py uit de SDK-map naast je script. De bibliotheek is één bestand zonder verdere afhankelijkheden.
Je hoeft haar niet te gebruiken — de API is gewone JSON over HTTP, en de ruwe endpoints staan hieronder beschreven.
2. Schrijf je script
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")
Draai het met TikMatrix open en de telefoon aangesloten. Print het een woordenboek met apparaatgegevens, dan zit alles goed aangesloten.
3. Registreer het (alleen beheerde modus)
Ga naar Apparaten → Eigen scripts → Script toevoegen:
| Veld | Betekenis |
|---|---|
| Naam | Zichtbaar in de scriptlijst en het takenlogboek |
| Opdracht | De programmaregel die wordt uitgevoerd, bv. python C:/scripts/my_flow.py |
| Werkmap | Optioneel. Waar het programma start |
| Platform | Zie platformmodi hieronder |
| Time-out | Seconden voordat het script wordt afgebroken en de taak als mislukt wordt gemarkeerd. Standaard 1800 |
| Extra omgevingsvariabelen | Optioneel JSON-object dat in de omgeving van het programma wordt samengevoegd |
| Ingeschakeld | Zet een script uit zonder het te verwijderen. Een uitgeschakeld script kan niet worden uitgedeeld |
Druk daarna op ▶ in de scriptregel en kies je apparaten, precies zoals bij een ingebouwd script.
De AI-assistent kan een eigen script opstellen aan de hand van een omschrijving in gewone taal en het in één stap registreren. Hij toont je het hele bestand voordat er iets naar schijf wordt geschreven.
Apparaatleases
Een telefoon kan maar door één ding tegelijk worden aangestuurd. Hem leasen vertelt TikMatrix dat het apparaat bezet is, zodat:
- de takenwachtrij geen taak naar hetzelfde scherm stuurt, en
- je JSON-RPC-aanroepen de gezondheid van de agent net zo rapporteren als een ingebouwd script doet, waardoor de watchdog een drukke agent ziet in plaats van een zwijgende.
Een lease verbruikt ook één apparaatplek uit je abonnement.
Leases verlopen — standaard na 120 seconden, maximaal 600. De Python-bibliotheek vernieuwt de jouwe in een achtergrondthread en geeft hem vrij zodra het with-blok eindigt, zodat een gecrasht script zijn apparaat binnen seconden vrijgeeft in plaats van het vast te houden tot je de app herstart. Roep je de API rechtstreeks aan, dan moet je zelf hartslagen sturen.
Je ziet elke levende lease — en kunt er één geforceerd vrijgeven — onder Instellingen → Developer API → Actieve apparaatsessies.
Platformmodi
Een geregistreerd script verklaart waarop het mikt:
Generic — het apparaat wordt onaangeroerd overgedragen. Er wordt geen app gestart, geen account gewisseld, geen invoermethode gecontroleerd, en achteraf wordt niets afgesloten. Gebruik dit om alles te automatiseren wat geen TikTok of Instagram is.
TikTok / Instagram — de app wordt geopend en het account gewisseld voordat je programma start, en de app wordt gesloten wanneer het klaar is, precies zoals bij een ingebouwd script. TIKMATRIX_PACKAGE vertelt welk pakket is gekozen. Gebruik dit om een stap toe te voegen die de ingebouwde scripts niet dekken.
Omgevingsvariabelen
Een beheerd script ontvangt:
| Variabele | Betekenis |
|---|---|
TIKMATRIX_API_BASE | Server-URL, bv. http://127.0.0.1:50809 |
TIKMATRIX_SESSION_ID | De lease die al voor je wordt aangehouden |
TIKMATRIX_SERIAL | Het apparaat waarnaar deze taak is gestuurd |
TIKMATRIX_PACKAGE | Het gekozen app-pakket |
TIKMATRIX_PLATFORM | tiktok, instagram of generic |
TikMatrix.from_env() leest dit allemaal voor je uit.
Zelfstandige scripts krijgen hier niets van — lease dan expliciet een apparaat.
Alles wat je in Extra omgevingsvariabelen zet, wordt er bovenop samengevoegd; dat is de gebruikelijke manier om één geregistreerd script per run andere instellingen te geven zonder het bestand aan te passen.
Naslag voor de Python-bibliotheek
TikMatrix — de verbinding
| Aanroep | Wat het doet |
|---|---|
TikMatrix(base_url=None, timeout=30.0) | Verbindt. Valt terug op TIKMATRIX_API_BASE, daarna http://127.0.0.1:50809 |
client.devices() | Online apparaten, elk met serial, real_serial en busy |
client.sessions() | Alle levende leases, ook die van andere processen |
client.device(serial, label=..., ttl_secs=120) | Least een apparaat en geeft een Device terug |
TikMatrix.from_env() | Neemt het apparaat over waarmee een beheerd script is gestart |
Device — de telefoon
| Aanroep | Wat het doet |
|---|---|
d.info() | Apparaatgegevens van UIAutomator2 |
d.window_size() | (breedte, hoogte) |
d.screenshot(path=None) | PNG-bytes, optioneel weggeschreven naar path |
d.hierarchy() | De huidige UI-boom als XML |
d.find(text=, resource_id=, description=, class_name=) | Overeenkomende knopen, elk met bounds en center |
d.exists(**criteria) | Of er iets overeenkomt |
d.wait_for(timeout=10.0, interval=1.0, **criteria) | Wacht tot het verschijnt en geeft het terug |
d.click(timeout=10.0, **criteria) | Wacht op een element en tikt op het midden ervan |
d.click_xy(x, y) | Tikt op een coördinaat |
d.swipe(sx, sy, ex, ey, steps=20) | Veegt |
d.press(key) | back, home, recent, enter, … |
d.input_text(text) | Typt in het actieve veld via de meegeleverde snelle invoermethode |
d.jsonrpc(method, params=None, timeout=10) | Elke UIAutomator2-methode |
d.adb(*args, timeout_ms=None) | Voert een ADB-opdracht uit |
d.release() | Geeft de lease vrij. with doet dit voor je |
find zoekt in de uitgelezen UI-boom, dus als een selector mist kun je print(d.hierarchy()) doen en precies zien waarin is gezocht. De Element Inspector in de apparaatweergave toont dezelfde boom visueel, meestal de snelste manier om een resource-id te vinden.
input_text heeft ADB nodigHet stuurt een broadcast naar de meegeleverde invoermethode, en dat loopt via adb shell. Zet ADB-toegang aan voordat je het gebruikt, anders mislukt het met 403.
Fouten
De bibliotheek gooit twee excepties, beide subklassen van RuntimeError:
| Exceptie | Wanneer |
|---|---|
DeviceBusyError | HTTP 409 — het apparaat is al geleased, of je abonnement heeft geen vrije plek |
TikMatrixError | Al het andere: abonnement te laag, lease verlopen, ADB uit, selector die nooit trof |
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("die telefoon is bij iemand anders in gebruik — probeer een andere")
except TikMatrixError as exc:
print("mislukt:", exc)
In een beheerd script is de exceptie laten doorlopen meestal het juiste: de afsluitcode ongelijk aan nul markeert de taak als mislukt en de traceback belandt in het takenlogboek.
HTTP-endpoints
Apparaatbewerkingen hebben een x-session-id-header nodig die naar een levende lease verwijst. Er is geen API-sleutel: net als de rest van de lokale API zijn deze endpoints niet geauthenticeerd — de machine over het netwerk kunnen bereiken ís de toegangscontrole. Ze sturen geen CORS-headers, dus roep ze aan vanuit een programma (curl, Python, welke servercode dan ook) en niet vanuit een pagina in een browser.
| Methode | Pad | Doel |
|---|---|---|
GET | /api/v1/rpc/devices | Toont online apparaten en of ze bezet zijn |
POST | /api/v1/rpc/session | Least een apparaat → session_id |
POST | /api/v1/rpc/session/{id}/heartbeat | Verlengt de lease |
DELETE | /api/v1/rpc/session/{id} | Geeft de lease vrij |
GET | /api/v1/rpc/session | Toont levende leases |
POST | /api/v1/rpc/jsonrpc | Roept een UIAutomator2-methode aan |
POST | /api/v1/rpc/adb | Voert een ADB-opdracht uit |
GET | /api/v1/rpc/hierarchy?serial= | Huidige UI-boom als XML |
GET | /api/v1/rpc/screenshot?serial= | Huidig scherm als PNG |
JSON-antwoorden gebruiken dezelfde envelop als de rest van de lokale API — {"code": 0, "message": "success", "data": ...}, met een code ongelijk aan nul bij een fout. hierarchy en screenshot geven in plaats daarvan de ruwe body terug.
Voorbeeld
# Een apparaat 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", ...}}
# Aansturen
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":[]}'
# In leven houden tijdens het werk
curl -X POST http://127.0.0.1:50809/api/v1/rpc/session/ff3ae079-.../heartbeat \
-H "Content-Type: application/json" \
-d '{"ttl_secs":120}'
# Teruggeven
curl -X DELETE http://127.0.0.1:50809/api/v1/rpc/session/ff3ae079-...
Fouten
| Status | Betekenis |
|---|---|
| 403 | Abonnement lager dan Pro, geen lease, verlopen lease of ADB-toegang uitgeschakeld |
| 409 | Apparaat al geleased, of je abonnement heeft geen vrije plek |
In een andere taal schrijven
Niets hiervan is Python-specifiek. Elke runtime die een HTTP-verzoek kan doen werkt — het contract van de beheerde modus is alleen: "lees drie omgevingsvariabelen, sluit af met 0 bij succes".
// my_flow.js — registreer met: 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"));
Staat de interpreter niet in PATH, geef dan het volledige pad op bij Opdracht, bv. C:/Program Files/nodejs/node.exe C:/scripts/my_flow.js.
Een eigen script starten via de API
Geregistreerde scripts kunnen ook via de Takenbeheer-API worden gestart, zodat één script vervolgwerk in de wachtrij kan zetten:
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 is het id van het script dat je hebt geregistreerd.
ADB-toegang
/api/v1/rpc/adb geeft je scripts een shell op het apparaat — je hebt die nodig om media te pushen, APK's te installeren en systeeminstellingen te wijzigen. Omdat het een volwaardige shell is op een endpoint zonder API-sleutel, staat hij standaard uit. Zet hem aan onder Instellingen → Developer API → ADB-opdrachten toestaan zodra je een script hebt dat hem nodig heeft; UI-automatisering via /rpc/jsonrpc werkt ook zonder.
Zolang hij uit staat antwoordt /api/v1/rpc/adb met 403 en blijft de rest van de API gewoon werken. Elke ADB-opdracht die een script uitvoert wordt in je logbestand geschreven.
Scripts schrijven die blijven werken
- Wacht op het scherm, slaap er niet voor.
d.wait_for(...)keert terug zodra het element er is; een vaste sleep is óf trager dan nodig, óf te kort op een slechte dag. - Controleer voordat je tikt. Een
d.exists(...)op een toestemmingsvenster of een "niet nu"-melding kost één boomuitlezing en redt een run die anders in het luchtledige zou tikken. - Print wat je hebt gedaan. In de beheerde modus ís stdout het takenlogboek, en het is het enige spoor van een run waar niemand naar keek.
- Maak opnieuw draaien veilig. Een nieuwe poging draait het hele programma opnieuw, dus een script dat publiceert zou moeten controleren of het al gepubliceerd heeft in plaats van aan te nemen dat het bij nul begint.
- Eén script, één klus. Gelijktijdigheid geldt per apparaat, dus tien kleine taken op tien telefoons zijn veel eerder klaar dan één script dat in een lus tien telefoons afgaat.
Opmerkingen en grenzen
- De opdracht wordt rechtstreeks uitgevoerd, niet via een shell, dus
&&en|gelden als argumenten en niet als operatoren. Registreercmd /c "..."(Windows) ofsh -c "..."(macOS) als je shell-gedrag wilt. - Zet paden met spaties tussen aanhalingstekens:
"C:/Program Files/Python/python.exe" my_script.py. - Een script dat zijn time-out overschrijdt wordt afgebroken en de taak als mislukt gemarkeerd.
- Een afsluitcode ongelijk aan nul markeert de taak als mislukt; alles wat het script naar stdout en stderr schrijft belandt in het takenlogboek.
- Scripts draaien met dezelfde rechten als TikMatrix zelf. Registreer alleen programma's die je zelf schreef of vertrouwt.
Problemen oplossen
API access requires Pro or higher plan (403)
De licentie op deze machine is Starter of inactief. Controleer Instellingen → Licentie.
Verbinding geweigerd op 127.0.0.1:50809
TikMatrix draait niet, of draait als een andere gebruiker. De server bestaat alleen zolang de app open is.
409 bij elke leasepoging Óf de telefoon is echt bezet — kijk bij Instellingen → Developer API → Actieve apparaatsessies — óf alle apparaatplekken in je abonnement zijn al bezet door lopende taken.
De lease verloopt midden in een lange stap
De standaard-TTL is 120 s en de bibliotheek vernieuwt hem op de achtergrond, dus dit betekent meestal dat het script zijn hoofdthread langer blokkeerde dan de TTL. Verhoog ttl_secs (tot 600), of haal het langdurige werk uit die thread.
d.adb(...) mislukt met 403
ADB-toegang staat uit. Zet hem aan onder Instellingen → Developer API → ADB-opdrachten toestaan.
Een selector treft nooit iets
print(d.hierarchy()) toont precies de boom die find doorzocht. Tekst wordt exact vergeleken, dus een spatie te veel of een vertaald label is de gebruikelijke oorzaak; zoeken op resource_id is stabieler dan op text.
De taak is mislukt maar de telefoon ziet er goed uit Lees het takenlogboek. Een afsluitcode ongelijk aan nul — ook een niet-afgevangen exceptie aan het eind van een geslaagde run — laat de taak mislukken, zelfs als de automatisering zelf werkte.
Volgende stappen
- Overzicht lokale API — authenticatie en antwoordformaat
- Takenbeheer-API — taken aanmaken, opvragen, opnieuw proberen en stoppen
- AI-assistent — laat een model een script opstellen en registreren
- SDK en voorbeelden op GitHub