Pular para o conteúdo principal

Scripts personalizados

Os scripts integrados cobrem os fluxos comuns. Quando você precisa de algo que eles não fazem — uma etapa em outra ordem, uma tela que eles nunca tocam ou um app que não é TikTok nem Instagram — você pode escrever por conta própria em qualquer linguagem e deixar o TikMatrix entregar o telefone para você.

Requisitos​

Requisito de licença

Scripts personalizados exigem um plano Pro, Team ou Business. O plano Starter não tem acesso.

O número de dispositivos do seu plano também é o limite de concorrência: um plano Pro (20 dispositivos) pode controlar 20 telefones ao mesmo tempo, seja por tarefas integradas, scripts personalizados ou uma mistura dos dois.

Duas formas de rodar um script​

Autônoma​

Você mesmo executa o programa. O TikMatrix apenas empresta os dispositivos.

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

Boa para trabalhos pontuais, coleta de dados e qualquer coisa que você queira rodar pelo seu próprio agendador.

Gerenciada​

Você registra o programa no TikMatrix e ele vira uma tarefa como qualquer outra. Ganha a fila de tarefas, a concorrência por plano, as novas tentativas automáticas, o log de tarefas e os modelos de agendamento. O TikMatrix aluga o dispositivo antes de iniciar seu programa e passa o id do aluguel no ambiente.

from tikmatrix import TikMatrix

with TikMatrix.from_env() as d: # dispositivo já alugado
d.click(text="Log in")
print("done") # esta linha vai parar no log da tarefa

Boa para tudo que você quer rodar repetidamente, em horário marcado ou em muitos dispositivos.

Qual escolher​

AutônomaGerenciada
Quem iniciaVocêA fila de tarefas do TikMatrix
Aluguel do dispositivoVocê adquireJá está em mãos ao iniciar
Novas tentativas, agendamento, logVocê constróiJá vem incluído
Rodar em muitos dispositivosVocê escreve o laçoUma tarefa por dispositivo, em paralelo
Melhor paraExploração, crawlers, trabalhos pontuaisTudo que você quer repetir

Você pode começar no modo autônomo enquanto acerta o fluxo e depois registrar o mesmo arquivo como script gerenciado — a única linha que muda é TikMatrix.from_env().

Primeiros passos​

1. Instale a biblioteca cliente​

pip install requests

Depois copie o tikmatrix.py do diretório do SDK para junto do seu script. A biblioteca é um único arquivo, sem outras dependências.

Você não é obrigado a usá-la — a API é JSON puro sobre HTTP, e os endpoints crus estão documentados abaixo.

2. Escreva seu 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")

Rode com o TikMatrix aberto e o telefone conectado. Se imprimir um dicionário com as informações do dispositivo, está tudo ligado.

3. Registre-o (apenas modo gerenciado)​

Vá em Dispositivos → Scripts personalizados → Adicionar script:

CampoSignificado
NomeAparece na lista de scripts e no log de tarefas
ComandoA linha do programa a executar, ex.: python C:/scripts/my_flow.py
Diretório de trabalhoOpcional. Onde o programa inicia
PlataformaVeja modos de plataforma abaixo
Tempo limiteSegundos até o script ser encerrado e a tarefa marcada como falha. Padrão 1800
Variáveis de ambiente extrasObjeto JSON opcional mesclado ao ambiente do programa
HabilitadoDesliga um script sem apagá-lo. Um script desabilitado não pode ser despachado

Depois clique em ▶ na linha do script e escolha os dispositivos, exatamente como em um script integrado.

Deixe o assistente escrever

O Assistente de IA pode redigir um script personalizado a partir de uma descrição em linguagem comum e registrá-lo em uma única etapa. Ele mostra o arquivo inteiro antes de gravar qualquer coisa em disco.

Aluguéis de dispositivo​

