Hoppa till huvudinnehåll

Egna skript

De inbyggda skripten täcker de vanliga flödena. När du behöver något de inte erbjuder — ett steg i annan ordning, en skärm de aldrig rör, eller en app som varken är TikTok eller Instagram — kan du skriva det själv i valfritt språk och låta TikMatrix räcka dig telefonen.

Krav

Licenskrav

Egna skript kräver Pro-, Team- eller Business-plan. Starter-planen har ingen åtkomst.

Antalet enheter i din plan är också gränsen för samtidighet: en Pro-plan (20 enheter) kan köra 20 telefoner samtidigt, oavsett om det sker via inbyggda uppgifter, egna skript eller en blandning.

Två sätt att köra ett skript

Fristående

Du startar programmet själv. TikMatrix lånar bara ut enheter.

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())

Bra för engångsjobb, datainsamling och allt du vill starta från din egen schemaläggare.

Hanterat

Du registrerar programmet i TikMatrix och det blir en uppgift som alla andra. Det får uppgiftskön, samtidighet enligt planen, automatiska omförsök, uppgiftsloggen och schemamallar. TikMatrix hyr enheten innan ditt program startar och skickar hyres-id:t via miljövariabler.

from tikmatrix import TikMatrix

with TikMatrix.from_env() as d: # enheten är redan hyrd
d.click(text="Log in")
print("done") # den här raden hamnar i uppgiftsloggen

Bra för allt du vill köra upprepat, schemalagt eller på många enheter.

Vilket ska du välja

FriståendeHanterat
Vem startarDuTikMatrix uppgiftskö
EnhetshyraDu tar den självRedan i handen vid start
Omförsök, schema, loggBygger du självIngår
Körning på många enheterDu skriver loopenEn uppgift per enhet, parallellt
Bäst förUtforskning, crawlers, engångsjobbAllt du vill upprepa

Du kan börja fristående medan du får flödet att sitta, och sedan registrera samma fil som ett hanterat skript — den enda rad som ändras är TikMatrix.from_env().

Kom igång

1. Installera klientbiblioteket

pip install requests

Kopiera sedan tikmatrix.py från SDK-katalogen bredvid ditt skript. Biblioteket är en enda fil utan andra beroenden.

Du måste inte använda det — API:t är vanlig JSON över HTTP, och de råa slutpunkterna dokumenteras nedan.

2. Skriv ditt skript

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")

Kör det med TikMatrix öppet och telefonen ansluten. Skriver det ut en ordbok med enhetsinformation är allt rätt kopplat.

3. Registrera det (endast hanterat läge)

Gå till Enheter → Egna skript → Lägg till skript:

FältBetydelse
NamnVisas i skriptlistan och i uppgiftsloggen
KommandoProgramraden som ska köras, t.ex. python C:/scripts/my_flow.py
ArbetskatalogValfritt. Var programmet startar
PlattformSe plattformslägen nedan
TidsgränsSekunder innan skriptet avbryts och uppgiften markeras som misslyckad. Standard 1800
Extra miljövariablerValfritt JSON-objekt som vävs in i programmets miljö
AktiveratStäng av ett skript utan att radera det. Ett avstängt skript kan inte skickas ut

Tryck sedan på ▶ på skriptets rad och välj dina enheter, precis som för ett inbyggt skript.

Låt assistenten skriva det

AI-assistenten kan skriva ett eget skript utifrån en beskrivning på vanligt språk och registrera det i ett enda steg. Den visar hela filen innan något skrivs till disk.

Enhetshyror

En telefon kan bara styras av en sak i taget. Att hyra den talar om för TikMatrix att enheten är upptagen, så att:

  • uppgiftskön inte skickar en uppgift till samma skärm, och
  • dina JSON-RPC-anrop rapporterar agentens hälsa precis som ett inbyggt skript gör, så att vakthunden ser en upptagen agent i stället för en tyst.

En hyra tar också en enhetsplats ur din plan.

Hyror förfaller — 120 sekunder som standard, högst 600. Python-biblioteket förnyar din i en bakgrundstråd och släpper den när with-blocket tar slut, så ett skript som kraschar frigör sin enhet inom sekunder i stället för att hålla den tills du startar om appen. Anropar du API:t direkt måste du skicka hjärtslagen själv.

Du ser alla levande hyror — och kan tvinga fram en frisläppning — under Inställningar → Developer API → Aktiva enhetssessioner.

Plattformslägen

Ett registrerat skript deklarerar vad det siktar på:

Generic — enheten lämnas över orörd. Ingen app startas, inga konton växlas, ingen inmatningsmetod kontrolleras, och inget stängs efteråt. Använd detta för att automatisera allt som inte är TikTok eller Instagram.

TikTok / Instagram — appen öppnas och kontot växlas innan ditt program startar, och appen stängs när det är klart, precis som för ett inbyggt skript. TIKMATRIX_PACKAGE talar om vilket paket som valdes. Använd detta för att lägga till ett steg som de inbyggda skripten inte täcker.

Miljövariabler

