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
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ć
| Samodzielny | Zarządzany | |
|---|---|---|
| Kto uruchamia | Ty | Kolejka zadań TikMatrix |
| Dzierżawa urządzenia | Bierzesz ją sam | Jest już utrzymywana przy starcie |
| Ponowienia, harmonogram, dziennik | Budujesz sam | W komplecie |
| Praca na wielu urządzeniach | Sam piszesz pętlę | Jedno zadanie na urządzenie, równolegle |
| Najlepsze do | Eksploracji, crawlerów, zadań jednorazowych | Wszystkiego, 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:
| Pole | Znaczenie |
|---|---|
| Nazwa | Widoczna na liście skryptów i w dzienniku zadań |
| Polecenie | Wiersz uruchamiający program, np. python C:/scripts/my_flow.py |
| Katalog roboczy | Opcjonalny. Miejsce startu programu |
| Platforma | Zobacz tryby platformy niżej |
| Limit czasu | Po ilu sekundach skrypt zostaje zabity, a zadanie oznaczone jako nieudane. Domyślnie 1800 |
| Dodatkowe zmienne środowiskowe | Opcjonalny obiekt JSON scalany ze środowiskiem programu |
| Włączony | Wyłą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.
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:
| Zmienna | Znaczenie |
|---|---|
TIKMATRIX_API_BASE | URL serwera, np. http://127.0.0.1:50809 |
TIKMATRIX_SESSION_ID | Dzierżawa już utrzymywana w twoim imieniu |
TIKMATRIX_SERIAL | Urządzenie, na które trafiło to zadanie |
TIKMATRIX_PACKAGE | Ustalony pakiet aplikacji |
TIKMATRIX_PLATFORM | tiktok, 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łanie | Co 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łanie | Co 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 ADBWysył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ątek | Kiedy |
|---|---|
DeviceBusyError | HTTP 409 — urządzenie jest już wydzierżawione albo w planie nie ma wolnego miejsca |
TikMatrixError | Cał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żka | Cel |
|---|---|---|
GET | /api/v1/rpc/devices | Lista urządzeń online i informacja, czy są zajęte |
POST | /api/v1/rpc/session | Dzierżawi urządzenie → session_id |
POST | /api/v1/rpc/session/{id}/heartbeat | Przedłuża dzierżawę |
DELETE | /api/v1/rpc/session/{id} | Zwalnia dzierżawę |
GET | /api/v1/rpc/session | Lista żywych dzierżaw |
POST | /api/v1/rpc/jsonrpc | Wywołuje metodę UIAutomator2 |
POST | /api/v1/rpc/adb | Wykonuje 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
| Status | Znaczenie |
|---|---|
| 403 | Plan niższy niż Pro, brak dzierżawy, wygasła dzierżawa albo wyłączony dostęp ADB |
| 409 | Urzą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.