Przejdź do głównej zawartości

Własne skrypty

Wbudowane skrypty obejmują typowe przepływy. Gdy potrzebujesz czegoś, czego nie oferują — kroku w innej kolejności, ekranu, którego nigdy nie dotykają, albo aplikacji innej niż TikTok czy Instagram — możesz napisać to sam w dowolnym języku, a TikMatrix odda ci telefon.

Wymagania

Wymagania licencyjne

Własne skrypty wymagają planu Pro, Team lub Business. Plan Starter nie ma dostępu.

Liczba urządzeń w twoim planie jest zarazem limitem równoległości: plan Pro (20 urządzeń) może sterować 20 telefonami naraz — przez zadania wbudowane, własne skrypty albo jedno i drugie.

Dwa sposoby uruchamiania skryptu

Samodzielny

Program uruchamiasz sam. TikMatrix tylko wypożycza ci urządzenia.

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

Dobre do zadań jednorazowych, zbierania danych i wszystkiego, co chcesz odpalać z własnego harmonogramu.

Zarządzany

Rejestrujesz program w TikMatrix i staje się on zadaniem jak każde inne. Dostaje kolejkę zadań, równoległość zgodną z planem, automatyczne ponowienia, dziennik zadań i szablony harmonogramów. TikMatrix dzierżawi urządzenie przed uruchomieniem twojego programu i przekazuje identyfikator dzierżawy w środowisku.

from tikmatrix import TikMatrix

with TikMatrix.from_env() as d: # urządzenie jest już wydzierżawione
d.click(text="Log in")
print("done") # ta linia trafi do dziennika zadania

Dobre do wszystkiego, co chcesz uruchamiać wielokrotnie, o wyznaczonej porze albo na wielu urządzeniach.

Co wybrać

SamodzielnyZarządzany
Kto uruchamiaTyKolejka zadań TikMatrix
Dzierżawa urządzeniaBierzesz ją samJest już utrzymywana przy starcie
Ponowienia, harmonogram, dziennikBudujesz samW komplecie
Praca na wielu urządzeniachSam piszesz pętlęJedno zadanie na urządzenie, równolegle
Najlepsze doEksploracji, crawlerów, zadań jednorazowychWszystkiego, co chcesz powtarzać

Możesz zacząć od trybu samodzielnego, dopracować przepływ, a potem zarejestrować ten sam plik jako skrypt zarządzany — zmienia się tylko linia TikMatrix.from_env().

Pierwsze kroki

1. Zainstaluj bibliotekę kliencką

pip install requests

Następnie skopiuj tikmatrix.py z katalogu SDK obok swojego skryptu. Biblioteka to jeden plik bez innych zależności.

Nie musisz jej używać — API to zwykły JSON po HTTP, a surowe endpointy opisano niżej.

2. Napisz skrypt

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

Uruchom go przy otwartym TikMatrix i podłączonym telefonie. Jeśli wypisze słownik z informacjami o urządzeniu, wszystko jest połączone poprawnie.

3. Zarejestruj go (tylko tryb zarządzany)

Przejdź do Urządzenia → Własne skrypty → Dodaj skrypt:

PoleZnaczenie
NazwaWidoczna na liście skryptów i w dzienniku zadań
PolecenieWiersz uruchamiający program, np. python C:/scripts/my_flow.py
Katalog roboczyOpcjonalny. Miejsce startu programu
PlatformaZobacz tryby platformy niżej
Limit czasuPo ilu sekundach skrypt zostaje zabity, a zadanie oznaczone jako nieudane. Domyślnie 1800
Dodatkowe zmienne środowiskoweOpcjonalny obiekt JSON scalany ze środowiskiem programu
WłączonyWyłącz skrypt bez usuwania. Wyłączony skrypt nie może zostać rozdysponowany

Potem naciśnij ▶ w wierszu skryptu i wybierz urządzenia — dokładnie jak przy skrypcie wbudowanym.

Niech napisze go asystent

Asystent AI potrafi napisać własny skrypt na podstawie opisu zwykłym językiem i zarejestrować go w jednym kroku. Pokazuje cały plik, zanim cokolwiek zostanie zapisane na dysku.

Dzierżawy urządzeń

