Aller au contenu principal

Scripts personnalisés

Les scripts intégrés couvrent les enchaînements courants. Quand il vous faut autre chose — une étape dans un autre ordre, un écran qu’ils ne touchent jamais, ou une application qui n’est ni TikTok ni Instagram — vous pouvez l’écrire vous-même dans n’importe quel langage et laisser TikMatrix vous confier le téléphone.

Prérequis

Exigence de licence

Les scripts personnalisés nécessitent une offre Pro, Team ou Business. L’offre Starter n’y a pas accès.

Le nombre d’appareils de votre offre est aussi la limite de parallélisme : une offre Pro (20 appareils) peut piloter 20 téléphones en même temps, que ce soit via des tâches intégrées, des scripts personnalisés ou un mélange des deux.

Deux façons d’exécuter un script

Autonome

Vous lancez votre programme vous-même. TikMatrix se contente de vous prêter des appareils.

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

Idéal pour les traitements ponctuels, la collecte de données et tout ce que vous voulez lancer depuis votre propre ordonnanceur.

Gérée

Vous enregistrez le programme dans TikMatrix et il devient une tâche comme les autres. Il bénéficie de la file de tâches, du parallélisme selon l’offre, des reprises automatiques, du journal des tâches et des modèles de planification. TikMatrix réserve l’appareil avant de démarrer votre programme et lui transmet l’identifiant de réservation dans son environnement.

from tikmatrix import TikMatrix

with TikMatrix.from_env() as d: # appareil déjà réservé
d.click(text="Log in")
print("done") # cette ligne atterrit dans le journal de la tâche

Idéal pour tout ce que vous voulez exécuter de façon répétée, à heure fixe ou sur de nombreux appareils.

Lequel choisir

AutonomeGérée
Qui lanceVousLa file de tâches de TikMatrix
Réservation de l’appareilVous la demandezDéjà détenue au démarrage
Reprises, planification, journalÀ construire vous-mêmeFournis
Exécution sur de nombreux appareilsVous écrivez la boucleUne tâche par appareil, en parallèle
Idéal pourExploration, crawlers, traitements ponctuelsTout ce que vous voulez répéter

Vous pouvez commencer en autonome le temps de mettre au point le déroulé, puis enregistrer le même fichier comme script géré — seule la ligne TikMatrix.from_env() change.

Pour commencer

1. Installez la bibliothèque cliente

pip install requests

Copiez ensuite tikmatrix.py depuis le répertoire du SDK à côté de votre script. La bibliothèque tient dans un seul fichier, sans autre dépendance.

Rien ne vous oblige à l’utiliser : l’API n’est que du JSON sur HTTP, et les points de terminaison bruts sont documentés plus bas.

2. Écrivez votre 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")

Lancez-le avec TikMatrix ouvert et le téléphone connecté. S’il affiche un dictionnaire d’informations sur l’appareil, tout est en place.

3. Enregistrez-le (mode géré uniquement)

Allez dans Appareils → Scripts personnalisés → Ajouter un script :

ChampSignification
NomAffiché dans la liste des scripts et dans le journal des tâches
CommandeLa ligne de programme à exécuter, p. ex. python C:/scripts/my_flow.py
Répertoire de travailFacultatif. Là où le programme démarre
PlateformeVoir les modes de plateforme plus bas
Délai d’expirationSecondes avant que le script soit tué et la tâche marquée en échec. 1800 par défaut
Variables d’environnement supplémentairesObjet JSON facultatif fusionné dans l’environnement du programme
ActivéDésactiver un script sans le supprimer. Un script désactivé ne peut pas être distribué

Appuyez ensuite sur ▶ sur la ligne du script et choisissez vos appareils, exactement comme pour un script intégré.

Laissez l’assistant l’écrire

L’assistant IA peut rédiger un script personnalisé à partir d’une description en langage courant et l’enregistrer en une seule étape. Il vous montre le fichier entier avant d’écrire quoi que ce soit sur le disque.

Réservations d’appareil