Ett hanterat skript får:

VariabelBetydelse
TIKMATRIX_API_BASEServerns URL, t.ex. http://127.0.0.1:50809
TIKMATRIX_SESSION_IDHyran som redan hålls åt dig
TIKMATRIX_SERIALEnheten som uppgiften skickades till
TIKMATRIX_PACKAGEDet valda appaketet
TIKMATRIX_PLATFORMtiktok, instagram eller generic

TikMatrix.from_env() läser allt detta åt dig.

Fristående skript får inget av det — hyr en enhet uttryckligen i stället.

Allt du lägger i Extra miljövariabler vävs in ovanpå, vilket är det vanliga sättet att ge ett och samma registrerade skript inställningar per körning utan att redigera filen.

Referens för Python-biblioteket

TikMatrix — anslutningen

AnropVad det gör
TikMatrix(base_url=None, timeout=30.0)Ansluter. Faller tillbaka på TIKMATRIX_API_BASE, sedan http://127.0.0.1:50809
client.devices()Enheter online, var och en med serial, real_serial och busy
client.sessions()Alla levande hyror, även sådana den här processen inte äger
client.device(serial, label=..., ttl_secs=120)Hyr en enhet och returnerar en Device
TikMatrix.from_env()Tar över enheten som ett hanterat skript startades med

Device — telefonen

AnropVad det gör
d.info()Enhetsinformation från UIAutomator2
d.window_size()(bredd, höjd)
d.screenshot(path=None)PNG-byte, valfritt skrivna till path
d.hierarchy()Aktuellt gränssnittsträd som XML
d.find(text=, resource_id=, description=, class_name=)Matchande noder, var och en med bounds och center
d.exists(**criteria)Om något matchar
d.wait_for(timeout=10.0, interval=1.0, **criteria)Väntar tills det dyker upp och returnerar det
d.click(timeout=10.0, **criteria)Väntar på ett element och trycker på dess mitt
d.click_xy(x, y)Trycker på en koordinat
d.swipe(sx, sy, ex, ey, steps=20)Sveper
d.press(key)back, home, recent, enter, …
d.input_text(text)Skriver i det fokuserade fältet via den medföljande snabbinmatningen
d.jsonrpc(method, params=None, timeout=10)Vilken UIAutomator2-metod som helst
d.adb(*args, timeout_ms=None)Kör ett ADB-kommando
d.release()Släpper hyran. with gör det åt dig

find matchar mot det uttagna gränssnittsträdet, så när en väljare missar kan du köra print(d.hierarchy()) och se exakt vad den sökte i. Elementinspektören i enhetsvyn visar samma träd visuellt, vilket oftast är snabbaste vägen till ett resource-id.

input_text kräver ADB

Den skickar en broadcast till den medföljande inmatningsmetoden, vilket går via adb shell. Slå på ADB-åtkomst innan du använder den, annars misslyckas den med 403.

Fel

Biblioteket kastar två undantag, båda underklasser till RuntimeError:

UndantagNär
DeviceBusyErrorHTTP 409 — enheten är redan hyrd, eller planen har ingen ledig enhetsplats
TikMatrixErrorAllt annat: för låg plan, förfallen hyra, avstängd ADB, väljare som aldrig träffade
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("den telefonen används av något annat — prova en annan")
except TikMatrixError as exc:
print("misslyckades:", exc)

I ett hanterat skript är det oftast rätt att låta undantaget slippa ut: utgångskoden skild från noll markerar uppgiften som misslyckad och stackspårningen hamnar i uppgiftsloggen.

HTTP-slutpunkter

Enhetsoperationer kräver ett x-session-id-huvud som pekar ut en levande hyra. Det finns ingen API-nyckel: liksom resten av det lokala API:t är dessa slutpunkter oautentiserade — att kunna nå maskinen på nätverket är åtkomstkontrollen. De skickar inga CORS-huvuden, så anropa dem från ett program (curl, Python, valfri serverkod) och inte från en sida i en webbläsare.

MetodSökvägSyfte
GET/api/v1/rpc/devicesListar enheter online och om de är upptagna
POST/api/v1/rpc/sessionHyr en enhet → session_id
POST/api/v1/rpc/session/{id}/heartbeatFörlänger hyran
DELETE/api/v1/rpc/session/{id}Släpper hyran
GET/api/v1/rpc/sessionListar levande hyror
POST/api/v1/rpc/jsonrpcAnropar en UIAutomator2-metod
POST/api/v1/rpc/adbKör ett ADB-kommando
GET/api/v1/rpc/hierarchy?serial=Aktuellt gränssnittsträd som XML
GET/api/v1/rpc/screenshot?serial=Aktuell skärm som PNG

JSON-svar använder samma hölje som resten av det lokala API:t{"code": 0, "message": "success", "data": ...}, med code skild från noll vid fel. hierarchy och screenshot returnerar i stället den råa kroppen.

Exempel

# Hyr en enhet
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", ...}}

# Styr den
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":[]}'