Telefonem może w danej chwili sterować tylko jedna rzecz. Wydzierżawienie go mówi TikMatrixowi, że urządzenie jest zajęte, więc:

  • kolejka zadań nie wyśle zadania na ten sam ekran, a
  • twoje wywołania JSON-RPC raportują kondycję agenta dokładnie tak, jak robi to skrypt wbudowany, więc watchdog widzi agenta zajętego, a nie milczącego.

Dzierżawa zajmuje też jedno miejsce urządzenia w twoim planie.

Dzierżawy wygasają — domyślnie po 120 sekundach, maksymalnie po 600. Biblioteka Pythona odnawia twoją w wątku w tle i zwalnia ją po wyjściu z bloku with, więc skrypt, który padnie, oddaje urządzenie w kilka sekund zamiast trzymać je do restartu aplikacji. Jeśli wołasz API bezpośrednio, musisz sam wysyłać sygnały życia.

Wszystkie żywe dzierżawy zobaczysz — i wymusisz ich zwolnienie — w Ustawienia → Developer API → Aktywne sesje urządzeń.

Tryby platformy

Zarejestrowany skrypt deklaruje swój cel:

Generic — urządzenie zostaje przekazane nietknięte. Żadna aplikacja nie jest uruchamiana, konta nie są przełączane, metoda wprowadzania nie jest sprawdzana, a po zakończeniu nic nie jest zamykane. Użyj tego do automatyzacji wszystkiego, co nie jest TikTokiem ani Instagramem.

TikTok / Instagram — aplikacja zostaje otwarta, a konto przełączone przed startem twojego programu; po zakończeniu aplikacja jest zamykana, dokładnie jak przy skrypcie wbudowanym. TIKMATRIX_PACKAGE mówi, który pakiet został ustalony. Użyj tego, by dodać krok, którego nie obejmują skrypty wbudowane.

Zmienne środowiskowe

Zarządzany skrypt otrzymuje:

ZmiennaZnaczenie
TIKMATRIX_API_BASEURL serwera, np. http://127.0.0.1:50809
TIKMATRIX_SESSION_IDDzierżawa już utrzymywana w twoim imieniu
TIKMATRIX_SERIALUrządzenie, na które trafiło to zadanie
TIKMATRIX_PACKAGEUstalony pakiet aplikacji
TIKMATRIX_PLATFORMtiktok, instagram lub generic

TikMatrix.from_env() odczytuje to wszystko za ciebie.

Skrypty samodzielne nie dostają żadnej z nich — wydzierżaw urządzenie jawnie.

Wszystko, co wpiszesz w Dodatkowe zmienne środowiskowe, jest scalane na wierzchu. To zwyczajowy sposób, by przekazać jednemu zarejestrowanemu skryptowi ustawienia dla konkretnego uruchomienia bez edytowania pliku.

Dokumentacja biblioteki Pythona

TikMatrix — połączenie

WywołanieCo robi
TikMatrix(base_url=None, timeout=30.0)Łączy się. Sięga po TIKMATRIX_API_BASE, potem http://127.0.0.1:50809
client.devices()Urządzenia online, każde z serial, real_serial i busy
client.sessions()Wszystkie żywe dzierżawy, także cudze
client.device(serial, label=..., ttl_secs=120)Dzierżawi urządzenie i zwraca Device
TikMatrix.from_env()Przejmuje urządzenie, z którym wystartował zarządzany skrypt

Device — telefon

WywołanieCo robi
d.info()Informacje o urządzeniu z UIAutomator2
d.window_size()(szerokość, wysokość)
d.screenshot(path=None)Bajty PNG, opcjonalnie zapisane do path
d.hierarchy()Bieżące drzewo interfejsu jako XML
d.find(text=, resource_id=, description=, class_name=)Pasujące węzły, każdy z bounds i center
d.exists(**criteria)Czy cokolwiek pasuje
d.wait_for(timeout=10.0, interval=1.0, **criteria)Czeka, aż się pojawi, i zwraca element
d.click(timeout=10.0, **criteria)Czeka na element i stuka w jego środek
d.click_xy(x, y)Stuka we współrzędne
d.swipe(sx, sy, ex, ey, steps=20)Przesuwa palcem
d.press(key)back, home, recent, enter, …
d.input_text(text)Pisze w aktywnym polu przez dołączoną szybką metodę wprowadzania
d.jsonrpc(method, params=None, timeout=10)Dowolna metoda UIAutomator2
d.adb(*args, timeout_ms=None)Wykonuje polecenie ADB
d.release()Zwalnia dzierżawę. with robi to za ciebie

