Перейти до основного вмісту

Власні скрипти

Вбудовані скрипти охоплюють типові сценарії. Коли потрібне щось інше — крок в іншому порядку, екран, якого вони ніколи не торкаються, або застосунок, що не є 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 — пристрій передається без змін. Жоден застосунок не запускається, облікові записи не перемикаються, метод введення не перевіряється, і нічого не закривається після завершення. Використовуйте це для автоматизації застосунку, якого TikMatrix не керує самостійно.

TikTok / Instagram / Threads — застосунок відкривається, а потрібний обліковий запис робиться актуальним до старту вашої програми; після завершення застосунок закривається — так само, як для вбудованого скрипта. TIKMATRIX_PACKAGE повідомляє, який пакет було визначено. Використовуйте це, щоб додати крок, якого немає у вбудованих скриптах.

На Threads перемикання облікового запису проходить через Налаштування → Змінити обліковий запис в програмі, а ім'я на сторінці профілю читається далі. Завдання, яке називає обліковий запис, не залогований на пристрої, завершується помилкою замість виконання як активного облікового запису.

Змінні середовища​

Керований скрипт отримує:

ЗміннаЗначення
TIKMATRIX_API_BASEURL сервера, наприклад http://127.0.0.1:50809
TIKMATRIX_SESSION_IDОренда, яку вже утримують для вас
TIKMATRIX_SERIALПристрій, на який надіслано це завдання
TIKMATRIX_PACKAGEВизначений пакет застосунку
TIKMATRIX_PLATFORMtiktok, instagram, threads або 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:

ВинятокКоли
DeviceBusyErrorHTTP 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.

Завдання позначене як невдале, але телефон виглядає добре Прочитайте журнал завдання. Ненульовий вихід — зокрема неперехоплений виняток наприкінці вдалого запуску — робить завдання невдалим, навіть якщо сама автоматизація спрацювала.

Далі​