Un téléphone ne peut être piloté que par une seule chose à la fois. Le réserver indique à TikMatrix que l’appareil est occupé, de sorte que :

  • la file de tâches n’enverra pas de tâche sur le même écran, et
  • vos appels JSON-RPC signalent l’état de l’agent exactement comme le fait un script intégré : le chien de garde voit un agent occupé plutôt qu’un agent muet.

Une réservation consomme aussi un emplacement d’appareil de votre offre.

Les réservations expirent — 120 secondes par défaut, 600 au maximum. La bibliothèque Python renouvelle la vôtre depuis un thread de fond et la libère à la sortie du bloc with : un script qui plante rend donc son appareil en quelques secondes au lieu de le garder jusqu’au redémarrage de l’application. Si vous appelez l’API directement, envoyez les battements vous-même.

Vous pouvez voir toutes les réservations en cours — et en libérer une de force — dans Paramètres → Developer API → Sessions d’appareil actives.

Modes de plateforme

Un script enregistré déclare sa cible :

Generic — l’appareil est remis tel quel. Aucune application n’est lancée, aucun changement de compte, aucune vérification de la méthode de saisie, et rien n’est fermé ensuite. À utiliser pour automatiser tout ce qui n’est ni TikTok ni Instagram.

TikTok / Instagram — l’application est ouverte et le compte basculé avant le démarrage de votre programme, et l’application est fermée à la fin, exactement comme pour un script intégré. TIKMATRIX_PACKAGE vous indique le paquet retenu. À utiliser pour ajouter une étape que les scripts intégrés ne couvrent pas.

Variables d’environnement

Un script géré reçoit :

VariableSignification
TIKMATRIX_API_BASEURL du serveur, p. ex. http://127.0.0.1:50809
TIKMATRIX_SESSION_IDLa réservation déjà détenue pour vous
TIKMATRIX_SERIALL’appareil auquel cette tâche a été affectée
TIKMATRIX_PACKAGEPaquet applicatif retenu
TIKMATRIX_PLATFORMtiktok, instagram ou generic

TikMatrix.from_env() lit tout cela pour vous.

Les scripts autonomes n’en reçoivent aucune — réservez explicitement un appareil.

Tout ce que vous mettez dans Variables d’environnement supplémentaires est fusionné par-dessus : c’est la manière habituelle de donner à un même script enregistré des réglages propres à une exécution sans modifier le fichier.

Référence de la bibliothèque Python

TikMatrix — la connexion

AppelRôle
TikMatrix(base_url=None, timeout=30.0)Se connecte. Repli sur TIKMATRIX_API_BASE, puis http://127.0.0.1:50809
client.devices()Appareils en ligne, chacun avec serial, real_serial et busy
client.sessions()Toutes les réservations en cours, y compris celles d’autres processus
client.device(serial, label=..., ttl_secs=120)Réserve un appareil et renvoie un Device
TikMatrix.from_env()Reprend l’appareil avec lequel un script géré a été lancé

Device — le téléphone

AppelRôle
d.info()Informations d’appareil UIAutomator2
d.window_size()(largeur, hauteur)
d.screenshot(path=None)Octets PNG, éventuellement écrits dans path
d.hierarchy()L’arbre d’interface courant en XML
d.find(text=, resource_id=, description=, class_name=)Nœuds correspondants, chacun avec bounds et center
d.exists(**criteria)Y a-t-il une correspondance
d.wait_for(timeout=10.0, interval=1.0, **criteria)Bloque jusqu’à l’apparition, puis renvoie l’élément
d.click(timeout=10.0, **criteria)Attend un élément puis tape en son centre
d.click_xy(x, y)Tape une coordonnée
d.swipe(sx, sy, ex, ey, steps=20)Balaye
d.press(key)back, home, recent, enter, …
d.input_text(text)Saisit dans le champ actif via le clavier rapide fourni
d.jsonrpc(method, params=None, timeout=10)N’importe quelle méthode UIAutomator2
d.adb(*args, timeout_ms=None)Exécute une commande ADB
d.release()Libère la réservation. with s’en charge

