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
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
| Autonome | Gérée | |
|---|---|---|
| Qui lance | Vous | La file de tâches de TikMatrix |
| Réservation de l’appareil | Vous la demandez | Déjà détenue au démarrage |
| Reprises, planification, journal | À construire vous-même | Fournis |
| Exécution sur de nombreux appareils | Vous écrivez la boucle | Une tâche par appareil, en parallèle |
| Idéal pour | Exploration, crawlers, traitements ponctuels | Tout 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 :
| Champ | Signification |
|---|---|
| Nom | Affiché dans la liste des scripts et dans le journal des tâches |
| Commande | La ligne de programme à exécuter, p. ex. python C:/scripts/my_flow.py |
| Répertoire de travail | Facultatif. Là où le programme démarre |
| Plateforme | Voir les modes de plateforme plus bas |
| Délai d’expiration | Secondes avant que le script soit tué et la tâche marquée en échec. 1800 par défaut |
| Variables d’environnement supplémentaires | Objet 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é.
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 :
| Variable | Signification |
|---|---|
TIKMATRIX_API_BASE | URL du serveur, p. ex. http://127.0.0.1:50809 |
TIKMATRIX_SESSION_ID | La réservation déjà d étenue pour vous |
TIKMATRIX_SERIAL | L’appareil auquel cette tâche a été affectée |
TIKMATRIX_PACKAGE | Paquet applicatif retenu |
TIKMATRIX_PLATFORM | tiktok, 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
| Appel | Rô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
| Appel | Rô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 ADBIl 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 :
| Exception | Quand |
|---|---|
DeviceBusyError | HTTP 409 — l’appareil est déjà r éservé, ou l’offre n’a plus d’emplacement libre |
TikMatrixError | Tout 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éthode | Chemin | Objet |
|---|---|---|
GET | /api/v1/rpc/devices | Liste les appareils en ligne et leur occupation |
POST | /api/v1/rpc/session | Réserve un appareil → session_id |
POST | /api/v1/rpc/session/{id}/heartbeat | Prolonge la réservation |
DELETE | /api/v1/rpc/session/{id} | Libère la réservation |
GET | /api/v1/rpc/session | Liste les réservations en cours |
POST | /api/v1/rpc/jsonrpc | Appelle une méthode UIAutomator2 |
POST | /api/v1/rpc/adb | Exé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
| Statut | Signification |
|---|---|
| 403 | Offre inférieure à Pro, pas de réservation, réservation expirée, ou accès ADB désactivé |
| 409 | Appareil 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. Enregistrezcmd /c "..."(Windows) oush -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
- Présentation de l’API locale — authentification et format de réponse
- API de gestion des tâches — créer, interroger, relancer et arrêter des tâches
- Assistant IA — laissez un modèle rédiger et enregistrer un script pour vous
- SDK et exemples sur GitHub