find dopasowuje na zrzuconym drzewie interfejsu, więc gdy selektor spudłuje, możesz wywołać print(d.hierarchy()) i zobaczyć dokładnie, w czym szukał. Inspektor elementów w widoku urządzenia pokazuje to samo drzewo wizualnie — zwykle to najszybszy sposób na znalezienie resource-id.

input_text wymaga ADB

Wysyła broadcast do dołączonej metody wprowadzania, co idzie przez adb shell. Włącz dostęp ADB przed użyciem, inaczej dostaniesz 403.

Błędy

Biblioteka zgłasza dwa wyjątki, oba dziedziczące po RuntimeError:

WyjątekKiedy
DeviceBusyErrorHTTP 409 — urządzenie jest już wydzierżawione albo w planie nie ma wolnego miejsca
TikMatrixErrorCała reszta: za niski plan, wygasła dzierżawa, wyłączony ADB, selektor, który nigdy nie trafił
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("ten telefon ma ktoś inny — spróbuj innego")
except TikMatrixError as exc:
print("niepowodzenie:", exc)

W zarządzanym skrypcie zwykle właściwe jest pozwolić wyjątkowi wylecieć: niezerowy kod wyjścia oznacza zadanie jako nieudane, a ślad stosu trafia do dziennika zadania.

Endpointy HTTP

Operacje na urządzeniu wymagają nagłówka x-session-id wskazującego żywą dzierżawę. Nie ma klucza API: tak jak reszta lokalnego API, te endpointy nie są uwierzytelniane — kontrolą dostępu jest sama możliwość dotarcia do maszyny w sieci. Nie wysyłają nagłówków CORS, więc wołaj je z programu (curl, Python, dowolny kod serwerowy), a nie ze strony w przeglądarce.

MetodaŚcieżkaCel
GET/api/v1/rpc/devicesLista urządzeń online i informacja, czy są zajęte
POST/api/v1/rpc/sessionDzierżawi urządzenie → session_id
POST/api/v1/rpc/session/{id}/heartbeatPrzedłuża dzierżawę
DELETE/api/v1/rpc/session/{id}Zwalnia dzierżawę
GET/api/v1/rpc/sessionLista żywych dzierżaw
POST/api/v1/rpc/jsonrpcWywołuje metodę UIAutomator2
POST/api/v1/rpc/adbWykonuje polecenie ADB
GET/api/v1/rpc/hierarchy?serial=Bieżące drzewo interfejsu jako XML
GET/api/v1/rpc/screenshot?serial=Bieżący ekran jako PNG

Odpowiedzi JSON używają tej samej koperty co reszta lokalnego API — {"code": 0, "message": "success", "data": ...}, z niezerowym code przy niepowodzeniu. hierarchy i screenshot zwracają surową treść.

Przykład

# Wydzierżaw urządzenie
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", ...}}

# Steruj nim
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":[]}'

# Utrzymuj dzierżawę przy życiu w trakcie pracy
curl -X POST http://127.0.0.1:50809/api/v1/rpc/session/ff3ae079-.../heartbeat \
-H "Content-Type: application/json" \
-d '{"ttl_secs":120}'

# Oddaj urządzenie
curl -X DELETE http://127.0.0.1:50809/api/v1/rpc/session/ff3ae079-...

Błędy

StatusZnaczenie
403Plan niższy niż Pro, brak dzierżawy, wygasła dzierżawa albo wyłączony dostęp ADB
409Urządzenie już wydzierżawione albo w planie nie ma wolnego miejsca

Pisanie w innym języku

Nic tutaj nie jest związane z Pythonem. Wystarczy dowolne środowisko potrafiące wysłać żądanie HTTP — kontrakt trybu zarządzanego brzmi tylko: „odczytaj trzy zmienne środowiskowe, zakończ z kodem 0 przy powodzeniu".

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

Jeśli interpretera nie ma w PATH, podaj pełną ścieżkę w polu Polecenie, np. C:/Program Files/nodejs/node.exe C:/scripts/my_flow.js.

Uruchamianie własnego skryptu przez API

Zarejestrowane skrypty można też uruchamiać przez API zarządzania zadaniami, dzięki czemu jeden skrypt może kolejkować dalszą pracę:

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 to identyfikator zarejestrowanego przez ciebie skryptu.

Dostęp ADB