find cherche dans l’arbre d’interface extrait : quand un sélecteur rate, vous pouvez donc faire print(d.hierarchy()) et voir exactement ce qui a été parcouru. L’inspecteur d’éléments de la vue appareil affiche le même arbre visuellement, ce qui est généralement le plus rapide pour trouver un resource-id.

input_text nécessite ADB

Il envoie un broadcast au clavier fourni, ce qui passe par adb shell. Activez l’accès ADB avant de l’utiliser, sinon il échoue en 403.

Erreurs

La bibliothèque lève deux exceptions, toutes deux sous-classes de RuntimeError :

ExceptionQuand
DeviceBusyErrorHTTP 409 — l’appareil est déjà réservé, ou l’offre n’a plus d’emplacement libre
TikMatrixErrorTout le reste : offre insuffisante, réservation expirée, ADB désactivé, sélecteur jamais trouvé
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("ce téléphone est pris par autre chose — essayez-en un autre")
except TikMatrixError as exc:
print("échec :", exc)

Dans un script géré, laisser l’exception remonter est généralement la bonne approche : le code de sortie non nul marque la tâche en échec et la trace atterrit dans le journal de la tâche.

Points de terminaison HTTP

Les opérations sur appareil exigent un en-tête x-session-id désignant une réservation en cours. Il n’y a pas de clé d’API : comme le reste de l’API locale, ces points de terminaison ne sont pas authentifiés — pouvoir atteindre la machine sur le réseau est le contrôle d’accès. Ils n’envoient aucun en-tête CORS : appelez-les depuis un programme (curl, Python, n’importe quel code côté serveur) plutôt que depuis une page dans un navigateur.

MéthodeCheminObjet
GET/api/v1/rpc/devicesListe les appareils en ligne et leur occupation
POST/api/v1/rpc/sessionRéserve un appareil → session_id
POST/api/v1/rpc/session/{id}/heartbeatProlonge la réservation
DELETE/api/v1/rpc/session/{id}Libère la réservation
GET/api/v1/rpc/sessionListe les réservations en cours
POST/api/v1/rpc/jsonrpcAppelle une méthode UIAutomator2
POST/api/v1/rpc/adbExécute une commande ADB
GET/api/v1/rpc/hierarchy?serial=Arbre d’interface courant en XML
GET/api/v1/rpc/screenshot?serial=Écran courant en PNG

Les réponses JSON utilisent la même enveloppe que le reste de l’API locale — {"code": 0, "message": "success", "data": ...}, avec un code non nul en cas d’échec. hierarchy et screenshot renvoient le corps brut.

Exemple

# Réserver un appareil
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", ...}}

# Le piloter
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":[]}'

# Maintenir la réservation pendant le travail
curl -X POST http://127.0.0.1:50809/api/v1/rpc/session/ff3ae079-.../heartbeat \
-H "Content-Type: application/json" \
-d '{"ttl_secs":120}'

# Le rendre
curl -X DELETE http://127.0.0.1:50809/api/v1/rpc/session/ff3ae079-...

Erreurs

StatutSignification
403Offre inférieure à Pro, pas de réservation, réservation expirée, ou accès ADB désactivé
409Appareil déjà réservé, ou plus d’emplacement libre dans l’offre

Écrire dans un autre langage

Rien ici n’est propre à Python. N’importe quel environnement capable d’émettre une requête HTTP convient — le contrat du mode géré se résume à « lire trois variables d’environnement et sortir avec 0 en cas de succès ».

// my_flow.js — à enregistrer avec : 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"));

Si l’interpréteur n’est pas dans le PATH, indiquez son chemin complet dans Commande, p. ex. C:/Program Files/nodejs/node.exe C:/scripts/my_flow.js.

Déclencher un script personnalisé depuis l’API

Les scripts enregistrés peuvent aussi être lancés via l’API de gestion des tâches, de sorte qu’un script peut mettre en file du travail complémentaire :

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 est l’identifiant du script que vous avez enregistré.

