Пользовательские скрипты
Встроенные скрипты закрывают типовые сценарии. Когда нужно что-то другое — шаг в ином порядке, экран, которого они не касаются, или приложение, отличное от TikTok и Instagram, — вы можете написать это сами на любом языке, а TikMatrix передаст вам телефон.
Требования
Пользовательские скрипты доступны на планах Pro, Team и Business. На плане Starter доступа нет.
Количество устройств в вашем плане — это одновременно и лимит параллельности: план Pro (20 устройств) может одновременно управлять 20 телефонами, будь то встроенные задачи, пользовательские скрипты или их смесь.
Два способа запуска
Автономный
Программу запускаете вы сами. TikMatrix только одалживает вам устройства.
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())
Подходит для разовых задач, сбора данных и всего, что вы хотите запускать из собственного планировщика.
Управляемый
Вы регистрируете программу в TikMatrix, и она становится обычной задачей: очередь задач, параллельность по плану, автоматические повторы, журнал задач и шаблоны расписаний. TikMatrix берёт устройство в аренду до старта вашей программы и передаёт идентификатор аренды через окружение.
from tikmatrix import TikMatrix
with TikMatrix.from_env() as d: # устройство уже арендовано
d.click(text="Log in")
print("done") # эта строка попадёт в журнал задачи
Подходит для всего, что нужно запускать регулярно, по расписанию или на многих устройствах.
Что выбрать
| Автономный | Управляемый | |
|---|---|---|
| Кто запускает | Вы | Очередь задач TikMatrix |
| Аренда устройства | Берё те сами | Уже удерживается на старте программы |
| Повторы, расписания, журнал | Реализуете сами | Уже есть |
| Запуск на многих устройствах | Пишете цикл сами | По задаче на устройство, параллельно |
| Для чего лучше | Исследование, краулеры, разовые задачи | Всё, что нужно повторять |
Можно начать с автономного режима, отладить сценарий, а затем зарегистрировать тот же файл как управляемый скрипт — меняется только строка TikMatrix.from_env().
Начало работы
1. Установите клиентскую библиотеку
pip install requests
Затем скопируйте tikmatrix.py из каталога SDK рядом со своим скриптом. Библиотека — один файл без других зависимостей.
Использовать её необязательно: API — это обычный JSON поверх HTTP, сырые эндпоинты описаны ниже.
2. Напишите скрипт
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")
Запустите его при открытом TikMatrix и подключённом телефоне. Если он напечатал словарь с информацией об устройстве — всё подключено правильно.
3. Зарегистрируйте его (только управляемый реж им)
Откройте Устройства → Пользовательские скрипты → Добавить скрипт:
| Поле | Значение |
|---|---|
| Название | Показывается в списке скриптов и в журнале задач |
| Команда | Строка запуска программы, например python C:/scripts/my_flow.py |
| Рабочий каталог | Необязательно. Где стартует программа |
| Платформа | См. режимы платформы ниже |
| Таймаут | Через сколько секунд скрипт убивается, а задача помечается неуспешной. По умолчанию 1800 |
| Дополнительные переменные окружения | Необязательный JSON-объект, добавляемый в окружение программы |
| Включён | Отключить скрипт, не удаляя его. Отключённый скрипт нельзя отправить в работу |
Затем нажмите ▶ в строке скрипта и в ыберите устройства — точно как для встроенного скрипта.
ИИ-ассистент может составить пользовательский скрипт по описанию на обычном языке и зарегистрировать его за один шаг. Весь файл он показывает вам до того, как что-либо будет записано на диск.
Аренда устройств
Телефоном одновременно может управлять только что-то одно. Аренда сообщает TikMatrix, что устройство занято, поэтому:
- очередь задач не отправит задачу на тот же экран, и
- ваши JSON-RPC вызовы со общают о состоянии агента ровно так же, как встроенный скрипт, — сторожевой таймер видит занятый агент, а не молчащий.
Аренда также занимает один слот устройства из вашего плана.
Аренда истекает — по умолчанию через 120 секунд, максимум 600. Python-библиотека продлевает её в фоновом потоке и освобождает при выходе из блока with, поэтому упавший скрипт отдаёт устройство за секунды, а не удерживает его до перезапуска приложения. Если вы обращаетесь к API напрямую, отправляйте heartbeat самостоятельно.
Все действующие аренды видны — и принудительно снимаются — в разделе Настройки → Developer API → Активные сессии устройств.
Режимы платформы
Зарегистрированный скрипт объявляет, на что он нацелен:
Generic — устройство передаётся как есть. Приложение не запускается, аккаунты не переключаются, метод ввода не проверяется, и после завершения ничего не закрывается. Используйте для автоматизации всего, что не является TikTok или Instagram.
TikTok / Instagram — приложение открывается и аккаунт переключается до старта вашей программы, а по завершении приложение закрывается — так же, как для встроенного скрипта. TIKMATRIX_PACKAGE сообщает, какой пакет был выбран. Используйте, чтобы добавить шаг, которого нет во встроенных скриптах.
Переменные окружения
Управляемый скрипт получает:
| Переменная | Значение |
|---|---|
TIKMATRIX_API_BASE | URL сервера, например http://127.0.0.1:50809 |
TIKMATRIX_SESSION_ID | Аренда, уже удерживаемая для вас |
TIKMATRIX_SERIAL | Устройство, на которое отправлена задача |
TIKMATRIX_PACKAGE | Определённый пакет приложения |
TIKMATRIX_PLATFORM | tiktok, instagram или generic |
TikMatrix.from_env() читает всё это за вас.
Автономные скрипты не получают ничего из этого — берите устройство в аренду явно.
Всё, что вы указал и в Дополнительных переменных окружения, накладывается сверху: это обычный способ передать одному зарегистрированному скрипту настройки конкретного запуска, не редактируя файл.
Справочник Python-библиотеки
TikMatrix — соединение
| Вызов | Что делает |
|---|---|
TikMatrix(base_url=None, timeout=30.0) | Подключение. Откат к TIKMATRIX_API_BASE, затем к http://127.0.0.1:50809 |
client.devices() | Устройства онлайн, каждое с serial, real_serial и busy |
client.sessions() | Все действующие аренды, включая чужие |
client.device(serial, label=..., ttl_secs=120) | Арендовать устройство и получить Device |
TikMatrix.from_env() | Принять устройство, с которым был запущен управляемый скрипт |
Device — телефон
| Вызов | Что делает |
|---|---|
d.info() | Информация об устройстве от UIAutomator2 |
d.window_size() | (ширина, высота) |
d.screenshot(path=None) | Байты PNG, при необходимости записываются в path |
d.hierarchy() | Текущее дерево интерфейса в XML |
d.find(text=, resource_id=, description=, class_name=) | Совпавшие узлы, каждый с bounds и center |
d.exists(**criteria) | Есть ли совпадения |
d.wait_for(timeout=10.0, interval=1.0, **criteria) | Ждать появления и вернуть элемент |
d.click(timeout=10.0, **criteria) | Дождаться элемента и нажать в его центр |
d.click_xy(x, y) | Нажатие по координате |
d.swipe(sx, sy, ex, ey, steps=20) | Свайп |
d.press(key) | back, home, recent, enter, … |
d.input_text(text) | Ввод в поле в фокусе через встроенный быстрый метод ввода |
d.jsonrpc(method, params=None, timeout=10) | Любой метод UIAutomator2 |
d.adb(*args, timeout_ms=None) | Выполнить ADB-команду |
d.release() | Освободить аренду. with делает это за вас |
find ищет по выгруженному дереву интерфейса, поэтому, когда селектор промахивается, можно вызвать print(d.hierarchy()) и посмотреть, по чему именно шёл поиск. Инспектор элементов в представлении устройства показывает то же дерево визуально — обычно это самый быстрый способ найти resource-id.
input_text требует ADBОн отправляет широковещательное сообщение встроенному методу ввода через adb shell. Включите доступ к ADB перед использованием, иначе будет 403.
Ошибки
Библиотека выбрасывает два исключения, оба наследники RuntimeError:
| Исключение | Когда |
|---|---|
DeviceBusyError | HTTP 409 — устройство уже арендовано либо в плане нет свободного слота |
TikMatrixError | Всё остальное: слишком низкий план, истёкшая аренда, выключенный ADB, селектор так и не совпал |
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("этот телефон занят кем-то другим — возьмите другой")
except TikMatrixError as exc:
print("сбой:", exc)
В управляемом скрипте чаще всего правильно дать исключению вылететь наружу: ненулевой код выхода помечает задачу неуспешной, а трассировка попадает в журнал задачи.