Um telefone só pode ser controlado por uma coisa de cada vez. Alugá-lo avisa ao TikMatrix que o dispositivo está ocupado, de modo que:

  • a fila de tarefas não despacha uma tarefa para a mesma tela, e
  • suas chamadas JSON-RPC reportam a saúde do agente exatamente como um script integrado faz, então o watchdog vê um agente ocupado em vez de um agente mudo.

Um aluguel também consome uma vaga de dispositivo do seu plano.

Aluguéis expiram — 120 segundos por padrão, 600 no máximo. A biblioteca Python renova o seu em uma thread de fundo e o libera quando o bloco with termina, então um script que quebra libera o dispositivo em segundos em vez de segurá-lo até você reiniciar o app. Se você chamar a API diretamente, precisa enviar os heartbeats por conta própria.

Você vê todos os aluguéis ativos — e pode liberar um à força — em Configurações → Developer API → Sessões de dispositivo ativas.

Modos de plataforma​

Um script registrado declara o alvo:

Generic — o dispositivo é entregue intocado. Nenhum app é aberto, nenhuma troca de conta, nenhuma verificação de método de entrada e nada é fechado depois. Use para automatizar um app que o TikMatrix não controla por si mesmo.

TikTok / Instagram / Threads — o app é aberto e a conta certa é definida antes do seu programa começar, e o app é fechado ao terminar, exatamente como em um script integrado. TIKMATRIX_PACKAGE informa qual pacote foi resolvido. Use para acrescentar uma etapa que os scripts integrados não cobrem.

No Threads a mudança de conta vai através de Configurações → Trocar contas no aplicativo, e o nome de usuário na página de perfil é lido depois. Uma tarefa que nomeia uma conta diferente da que está conectada no dispositivo falha em vez de ser executada como a conta ativa.

Variáveis de ambiente​

Um script gerenciado recebe:

VariávelSignificado
TIKMATRIX_API_BASEURL do servidor, ex.: http://127.0.0.1:50809
TIKMATRIX_SESSION_IDO aluguel já mantido em seu nome
TIKMATRIX_SERIALO dispositivo para o qual esta tarefa foi despachada
TIKMATRIX_PACKAGEPacote do app resolvido
TIKMATRIX_PLATFORMtiktok, instagram, threads ou generic

TikMatrix.from_env() lê tudo isso por você.

Scripts autônomos não recebem nada disso — alugue um dispositivo explicitamente.

Tudo o que você colocar em Variáveis de ambiente extras é mesclado por cima, que é a forma usual de dar a um mesmo script registrado configurações por execução sem editar o arquivo.

Referência da biblioteca Python​

TikMatrix — a conexão​

ChamadaO que faz
TikMatrix(base_url=None, timeout=30.0)Conecta. Recorre a TIKMATRIX_API_BASE e depois a http://127.0.0.1:50809
client.devices()Dispositivos on-line, cada um com serial, real_serial e busy
client.sessions()Todos os aluguéis ativos, inclusive os de outros processos
client.device(serial, label=..., ttl_secs=120)Aluga um dispositivo e devolve um Device
TikMatrix.from_env()Adota o dispositivo com que um script gerenciado foi iniciado

Device — o telefone​

ChamadaO que faz
d.info()Informações do dispositivo pelo UIAutomator2
d.window_size()(largura, altura)
d.screenshot(path=None)Bytes PNG, opcionalmente gravados em path
d.hierarchy()A árvore de UI atual em XML
d.find(text=, resource_id=, description=, class_name=)Nós correspondentes, cada um com bounds e center
d.exists(**criteria)Se há alguma correspondência
d.wait_for(timeout=10.0, interval=1.0, **criteria)Bloqueia até aparecer e devolve o elemento
d.click(timeout=10.0, **criteria)Espera o elemento e toca no centro dele
d.click_xy(x, y)Toca em uma coordenada
d.swipe(sx, sy, ex, ey, steps=20)Desliza
d.press(key)back, home, recent, enter, …
d.input_text(text)Digita no campo em foco pelo IME rápido incluído
d.jsonrpc(method, params=None, timeout=10)Qualquer método do UIAutomator2
d.adb(*args, timeout_ms=None)Executa um comando ADB
d.release()Libera o aluguel. O with faz isso por você