Accès ADB

/api/v1/rpc/adb donne à vos scripts un shell sur l’appareil — nécessaire pour pousser des médias, installer des APK et modifier des réglages système. Comme c’est un shell complet sur un point de terminaison sans clé d’API, il est livré désactivé. Activez-le dans Paramètres → Developer API → Autoriser les commandes ADB lorsque vous avez un script qui en a besoin ; l’automatisation d’interface via /rpc/jsonrpc fonctionne sans lui.

Tant qu’il est désactivé, /api/v1/rpc/adb répond 403 et le reste de l’API continue de fonctionner. Chaque commande ADB exécutée par un script est écrite dans votre fichier de journal.

Écrire des scripts qui tiennent dans la durée

  • Attendez l’écran, ne dormez pas à sa place. d.wait_for(...) revient dès que l’élément est là ; un sleep fixe est soit plus lent que nécessaire, soit trop court un mauvais jour.
  • Vérifiez avant de taper. Un d.exists(...) sur une boîte de consentement ou un « pas maintenant » coûte une extraction d’arbre et sauve une exécution qui aurait sinon tapé dans le vide.
  • Affichez ce que vous avez fait. En mode géré, la sortie standard est le journal de la tâche, et c’est la seule trace d’une exécution que personne ne regardait.
  • Rendez la reprise sûre. Une reprise relance tout le programme : un script qui publie devrait vérifier s’il a déjà publié plutôt que de supposer qu’il part de zéro.
  • Un script, une mission. Le parallélisme est par appareil : dix petites tâches sur dix téléphones finissent bien plus vite qu’un script qui boucle sur dix téléphones.

Remarques et limites

  • La commande est exécutée directement, pas via un shell : && et | sont donc traités comme des arguments et non des opérateurs. Enregistrez cmd /c "..." (Windows) ou sh -c "..." (macOS) si vous voulez le comportement d’un shell.
  • Mettez entre guillemets les chemins contenant des espaces : "C:/Program Files/Python/python.exe" my_script.py.
  • Un script qui dépasse son délai est arrêté et la tâche est marquée en échec.
  • Un code de sortie non nul marque la tâche en échec ; tout ce que le script écrit sur stdout et stderr atterrit dans le journal de la tâche.
  • Les scripts s’exécutent avec les mêmes droits que TikMatrix. N’enregistrez que des programmes que vous avez écrits ou en lesquels vous avez confiance.

Dépannage

API access requires Pro or higher plan (403) La licence de cette machine est Starter ou inactive. Vérifiez Paramètres → Licence.

Connexion refusée sur 127.0.0.1:50809 TikMatrix n’est pas lancé, ou tourne sous un autre utilisateur. Le serveur n’existe que tant que l’application est ouverte.

409 à chaque tentative de réservation Soit le téléphone est réellement occupé — regardez dans Paramètres → Developer API → Sessions d’appareil actives — soit tous les emplacements d’appareil de l’offre sont déjà pris par des tâches en cours.

La réservation expire au milieu d’une étape longue Le TTL par défaut est de 120 s et la bibliothèque le renouvelle en fond : cela signifie donc généralement que le script a bloqué son thread principal plus longtemps que le TTL. Augmentez ttl_secs (jusqu’à 600), ou sortez le travail long de ce thread.

d.adb(...) échoue en 403 L’accès ADB est désactivé. Activez-le dans Paramètres → Developer API → Autoriser les commandes ADB.

Un sélecteur ne correspond jamais print(d.hierarchy()) montre l’arbre exact parcouru par find. Le texte est comparé à l’identique : une espace en trop ou un libellé traduit en est la cause habituelle ; chercher par resource_id est plus stable que par text.

La tâche est en échec alors que le téléphone semble aller bien Lisez le journal de la tâche. Une sortie non nulle — y compris une exception non rattrapée à la fin d’une exécution réussie — met la tâche en échec même si l’automatisation elle-même a fonctionné.

Étapes suivantes