/api/v1/rpc/adb daje twoim skryptom powłokę na urządzeniu — potrzebujesz jej do wgrywania mediów, instalowania APK i zmiany ustawień systemowych. Ponieważ to pełna powłoka na endpointcie bez klucza API, jest domyślnie wyłączona. Włącz ją w Ustawienia → Developer API → Zezwól na polecenia ADB, gdy masz skrypt, który jej potrzebuje; automatyzacja interfejsu przez /rpc/jsonrpc działa i bez niej.

Kiedy jest wyłączona, /api/v1/rpc/adb odpowiada 403, a reszta API działa normalnie. Każde polecenie ADB uruchomione przez skrypt trafia do twojego pliku dziennika.

Jak pisać skrypty, które nadal działają

  • Czekaj na ekran, nie usypiaj za niego. d.wait_for(...) wraca, gdy tylko element się pojawi; stały sleep jest albo wolniejszy niż trzeba, albo za krótki w gorszy dzień.
  • Sprawdź, zanim stukniesz. d.exists(...) na oknie zgody albo komunikacie „nie teraz" kosztuje jeden zrzut drzewa i ratuje przebieg, który inaczej stuknąłby w pustkę.
  • Wypisuj, co zrobiłeś. W trybie zarządzanym stdout jest dziennikiem zadania i jedynym śladem przebiegu, którego nikt nie oglądał.
  • Zadbaj o bezpieczne powtórzenie. Ponowienie uruchamia cały program od nowa, więc skrypt publikujący powinien sprawdzić, czy już opublikował, zamiast zakładać, że startuje od zera.
  • Jeden skrypt, jedno zadanie. Równoległość liczy się na urządzenie, więc dziesięć małych zadań na dziesięciu telefonach kończy się znacznie szybciej niż jeden skrypt przechodzący pętlą po dziesięciu telefonach.

Uwagi i ograniczenia

  • Polecenie jest wykonywane bezpośrednio, nie przez powłokę, więc && i | są traktowane jako argumenty, a nie operatory. Zarejestruj cmd /c "..." (Windows) lub sh -c "..." (macOS), jeśli chcesz zachowania powłoki.
  • Ścieżki ze spacjami ujmuj w cudzysłowy: "C:/Program Files/Python/python.exe" my_script.py.
  • Skrypt przekraczający swój limit czasu zostaje zakończony, a zadanie oznaczone jako nieudane.
  • Niezerowy kod wyjścia oznacza zadanie jako nieudane; wszystko, co skrypt wypisze na stdout i stderr, trafia do dziennika zadania.
  • Skrypty działają z tymi samymi uprawnieniami co sam TikMatrix. Rejestruj tylko programy, które sam napisałeś albo którym ufasz.

Rozwiązywanie problemów

API access requires Pro or higher plan (403) Licencja na tej maszynie to Starter albo jest nieaktywna. Sprawdź Ustawienia → Licencja.

Odmowa połączenia na 127.0.0.1:50809 TikMatrix nie działa albo działa jako inny użytkownik. Serwer istnieje tylko wtedy, gdy aplikacja jest otwarta.

409 przy każdej próbie dzierżawy Albo telefon faktycznie jest zajęty — sprawdź Ustawienia → Developer API → Aktywne sesje urządzeń — albo wszystkie miejsca urządzeń w planie zajmują już działające zadania.

Dzierżawa wygasa w środku długiego kroku Domyślny TTL to 120 s, a biblioteka odnawia go w tle, więc zwykle oznacza to, że skrypt zablokował swój główny wątek na dłużej niż TTL. Podnieś ttl_secs (do 600) albo przenieś długą pracę poza ten wątek.

d.adb(...) kończy się błędem 403 Dostęp ADB jest wyłączony. Włącz go w Ustawienia → Developer API → Zezwól na polecenia ADB.

Selektor nigdy nie pasuje print(d.hierarchy()) pokazuje dokładnie to drzewo, które przeszukał find. Tekst porównywany jest dosłownie, więc dodatkowa spacja albo przetłumaczona etykieta to typowa przyczyna; dopasowanie po resource_id jest stabilniejsze niż po text.

Zadanie oznaczone jako nieudane, a telefon wygląda dobrze Przeczytaj dziennik zadania. Niezerowe wyjście — w tym nieprzechwycony wyjątek na końcu udanego przebiegu — oznacza zadanie jako nieudane, nawet jeśli sama automatyzacja zadziałała.

Dalsze kroki