O find casa contra a árvore de UI despejada, então quando um seletor erra você pode fazer print(d.hierarchy()) e ver exatamente o que foi pesquisado. O Inspetor de elementos na visão do dispositivo mostra a mesma árvore visualmente, o que costuma ser o jeito mais rápido de achar um resource-id.

input_text precisa de ADB

Ele envia um broadcast ao método de entrada incluído, o que passa por adb shell. Habilite o acesso ADB antes de usar, ou ele falha com 403.

Erros​

A biblioteca levanta duas exceções, ambas subclasses de RuntimeError:

ExceçãoQuando
DeviceBusyErrorHTTP 409 — o dispositivo já está alugado, ou o plano não tem vaga livre
TikMatrixErrorTodo o resto: plano insuficiente, aluguel expirado, ADB desabilitado, seletor que nunca casou
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("esse telefone está com outro processo — tente outro")
except TikMatrixError as exc:
print("falhou:", exc)

Em um script gerenciado, deixar a exceção escapar costuma ser o certo: a saída diferente de zero marca a tarefa como falha e o traceback vai para o log da tarefa.

Endpoints HTTP​

Operações de dispositivo precisam de um cabeçalho x-session-id nomeando um aluguel ativo. Não há chave de API: como o resto da API local, esses endpoints não são autenticados — conseguir alcançar a máquina na rede é o controle de acesso. Eles não enviam cabeçalhos CORS, então chame-os a partir de um programa (curl, Python, qualquer código de servidor) e não de uma página no navegador.

MétodoCaminhoFinalidade
GET/api/v1/rpc/devicesLista dispositivos on-line e se cada um está ocupado
POST/api/v1/rpc/sessionAluga um dispositivo → session_id
POST/api/v1/rpc/session/{id}/heartbeatEstende o aluguel
DELETE/api/v1/rpc/session/{id}Libera o aluguel
GET/api/v1/rpc/sessionLista os aluguéis ativos
POST/api/v1/rpc/jsonrpcChama um método do UIAutomator2
POST/api/v1/rpc/adbExecuta um comando ADB
GET/api/v1/rpc/hierarchy?serial=Árvore de UI atual em XML
GET/api/v1/rpc/screenshot?serial=Tela atual em PNG

As respostas JSON usam o mesmo envelope do resto da API local — {"code": 0, "message": "success", "data": ...}, com code diferente de zero em caso de falha. hierarchy e screenshot devolvem o corpo cru.

Exemplo​

# Alugar um dispositivo
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", ...}}

# Controlá-lo
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":[]}'

# Manter vivo enquanto trabalha
curl -X POST http://127.0.0.1:50809/api/v1/rpc/session/ff3ae079-.../heartbeat \
-H "Content-Type: application/json" \
-d '{"ttl_secs":120}'

# Devolvê-lo
curl -X DELETE http://127.0.0.1:50809/api/v1/rpc/session/ff3ae079-...

Erros​

StatusSignificado
403Plano abaixo de Pro, sem aluguel, aluguel expirado ou acesso ADB desabilitado
409Dispositivo já alugado, ou o plano não tem vaga livre

Escrever em outra linguagem​

Nada aqui é específico de Python. Qualquer runtime capaz de fazer uma requisição HTTP serve — o contrato do modo gerenciado é só "leia três variáveis de ambiente e saia com 0 em caso de sucesso".

// my_flow.js — registre com: 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"));

Se o interpretador não estiver no PATH, informe o caminho completo em Comando, ex.: C:/Program Files/nodejs/node.exe C:/scripts/my_flow.js.