# Håll hyran vid liv under arbetet
curl -X POST http://127.0.0.1:50809/api/v1/rpc/session/ff3ae079-.../heartbeat \
-H "Content-Type: application/json" \
-d '{"ttl_secs":120}'

# Lämna tillbaka den
curl -X DELETE http://127.0.0.1:50809/api/v1/rpc/session/ff3ae079-...

Fel

StatusBetydelse
403Plan under Pro, ingen hyra, förfallen hyra eller avstängd ADB-åtkomst
409Enheten är redan hyrd, eller planen har ingen ledig enhetsplats

Skriva i ett annat språk

Inget här är Python-specifikt. Vilken körmiljö som helst som kan göra en HTTP-förfrågan fungerar — kontraktet för hanterat läge är bara "läs tre miljövariabler, avsluta med 0 vid framgång".

// my_flow.js — registrera med: 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"));

Om tolken inte ligger i PATH, ange hela sökvägen i Kommando, t.ex. C:/Program Files/nodejs/node.exe C:/scripts/my_flow.js.

Starta ett eget skript från API:t

Registrerade skript kan också startas via uppgifts-API:t, så att ett skript kan köa efterföljande arbete:

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 är id:t för skriptet du registrerade.

ADB-åtkomst

/api/v1/rpc/adb ger dina skript ett skal på enheten — du behöver det för att skicka mediefiler, installera APK:er och ändra systeminställningar. Eftersom det är ett fullständigt skal på en slutpunkt utan API-nyckel levereras det avstängt. Slå på det under Inställningar → Developer API → Tillåt ADB-kommandon när du har ett skript som behöver det; gränssnittsautomatisering via /rpc/jsonrpc fungerar ändå.

Medan det är avstängt svarar /api/v1/rpc/adb med 403 och resten av API:t fortsätter fungera. Varje ADB-kommando ett skript kör skrivs till din loggfil.

Skriva skript som fortsätter fungera

  • Vänta på skärmen, sov inte i stället. d.wait_for(...) återvänder så snart elementet finns där; en fast sleep är antingen långsammare än nödvändigt eller för kort en dålig dag.
  • Kontrollera innan du trycker. Ett d.exists(...) på en samtyckesruta eller ett "inte nu" kostar en trädutläsning och räddar en körning som annars hade tryckt i tomma luften.
  • Skriv ut vad du gjorde. I hanterat läge är stdout uppgiftsloggen, och det är enda spåret av en körning ingen tittade på.
  • Gör en omkörning ofarlig. Ett omförsök kör hela programmet igen, så ett skript som publicerar bör kontrollera om det redan publicerat i stället för att anta att det börjar om från noll.
  • Ett skript, ett jobb. Samtidighet räknas per enhet, så tio små uppgifter på tio telefoner blir klara långt före ett skript som loopar över tio telefoner.

Noteringar och gränser

  • Kommandot körs direkt, inte genom ett skal, så && och | behandlas som argument och inte som operatorer. Registrera cmd /c "..." (Windows) eller sh -c "..." (macOS) om du vill ha skalbeteende.
  • Sätt citattecken runt sökvägar med mellanslag: "C:/Program Files/Python/python.exe" my_script.py.
  • Ett skript som överskrider sin tidsgräns avslutas och uppgiften markeras som misslyckad.
  • En utgångskod skild från noll markerar uppgiften som misslyckad; allt skriptet skriver till stdout och stderr hamnar i uppgiftsloggen.
  • Skript körs med samma behörigheter som TikMatrix självt. Registrera bara program du skrivit själv eller litar på.

Felsökning

API access requires Pro or higher plan (403) Licensen på den här maskinen är Starter eller inaktiv. Kontrollera Inställningar → Licens.

Anslutning nekad på 127.0.0.1:50809 TikMatrix körs inte, eller körs som en annan användare. Servern finns bara så länge appen är öppen.

409 vid varje hyresförsök Antingen är telefonen verkligen upptagen — titta under Inställningar → Developer API → Aktiva enhetssessioner — eller så är alla enhetsplatser i planen redan tagna av pågående uppgifter.

Hyran förfaller mitt i ett långt steg Standard-TTL är 120 s och biblioteket förnyar den i bakgrunden, så detta betyder oftast att skriptet blockerade sin huvudtråd längre än TTL:en. Höj ttl_secs (upp till 600), eller flytta det långa arbetet ur den tråden.

d.adb(...) misslyckas med 403 ADB-åtkomsten är avstängd. Slå på den under Inställningar → Developer API → Tillåt ADB-kommandon.

En väljare matchar aldrig print(d.hierarchy()) visar exakt det träd find sökte i. Text jämförs exakt, så ett extra blanksteg eller en översatt etikett är den vanliga orsaken; att matcha på resource_id är stabilare än på text.

Uppgiften är markerad som misslyckad men telefonen ser bra ut Läs uppgiftsloggen. En utgångskod skild från noll — även ett ofångat undantag i slutet av en lyckad körning — får uppgiften att misslyckas trots att automatiseringen fungerade.

Nästa steg