Script personalizzati
Gli script integrati coprono i flussi più comuni. Quando ti serve qualcosa che non offrono — un passaggio in un ordine diverso, una schermata che non toccano mai o un'app che non è TikTok né Instagram — puoi scriverlo tu in qualsiasi linguaggio e lasciare che TikMatrix ti consegni il telefono.
Requisiti
Gli script personalizzati richiedono un piano Pro, Team o Business. Il piano Starter non ha accesso.
Il numero di dispositivi del tuo piano è anche il limite di concorrenza: un piano Pro (20 dispositivi) può pilotare 20 telefoni contemporaneamente, tramite attività integrate, script personalizzati o un misto dei due.
Due modi di eseguire uno script
Autonomo
Il programma lo avvii tu. TikMatrix si limita a prestarti i dispositivi.
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())
Adatto a lavori una tantum, raccolta dati e tutto ciò che vuoi lanciare dal tuo scheduler.
Gestito
Registri il programma in TikMatrix e diventa un'attività come le altre. Ottiene la coda delle attività, la concorrenza in base al piano, i tentativi automatici, il registro delle attività e i modelli di pianificazione. TikMatrix prende in leasing il dispositivo prima di avviare il tuo programma e passa l'id del leasing nell'ambiente.
from tikmatrix import TikMatrix
with TikMatrix.from_env() as d: # dispositivo già in leasing
d.click(text="Log in")
print("done") # questa riga finisce nel registro dell'attività
Adatto a tutto ciò che vuoi eseguire ripetutamente, a orario o su molti dispositivi.
Quale scegliere
| Autonomo | Gestito | |
|---|---|---|
| Chi lo avvia | Tu | La coda attività di TikMatrix |
| Leasing del dispositivo | Lo acquisisci tu | Già in mano all'avvio |
| Tentativi, pianificazione, registro | Li costruisci tu | Inclusi |
| Esecuzione su molti dispositivi | Scrivi tu il ciclo | Un'attività per dispositivo, in parallelo |
| Ideale per | Esplorazione, crawler, lavori una tantum | Tutto ciò che vuoi ripetere |
Puoi iniziare in modalità autonoma mentre metti a punto il flusso e poi registrare lo stesso file come script gestito: l'unica riga che cambia è TikMatrix.from_env().
Per iniziare
1. Installa la libreria client
pip install requests
Poi copia tikmatrix.py dalla directory dell'SDK accanto al tuo script. La libreria è un unico file senza altre dipendenze.
Non sei obbligato a usarla: l'API è semplice JSON su HTTP, e gli endpoint grezzi sono documentati più sotto.
2. Scrivi lo 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")
Eseguilo con TikMatrix aperto e il telefono collegato. Se stampa un dizionario con le informazioni del dispositivo, tutto è collegato.
3. Registralo (solo modalità gestita)
Vai su Dispositivi → Script personalizzati → Aggiungi script:
| Campo | Significato |
|---|---|
| Nome | Compare nell'elenco degli script e nel registro delle attività |
| Comando | La riga di programma da eseguire, es. python C:/scripts/my_flow.py |
| Directory di lavoro | Facoltativa. Dove parte il programma |
| Piattaforma | Vedi modalità piattaforma più sotto |
| Timeout | Secondi prima che lo script venga terminato e l'attività segnata come fallita. Predefinito 1800 |
| Variabili d'ambiente aggiuntive | Oggetto JSON facoltativo unito all'ambiente del programma |
| Abilitato | Disattiva uno script senza eliminarlo. Uno script disabilitato non può essere distribuito |
Poi premi ▶ sulla riga dello script e scegli i dispositivi, esattamente come per uno script integrato.
L'assistente IA può redigere uno script personalizzato partendo da una descrizione in linguaggio comune e registrarlo in un solo passaggio. Ti mostra l'intero file prima che qualcosa venga scritto su disco.
Leasing dei dispositivi
Un telefono può essere pilotato da una cosa sola per volta. Prenderlo in leasing dice a TikMatrix che il dispositivo è occupato, così:
- la coda delle attività non invierà un'attività sullo stesso schermo, e
- le tue chiamate JSON-RPC riportano lo stato dell'agente esattamente come farebbe uno script integrato, quindi il watchdog vede un agente occupato invece di uno muto.
Un leasing consuma anche uno slot dispositivo del tuo piano.
I leasing scadono: 120 secondi di default, 600 al massimo. La libreria Python rinnova il tuo in un thread di sfondo e lo rilascia all'uscita dal blocco with, così uno script che va in crash libera il dispositivo in pochi secondi invece di tenerlo fino al riavvio dell'app. Se chiami l'API direttamente, devi inviare tu gli heartbeat.
Puoi vedere tutti i leasing attivi — e rilasciarne uno a forza — in Impostazioni → Developer API → Sessioni dispositivo attive.
Modalità piattaforma
Uno script registrato dichiara il proprio bersaglio:
Generic — il dispositivo viene consegnato intatto. Nessuna app viene avviata, nessun cambio account, nessun controllo del metodo di input, e alla fine non viene chiuso nulla. Usala per automatizzare qualunque cosa non sia TikTok o Instagram.
TikTok / Instagram — l'app viene aperta e l'account cambiato prima che il tuo programma parta, e l'app viene chiusa al termine, esattamente come per uno script integrato. TIKMATRIX_PACKAGE indica quale pacchetto è stato risolto. Usala per aggiungere un passaggio che gli script integrati non coprono.
Variabili d'ambiente
Uno script gestito riceve:
| Variabile | Significato |
|---|---|
TIKMATRIX_API_BASE | URL del server, es. http://127.0.0.1:50809 |
TIKMATRIX_SESSION_ID | Il leasing già detenuto per tuo conto |
TIKMATRIX_SERIAL | Il dispositivo a cui è stata assegnata questa attività |
TIKMATRIX_PACKAGE | Pacchetto app risolto |
TIKMATRIX_PLATFORM | tiktok, instagram o generic |
TikMatrix.from_env() legge tutto questo per te.
Gli script autonomi non ricevono nulla di tutto ciò: prendi un dispositivo in leasing esplicitamente.
Tutto ciò che metti in Variabili d'ambiente aggiuntive viene unito sopra: è il modo usuale di dare a uno stesso script registrato impostazioni per singola esecuzione senza modificare il file.
Riferimento della libreria Python
TikMatrix — la connessione
| Chiamata | Cosa fa |
|---|---|
TikMatrix(base_url=None, timeout=30.0) | Si connette. Ripiega su TIKMATRIX_API_BASE, poi http://127.0.0.1:50809 |
client.devices() | Dispositivi online, ciascuno con serial, real_serial e busy |
client.sessions() | Tutti i leasing attivi, compresi quelli di altri processi |
client.device(serial, label=..., ttl_secs=120) | Prende un dispositivo in leasing e restituisce un Device |
TikMatrix.from_env() | Adotta il dispositivo con cui è stato avviato uno script gestito |
Device — il telefono
| Chiamata | Cosa fa |
|---|---|
d.info() | Informazioni dispositivo da UIAutomator2 |
d.window_size() | (larghezza, altezza) |
d.screenshot(path=None) | Byte PNG, opzionalmente scritti in path |
d.hierarchy() | L'albero UI corrente in XML |
d.find(text=, resource_id=, description=, class_name=) | Nodi corrispondenti, ciascuno con bounds e center |
d.exists(**criteria) | Se c'è qualche corrispondenza |
d.wait_for(timeout=10.0, interval=1.0, **criteria) | Attende che compaia e lo restituisce |
d.click(timeout=10.0, **criteria) | Attende un elemento e tocca il suo centro |
d.click_xy(x, y) | Tocca una coordinata |
d.swipe(sx, sy, ex, ey, steps=20) | Scorre |
d.press(key) | back, home, recent, enter, … |
d.input_text(text) | Scrive nel campo attivo tramite l'IME rapido incluso |
d.jsonrpc(method, params=None, timeout=10) | Qualsiasi metodo UIAutomator2 |
d.adb(*args, timeout_ms=None) | Esegue un comando ADB |
d.release() | Rilascia il leasing. with lo fa per te |
find cerca sull'albero UI estratto, quindi quando un selettore fallisce puoi fare print(d.hierarchy()) e vedere esattamente cosa è stato cercato. L'Ispettore elementi nella vista dispositivo mostra lo stesso albero in forma visiva, ed è di solito il modo più rapido per trovare un resource-id.
input_text richiede ADBInvia un broadcast al metodo di input incluso, cosa che passa da adb shell. Abilita l'accesso ADB prima di usarlo, altrimenti fallisce con 403.
Errori
La libreria solleva due eccezioni, entrambe sottoclassi di RuntimeError:
| Eccezione | Quando |
|---|---|
DeviceBusyError | HTTP 409 — il dispositivo è già in leasing, o il piano non ha slot liberi |
TikMatrixError | Tutto il resto: piano insufficiente, leasing scaduto, ADB disabilitato, selettore mai trovato |
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("quel telefono lo sta usando qualcun altro — provane un altro")
except TikMatrixError as exc:
print("fallito:", exc)
In uno script gestito, lasciar propagare l'eccezione è di solito la cosa giusta: l'uscita diversa da zero segna l'attività come fallita e il traceback finisce nel registro dell'attività.
Endpoint HTTP
Le operazioni sul dispositivo richiedono un header x-session-id che indichi un leasing attivo. Non c'è chiave API: come il resto dell'API locale, questi endpoint non sono autenticati — riuscire a raggiungere la macchina in rete è il controllo d'accesso. Non inviano header CORS, quindi chiamali da un programma (curl, Python, qualsiasi codice lato server) e non da una pagina nel browser.
| Metodo | Percorso | Scopo |
|---|---|---|
GET | /api/v1/rpc/devices | Elenca i dispositivi online e se sono occupati |
POST | /api/v1/rpc/session | Prende un dispositivo in leasing → session_id |
POST | /api/v1/rpc/session/{id}/heartbeat | Estende il leasing |
DELETE | /api/v1/rpc/session/{id} | Rilascia il leasing |
GET | /api/v1/rpc/session | Elenca i leasing attivi |
POST | /api/v1/rpc/jsonrpc | Chiama un metodo UIAutomator2 |
POST | /api/v1/rpc/adb | Esegue un comando ADB |
GET | /api/v1/rpc/hierarchy?serial= | Albero UI corrente in XML |
GET | /api/v1/rpc/screenshot?serial= | Schermo corrente in PNG |
Le risposte JSON usano lo stesso involucro del resto dell'API locale — {"code": 0, "message": "success", "data": ...}, con code diverso da zero in caso di errore. hierarchy e screenshot restituiscono invece il corpo grezzo.
Esempio
# Prendere un dispositivo in leasing
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", ...}}
# Pilotarlo
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":[]}'
# Tenerlo vivo mentre lavori
curl -X POST http://127.0.0.1:50809/api/v1/rpc/session/ff3ae079-.../heartbeat \
-H "Content-Type: application/json" \
-d '{"ttl_secs":120}'
# Restituirlo
curl -X DELETE http://127.0.0.1:50809/api/v1/rpc/session/ff3ae079-...
Errori
| Stato | Significato |
|---|---|
| 403 | Piano inferiore a Pro, nessun leasing, leasing scaduto o accesso ADB disabilitato |
| 409 | Dispositivo già in leasing, o il piano non ha slot liberi |
Scrivere in un altro linguaggio
Qui non c'è nulla di specifico di Python. Va bene qualsiasi runtime in grado di fare una richiesta HTTP: il contratto della modalità gestita è solo «leggi tre variabili d'ambiente ed esci con 0 in caso di successo».
// my_flow.js — registralo con: 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"));
Se l'interprete non è nel PATH, indica il percorso completo in Comando, es. C:/Program Files/nodejs/node.exe C:/scripts/my_flow.js.
Avviare uno script personalizzato dall'API
Gli script registrati possono essere avviati anche tramite l'API di gestione attività, così uno script può accodare lavoro successivo:
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 è l'id dello script che hai registrato.
Accesso ADB
/api/v1/rpc/adb dà ai tuoi script una shell sul dispositivo: serve per caricare materiali, installare APK e cambiare impostazioni di sistema. Poiché è una shell completa su un endpoint senza chiave API, viene fornita disattivata. Attivala in Impostazioni → Developer API → Consenti comandi ADB quando hai uno script che ne ha bisogno; l'automazione dell'interfaccia tramite /rpc/jsonrpc funziona anche senza.
Mentre è disattivata, /api/v1/rpc/adb risponde 403 e il resto dell'API continua a funzionare. Ogni comando ADB eseguito da uno script viene scritto nel file di log.
Scrivere script che continuano a funzionare
- Aspetta la schermata, non dormire al suo posto.
d.wait_for(...)ritorna appena l'elemento c'è; uno sleep fisso è o più lento del necessario o troppo corto in una giornata storta. - Controlla prima di toccare. Un
d.exists(...)su una finestra di consenso o su un «non ora» costa un'estrazione dell'albero e salva un'esecuzione che altrimenti avrebbe toccato il vuoto. - Stampa quello che hai fatto. In modalità gestita stdout è il registro dell'attività, ed è l'unica traccia di un'esecuzione che nessuno stava guardando.
- Rendi sicura la riesecuzione. Un nuovo tentativo riesegue l'intero programma, quindi uno script che pubblica dovrebbe controllare se ha già pubblicato invece di dare per scontato di ripartire da zero.
- Uno script, un compito. La concorrenza è per dispositivo, quindi dieci attività piccole su dieci telefoni finiscono molto prima di uno script che cicla su dieci telefoni.
Note e limiti
- Il comando viene eseguito direttamente, non attraverso una shell, quindi
&&e|sono trattati come argomenti e non come operatori. Registracmd /c "..."(Windows) osh -c "..."(macOS) se vuoi il comportamento della shell. - Metti tra virgolette i percorsi con spazi:
"C:/Program Files/Python/python.exe" my_script.py. - Uno script che supera il timeout viene terminato e l'attività segnata come fallita.
- Un codice di uscita diverso da zero segna l'attività come fallita; tutto ciò che lo script scrive su stdout e stderr finisce nel registro dell'attività.
- Gli script girano con gli stessi permessi di TikMatrix. Registra solo programmi che hai scritto tu o di cui ti fidi.
Risoluzione dei problemi
API access requires Pro or higher plan (403)
La licenza su questa macchina è Starter o inattiva. Controlla Impostazioni → Licenza.
Connessione rifiutata su 127.0.0.1:50809
TikMatrix non è in esecuzione, o gira con un altro utente. Il server esiste solo mentre l'app è aperta.
409 a ogni tentativo di leasing O il telefono è davvero occupato — controlla in Impostazioni → Developer API → Sessioni dispositivo attive — oppure tutti gli slot dispositivo del piano sono già presi da attività in esecuzione.
Il leasing scade a metà di un passaggio lungo
Il TTL predefinito è 120 s e la libreria lo rinnova in background, quindi di solito significa che lo script ha bloccato il thread principale più a lungo del TTL. Aumenta ttl_secs (fino a 600) o sposta il lavoro lungo fuori da quel thread.
d.adb(...) fallisce con 403
L'accesso ADB è disattivato. Attivalo in Impostazioni → Developer API → Consenti comandi ADB.
Un selettore non trova mai nulla
print(d.hierarchy()) mostra l'albero esatto che find ha cercato. Il testo è confrontato in modo esatto, quindi uno spazio di troppo o un'etichetta tradotta sono la causa più comune; cercare per resource_id è più stabile che per text.
L'attività risulta fallita ma il telefono sembra a posto Leggi il registro dell'attività. Un'uscita diversa da zero — inclusa un'eccezione non gestita al termine di un'esecuzione riuscita — fa fallire l'attività anche se l'automazione ha funzionato.
Prossimi passi
- Panoramica dell'API locale — autenticazione e formato delle risposte
- API di gestione attività — creare, interrogare, ritentare e fermare attività
- Assistente IA — lascia che un modello rediga e registri uno script per te
- SDK ed esempi su GitHub