Disparar um script personalizado pela API​

Scripts registrados também podem ser iniciados pela API de gerenciamento de tarefas, de modo que um script pode enfileirar trabalho subsequente:

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 é o id do script que você registrou.

Acesso ADB​

/api/v1/rpc/adb dá aos seus scripts um shell no dispositivo — você precisa dele para enviar mídia, instalar APKs e mudar configurações do sistema. Como é um shell completo em um endpoint sem chave de API, ele vem desligado. Ligue em Configurações → Developer API → Permitir comandos ADB quando tiver um script que precise dele; a automação de UI por /rpc/jsonrpc funciona sem ele.

Enquanto está desligado, /api/v1/rpc/adb responde 403 e o resto da API continua funcionando. Todo comando ADB que um script executa é gravado no seu arquivo de log.

Como escrever scripts que continuam funcionando​

  • Espere a tela, não durma por ela. d.wait_for(...) retorna assim que o elemento aparece; um sleep fixo é ou mais lento do que precisa ou curto demais num dia ruim.
  • Verifique antes de tocar. Um d.exists(...) num diálogo de consentimento ou num aviso de "agora não" custa um despejo da árvore e salva uma execução que, sem ele, tocaria no vazio.
  • Imprima o que você fez. No modo gerenciado, o stdout é o log da tarefa, e é o único registro de uma execução que ninguém acompanhou.
  • Torne a reexecução segura. Uma nova tentativa roda o programa inteiro de novo, então um script que publica deve checar se já publicou em vez de supor que começa do zero.
  • Um script, um trabalho. A concorrência é por dispositivo, então dez tarefas pequenas em dez telefones terminam muito antes do que um script percorrendo dez telefones em laço.

Notas e limites​

  • O comando é executado diretamente, não por um shell, então && e | são tratados como argumentos e não como operadores. Registre cmd /c "..." (Windows) ou sh -c "..." (macOS) se quiser comportamento de shell.
  • Coloque entre aspas caminhos com espaços: "C:/Program Files/Python/python.exe" my_script.py.
  • Um script que ultrapassa o tempo limite é encerrado e a tarefa é marcada como falha.
  • Um código de saída diferente de zero marca a tarefa como falha; tudo que o script escreve em stdout e stderr vai para o log da tarefa.
  • Scripts rodam com as mesmas permissões do próprio TikMatrix. Registre apenas programas que você escreveu ou em que confia.

Solução de problemas​

API access requires Pro or higher plan (403) A licença nesta máquina é Starter ou está inativa. Verifique Configurações → Licença.

Conexão recusada em 127.0.0.1:50809 O TikMatrix não está rodando, ou está rodando como outro usuário. O servidor só existe enquanto o app está aberto.

409 em toda tentativa de aluguel Ou o telefone está de fato ocupado — veja em Configurações → Developer API → Sessões de dispositivo ativas — ou todas as vagas de dispositivo do plano já estão tomadas por tarefas em execução.

O aluguel expira no meio de uma etapa longa O TTL padrão é 120 s e a biblioteca renova em segundo plano, então isso normalmente significa que o script bloqueou a thread principal por mais tempo que o TTL. Aumente ttl_secs (até 600) ou tire o trabalho longo dessa thread.

d.adb(...) falha com 403 O acesso ADB está desligado. Ligue em Configurações → Developer API → Permitir comandos ADB.

Um seletor nunca casa print(d.hierarchy()) mostra exatamente a árvore que o find pesquisou. O texto é comparado de forma exata, então um espaço a mais ou um rótulo traduzido é a causa mais comum; casar por resource_id é mais estável do que por text.

A tarefa é marcada como falha mas o telefone parece bem Leia o log da tarefa. Uma saída diferente de zero — inclusive uma exceção não tratada ao fim de uma execução bem-sucedida — reprova a tarefa mesmo que a automação em si tenha funcionado.

Próximos passos​