Власні скрипти
Вбудовані скрипти охоплюють типові сценарії. Коли потрібне щось інше — крок в іншому порядку, екран, якого вони ніколи не торкаються, або застосунок, що не є 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 напряму, надсилайте сигнали життя самостійно.
Усі активні оренди можна побачити — і примусово звільнити — у Налаштування → 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)
У керованому скрипті зазвичай правильно дати винятку вилетіти назовні: ненульовий код виходу позначає завдання як невдале, а трасування потрапляє до журналу завдання.
Кінцеві точки HTTP
Операції з пристроєм потребують заголовка x-session-id, що вказує на активну оренду. Ключа API немає: як і решта локального API, ці кінцеві точки не автентифікуються — контролем доступу є сама можливість дістатися до машини в мережі. Вони не надсилають заголовків CORS, тож звертайтеся до них із програми (curl, Python, будь-який серверний код), а не зі сторінки в браузері.
| Метод | Шлях | Призначення |
|---|---|---|
GET | /api/v1/rpc/devices | Перелік пристроїв онлайн і чи зайняті вони |
POST | /api/v1/rpc/session | Орендувати пристрій → session_id |
POST | /api/v1/rpc/session/{id}/heartbeat | Подовжити оренду |
DELETE | /api/v1/rpc/session/{id} | Звільнити оренду |
GET | /api/v1/rpc/session | Перелік активних оренд |
POST | /api/v1/rpc/jsonrpc | Викликати метод UIAutomator2 |
POST | /api/v1/rpc/adb | Виконати команду ADB |
GET | /api/v1/rpc/hierarchy?serial= | Поточне дерево інтерфейсу як XML |
GET | /api/v1/rpc/screenshot?serial= | Поточний екран як PNG |
Відповіді JSON використовують ту саму оболонку, що й решта локального API — {"code": 0, "message": "success", "data": ...}, з ненульовим code у разі помилки. hierarchy та screenshot повертають сире тіло.
Приклад
# Орендувати пристрій
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", ...}}
# Керувати ним
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":[]}'
# Підтримувати оренду під час роботи
curl -X POST http://127.0.0.1:50809/api/v1/rpc/session/ff3ae079-.../heartbeat \
-H "Content-Type: application/json" \
-d '{"ttl_secs":120}'
# Повернути пристрій
curl -X DELETE http://127.0.0.1:50809/api/v1/rpc/session/ff3ae079-...
Помилки
| Статус | Значення |
|---|---|
| 403 | План нижчий за Pro, немає оренди, оренда збігла, або доступ до ADB вимкнено |
| 409 | Пристрій уже орендовано, або в плані немає вільного слота |
Писати іншою мовою
Тут немає нічого специфічного для Python. Підійде будь-яке середовище, що вміє надсилати HTTP-запити — контракт керованого режиму лише такий: «прочитай три змінні середовища, вийди з кодом 0 у разі успіху».
// my_flow.js — реєструйте так: 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"));
Якщо інтерпретатора немає в PATH, укажіть повний шлях у полі Команда, наприклад C:/Program Files/nodejs/node.exe C:/scripts/my_flow.js.
Запуск власного скрипта через API
Зареєстровані скрипти можна запускати й через API керування завданнями, тож один скрипт може ставити в чергу подальшу роботу:
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 — це ідентифікатор зареєстрованого вами скрипта.
Доступ до ADB
/api/v1/rpc/adb дає вашим скриптам оболонку на пристрої — вона потрібна для завантаження медіа, встановлення APK і зміни системних налаштувань. Оскільки це повноцінна оболонка на кінцевій точці без ключа API, вона постачаєть ся вимкненою. Увімкніть її в Налаштування → Developer API → Дозволити команди ADB, коли у вас з'явиться скрипт, якому вона потрібна; автоматизація інтерфейсу через /rpc/jsonrpc працює й без неї.
Поки вона вимкнена, /api/v1/rpc/adb відповідає 403, а решта API працює як звичайно. Кожна команда ADB, яку виконує скрипт, записується у ваш файл журналу.
Як писати скрипти, що продовжують працювати
- Чекайте на екран, а не спіть замість цього.
d.wait_for(...)повертається щойно елемент з'явився; фіксована пауза або повільніша, ніж потрібно, або надто коротка в невдалий день. - Перевіряйте, перш ніж торкатися.
d.exists(...)на вікні згоди чи підказці «не зараз» коштує одного вивантаження дерева і рятує запуск, який інакше торкнувся б порожнечі. - Друкуйте те, що зробили. У керованому режимі stdout — це журнал завдання, і це єдиний слід запуску, за яким ніхто не спостерігав.
- Зробіть повторний запуск безпечним. Повтор виконує всю програму заново, тож скрипт, що публікує, має перевіряти, чи вже опублікував, а не припускати, що починає з нуля.
- Один скрипт — одна робота. Паралельність рахується на пристрій, тож десять невеликих завдань на десяти телефонах завершаться значно швидше, ніж один скрипт, що в циклі обходить десять телефонів.
Нотатки й обмеження
- Команда виконується напряму, не через оболонку, тож
&&і|вважаються аргументами, а не операторами. Зареєструйтеcmd /c "..."(Windows) абоsh -c "..."(macOS), якщо вам потрібна поведінка оболонки. - Беріть у лапки шляхи з пробілами:
"C:/Program Files/Python/python.exe" my_script.py. - Скрипт, що перевищив тайм-аут, завершується, а завдання позначаєть ся як невдале.
- Ненульовий код виходу позначає завдання як невдале; усе, що скрипт пише у stdout і stderr, потрапляє до журналу завдання.
- Скрипти виконуються з тими самими правами, що й сам TikMatrix. Реєструйте лише програми, які написали ви або яким довіряєте.
Усунення несправностей
API access requires Pro or higher plan (403)
Ліцензія на цій машині — Starter або неактивна. Перевірте Налаштування → Ліцензія.
Відмова у з'єднанні на 127.0.0.1:50809
TikMatrix не запущено, або він працює під іншим користувачем. Сервер існує лише поки застосунок відкрито.
409 за кожної спроби оренди Або телефон справді зайнятий — подивіться в Налаштування → Developer API → Активні сеанси пристроїв — або всі слоти пристроїв у плані вже зайняті активними завданнями.
Оренда збігає посеред довгого кроку
Типовий TTL — 120 с, і бібліотека поновлює його у фоні, тож зазвичай це означає, що скрипт заблокував свій головний потік довше за TTL. Збільште ttl_secs (до 600) або винесіть тривалу роботу з цього потоку.
d.adb(...) завершується з 403
Доступ до ADB вимкнено. Увімкніть його в Налаштування → Developer API → Дозволити команди ADB.
Селектор ніколи не збігається
print(d.hierarchy()) показує саме те дерево, у якому шукав find. Текст порівнюється точно, тож зайвий пробіл або локалізований підпис — найчастіша причина; пошук за resource_id стабільніший, ніж за text.
Завдання позначене як невдале, але телефон виглядає добре Прочитайте журнал завдання. Ненульовий вихід — зокрема неперехоплений виняток наприкінці вдалого запуску — робить завдання невдалим, навіть якщо сама автоматизація спрацювала.
Далі
- Огляд локального API — автентифікація та формат відповіді
- API керування завданнями — створення, запити, повтор і зупинка завдань
- ШІ-асистент — хай модель складе й зареєструє скрипт за вас
- SDK і приклади на GitHub