Ana içeriğe geç

Özel Betikler

Yerleşik betikler yaygın akışları kapsar. Onların sunmadığı bir şeye ihtiyaç duyduğunuzda — farklı sırada bir adım, hiç dokunmadıkları bir ekran ya da TikTok veya Instagram olmayan bir uygulama — bunu istediğiniz dilde kendiniz yazabilir ve telefonu TikMatrix'in size teslim etmesini sağlayabilirsiniz.

Gereksinimler

Lisans gereksinimi

Özel betikler Pro, Team veya Business planı gerektirir. Starter planının erişimi yoktur.

Planınızdaki cihaz sayısı aynı zamanda eşzamanlılık sınırıdır: Pro planı (20 cihaz) aynı anda 20 telefon sürebilir — ister yerleşik görevlerle, ister özel betiklerle, ister ikisinin karışımıyla.

Bir betiği çalıştırmanın iki yolu

Bağımsız

Programı siz çalıştırırsınız. TikMatrix yalnızca size cihaz ödünç verir.

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

Tek seferlik işler, veri toplama ve kendi zamanlayıcınızdan başlatmak istediğiniz her şey için uygundur.

Yönetilen

Programı TikMatrix'e kaydedersiniz ve o da diğerleri gibi bir göreve dönüşür. Görev kuyruğunu, plana göre eşzamanlılığı, otomatik yeniden denemeleri, görev günlüğünü ve zamanlama şablonlarını kazanır. TikMatrix programınızı başlatmadan önce cihazı kiralar ve kira kimliğini ortam değişkeniyle iletir.

from tikmatrix import TikMatrix

with TikMatrix.from_env() as d: # cihaz zaten kiralanmış durumda
d.click(text="Log in")
print("done") # bu satır görev günlüğüne düşer

Tekrar tekrar, zamanlanmış olarak veya çok sayıda cihazda çalıştırmak istediğiniz her şey için uygundur.

Hangisini seçmeli

BağımsızYönetilen
Kim başlatırSizTikMatrix görev kuyruğu
Cihaz kirasıSiz alırsınızBaşlangıçta zaten elinizde
Yeniden deneme, zamanlama, günlükKendiniz kurarsınızHazır gelir
Çok sayıda cihazda çalıştırmaDöngüyü siz yazarsınızCihaz başına bir görev, paralel dağıtılır
En uygun olduğu yerKeşif, tarayıcılar, tek seferlik işlerTekrarlamak istediğiniz her şey

Akışı oturtana kadar bağımsız modda başlayıp aynı dosyayı sonra yönetilen betik olarak kaydedebilirsiniz — değişen tek satır TikMatrix.from_env() olur.

Başlarken

1. İstemci kütüphanesini kurun

pip install requests

Ardından SDK dizinindeki tikmatrix.py dosyasını betiğinizin yanına kopyalayın. Kütüphane tek dosyadır ve başka bağımlılığı yoktur.

Onu kullanmak zorunda değilsiniz — API, HTTP üzerinden düz JSON'dur ve ham uç noktalar aşağıda belgelenmiştir.

2. Betiğinizi yazın

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 açıkken ve telefon bağlıyken çalıştırın. Cihaz bilgisi sözlüğünü yazdırıyorsa her şey yerli yerindedir.

3. Kaydedin (yalnızca yönetilen mod)

Cihazlar → Özel Betikler → Betik Ekle yolunu izleyin:

AlanAnlamı
AdBetik listesinde ve görev günlüğünde görünür
KomutÇalıştırılacak program satırı, ör. python C:/scripts/my_flow.py
Çalışma diziniİsteğe bağlı. Programın başladığı yer
PlatformAşağıdaki platform kiplerine bakın
Zaman aşımıBetiğin sonlandırılıp görevin başarısız sayılmasına kaç saniye kaldığı. Varsayılan 1800
Ek ortam değişkenleriProgramın ortamına eklenen isteğe bağlı JSON nesnesi
EtkinBir betiği silmeden kapatın. Devre dışı betik dağıtılamaz

Sonra betik satırındaki ▶ düğmesine basıp cihazlarınızı seçin — tıpkı yerleşik bir betikte olduğu gibi.

Yazma işini asistana bırakın

Yapay zekâ asistanı, gündelik dille yazılmış bir tarifden özel betik taslağı çıkarıp tek adımda kaydedebilir. Diske herhangi bir şey yazılmadan önce dosyanın tamamını size gösterir.

Cihaz kiraları

Bir telefonu aynı anda yalnızca bir şey sürebilir. Onu kiralamak TikMatrix'e cihazın meşgul olduğunu bildirir; böylece:

  • görev kuyruğu aynı ekrana görev göndermez ve
  • JSON-RPC çağrılarınız, yerleşik bir betiğin yaptığı gibi ajan sağlığını bildirir; bekçi süreç sessiz bir ajan yerine meşgul bir ajan görür.

Kira aynı zamanda planınızdan bir cihaz yuvası tüketir.

Kiralar sona erer — varsayılan 120 saniye, en fazla 600. Python kütüphanesi kiranızı arka planda bir iş parçacığında yeniler ve with bloğu bitince serbest bırakır; böylece çöken bir betik cihazı uygulamayı yeniden başlatana kadar tutmak yerine saniyeler içinde bırakır. API'yi doğrudan çağırıyorsanız kalp atışlarını kendiniz göndermelisiniz.

Tüm canlı kiraları Ayarlar → Developer API → Etkin cihaz oturumları altında görebilir ve zorla serbest bırakabilirsiniz.

Platform kipleri

Kayıtlı bir betik neyi hedeflediğini bildirir:

Generic — cihaz olduğu gibi teslim edilir. Hiçbir uygulama açılmaz, hesap değiştirilmez, giriş yöntemi denetlenmez ve iş bitince hiçbir şey kapatılmaz. TikTok veya Instagram dışındaki her şeyi otomatikleştirmek için bunu kullanın.

TikTok / Instagram — programınız başlamadan önce uygulama açılır ve hesap değiştirilir, iş bitince uygulama kapatılır; tıpkı yerleşik bir betikte olduğu gibi. TIKMATRIX_PACKAGE hangi paketin seçildiğini söyler. Yerleşik betiklerin kapsamadığı bir adım eklemek için bunu kullanın.

Ortam değişkenleri

Yönetilen bir betik şunları alır:

DeğişkenAnlamı
TIKMATRIX_API_BASESunucu URL'si, ör. http://127.0.0.1:50809
TIKMATRIX_SESSION_IDSizin adınıza hâlihazırda tutulan kira
TIKMATRIX_SERIALBu görevin gönderildiği cihaz
TIKMATRIX_PACKAGEÇözümlenen uygulama paketi
TIKMATRIX_PLATFORMtiktok, instagram veya generic

TikMatrix.from_env() bunların hepsini sizin için okur.

Bağımsız betikler bunların hiçbirini almaz — bunun yerine cihazı açıkça kiralayın.

Ek ortam değişkenleri alanına koyduğunuz her şey bunların üzerine eklenir; bu, kayıtlı tek bir betiğe dosyayı düzenlemeden çalıştırmaya özgü ayarlar vermenin alışılmış yoludur.

Python kütüphanesi başvurusu

TikMatrix — bağlantı

ÇağrıNe yapar
TikMatrix(base_url=None, timeout=30.0)Bağlanır. Sırasıyla TIKMATRIX_API_BASE ve http://127.0.0.1:50809 değerlerine düşer
client.devices()Çevrimiçi cihazlar; her biri serial, real_serial ve busy ile
client.sessions()Bu sürece ait olmayanlar dahil tüm canlı kiralar
client.device(serial, label=..., ttl_secs=120)Bir cihaz kiralar ve Device döndürür
TikMatrix.from_env()Yönetilen bir betiğin birlikte başlatıldığı cihazı devralır

Device — telefon

ÇağrıNe yapar
d.info()UIAutomator2 cihaz bilgisi
d.window_size()(genişlik, yükseklik)
d.screenshot(path=None)PNG baytları, istenirse path yoluna yazılır
d.hierarchy()Geçerli arayüz ağacı, XML olarak
d.find(text=, resource_id=, description=, class_name=)Eşleşen düğümler; her biri bounds ve center ile
d.exists(**criteria)Eşleşen bir şey var mı
d.wait_for(timeout=10.0, interval=1.0, **criteria)Belirene kadar bekler, sonra döndürür
d.click(timeout=10.0, **criteria)Öğeyi bekler, sonra merkezine dokunur
d.click_xy(x, y)Bir koordinata dokunur
d.swipe(sx, sy, ex, ey, steps=20)Kaydırır
d.press(key)back, home, recent, enter, …
d.input_text(text)Birlikte gelen hızlı giriş yöntemiyle odaktaki alana yazar
d.jsonrpc(method, params=None, timeout=10)Herhangi bir UIAutomator2 yöntemi
d.adb(*args, timeout_ms=None)Bir ADB komutu çalıştırır
d.release()Kirayı bırakır. with bunu sizin için yapar

find, dökülen arayüz ağacı üzerinde eşleştirme yapar; bu yüzden bir seçici ıskaladığında print(d.hierarchy()) diyerek tam olarak neyin arandığını görebilirsiniz. Cihaz görünümündeki Öğe Denetçisi aynı ağacı görsel olarak gösterir ve genellikle bir resource-id bulmanın en hızlı yoludur.

input_text ADB gerektirir

Birlikte gelen giriş yöntemine adb shell üzerinden bir yayın gönderir. Kullanmadan önce ADB erişimini açın; aksi hâlde 403 ile başarısız olur.

Hatalar

Kütüphane iki istisna fırlatır; her ikisi de RuntimeError alt sınıfıdır:

İstisnaNe zaman
DeviceBusyErrorHTTP 409 — cihaz zaten kiralanmış ya da planınızda boş cihaz yuvası yok
TikMatrixErrorGeri kalan her şey: plan yetersiz, kira süresi dolmuş, ADB kapalı, seçici hiç eşleşmedi
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("o telefonu başkası kullanıyor — başkasını deneyin")
except TikMatrixError as exc:
print("başarısız:", exc)

Yönetilen bir betikte istisnanın dışarı sızmasına izin vermek genellikle doğru olandır: sıfır olmayan çıkış kodu görevi başarısız işaretler ve yığın izi görev günlüğüne düşer.

HTTP uç noktaları

Cihaz işlemleri, canlı bir kirayı belirten x-session-id başlığı gerektirir. API anahtarı yoktur: yerel API'nin geri kalanı gibi bu uç noktalar da kimlik doğrulaması yapmaz — makineye ağ üzerinden ulaşabilmek erişim denetiminin ta kendisidir. CORS başlığı göndermezler, bu yüzden onları tarayıcıdaki bir sayfadan değil bir programdan (curl, Python, herhangi bir sunucu tarafı kod) çağırın.

YöntemYolAmaç
GET/api/v1/rpc/devicesÇevrimiçi cihazları ve meşgul olup olmadıklarını listeler
POST/api/v1/rpc/sessionCihaz kiralar → session_id
POST/api/v1/rpc/session/{id}/heartbeatKirayı uzatır
DELETE/api/v1/rpc/session/{id}Kirayı bırakır
GET/api/v1/rpc/sessionCanlı kiraları listeler
POST/api/v1/rpc/jsonrpcBir UIAutomator2 yöntemi çağırır
POST/api/v1/rpc/adbBir ADB komutu çalıştırır
GET/api/v1/rpc/hierarchy?serial=Geçerli arayüz ağacı, XML olarak
GET/api/v1/rpc/screenshot?serial=Geçerli ekran, PNG olarak

JSON yanıtları yerel API'nin geri kalanıyla aynı zarfı kullanır — {"code": 0, "message": "success", "data": ...}, başarısızlıkta code sıfırdan farklıdır. hierarchy ve screenshot ise ham gövdeyi döndürür.

Örnek

# Cihaz kirala
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", ...}}

# Cihazı sür
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":[]}'

# Çalışırken kirayı canlı tut
curl -X POST http://127.0.0.1:50809/api/v1/rpc/session/ff3ae079-.../heartbeat \
-H "Content-Type: application/json" \
-d '{"ttl_secs":120}'

# Geri ver
curl -X DELETE http://127.0.0.1:50809/api/v1/rpc/session/ff3ae079-...

Hatalar

DurumAnlamı
403Plan Pro'nun altında, kira yok, kira süresi dolmuş veya ADB erişimi kapalı
409Cihaz zaten kiralanmış ya da planınızda boş cihaz yuvası yok

Başka bir dilde yazmak

Burada Python'a özgü hiçbir şey yok. HTTP isteği yapabilen her çalışma zamanı işe yarar — yönetilen modun sözleşmesi yalnızca şudur: "üç ortam değişkenini oku, başarıda 0 ile çık".

// my_flow.js — şununla kaydedin: 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"));

Yorumlayıcı PATH içinde değilse Komut alanına tam yolunu yazın, ör. C:/Program Files/nodejs/node.exe C:/scripts/my_flow.js.

Özel betiği API'den tetiklemek

Kayıtlı betikler Görev Yönetimi API'si üzerinden de başlatılabilir; böylece bir betik ardından gelecek işi kuyruğa alabilir:

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, kaydettiğiniz betiğin kimliğidir.

ADB erişimi

/api/v1/rpc/adb, betiklerinize cihaz üzerinde bir kabuk verir — medya göndermek, APK kurmak ve sistem ayarlarını değiştirmek için gereklidir. API anahtarı olmayan bir uç nokta üzerinde tam bir kabuk olduğu için kapalı olarak gelir. Buna ihtiyaç duyan bir betiğiniz olduğunda Ayarlar → Developer API → ADB komutlarına izin ver altından açın; /rpc/jsonrpc üzerinden arayüz otomasyonu bu olmadan da çalışır.

Kapalıyken /api/v1/rpc/adb 403 döner ve API'nin geri kalanı çalışmayı sürdürür. Bir betiğin çalıştırdığı her ADB komutu günlük dosyanıza yazılır.

Çalışmayı sürdüren betikler yazmak

  • Ekranı bekleyin, onun için uyumayın. d.wait_for(...) öğe belirir belirmez döner; sabit bir uyku ya gereğinden yavaştır ya da kötü bir günde fazla kısa kalır.
  • Dokunmadan önce denetleyin. Bir onay kutusunda veya "şimdi değil" uyarısında yapılan d.exists(...) çağrısının bedeli tek bir ağaç dökümüdür ve aksi hâlde boşluğa dokunacak bir çalıştırmayı kurtarır.
  • Ne yaptığınızı yazdırın. Yönetilen modda stdout görev günlüğüdür ve kimsenin izlemediği bir çalıştırmanın tek kaydıdır.
  • Yeniden çalıştırmayı güvenli kılın. Yeniden deneme programın tamamını baştan çalıştırır; bu yüzden gönderi paylaşan bir betik sıfırdan başladığını varsaymak yerine zaten paylaşıp paylaşmadığını denetlemelidir.
  • Bir betik bir iş. Eşzamanlılık cihaz başınadır; on telefonda on küçük görev, on telefonu döngüyle gezen tek bir betikten çok daha erken biter.

Notlar ve sınırlar

  • Komut doğrudan çalıştırılır, kabuk üzerinden değil; bu yüzden && ve | işleç değil bağımsız değişken sayılır. Kabuk davranışı istiyorsanız cmd /c "..." (Windows) veya sh -c "..." (macOS) kaydedin.
  • Boşluk içeren yolları tırnak içine alın: "C:/Program Files/Python/python.exe" my_script.py.
  • Zaman aşımını aşan bir betik sonlandırılır ve görev başarısız işaretlenir.
  • Sıfırdan farklı çıkış kodu görevi başarısız işaretler; betiğin stdout ve stderr'e yazdığı her şey görev günlüğüne düşer.
  • Betikler TikMatrix'in kendisiyle aynı izinlerle çalışır. Yalnızca kendi yazdığınız veya güvendiğiniz programları kaydedin.

Sorun giderme

API access requires Pro or higher plan (403) Bu makinedeki lisans Starter ya da etkin değil. Ayarlar → Lisans bölümünü denetleyin.

127.0.0.1:50809 üzerinde bağlantı reddedildi TikMatrix çalışmıyor ya da başka bir kullanıcı olarak çalışıyor. Sunucu yalnızca uygulama açıkken vardır.

Her kira denemesinde 409 Ya telefon gerçekten meşguldür — Ayarlar → Developer API → Etkin cihaz oturumları bölümüne bakın — ya da planınızdaki tüm cihaz yuvaları çalışan görevlerce doludur.

Kira uzun bir adımın ortasında sona eriyor Varsayılan TTL 120 saniyedir ve kütüphane onu arka planda yeniler; dolayısıyla bu genellikle betiğin ana iş parçacığını TTL'den uzun süre bloke ettiği anlamına gelir. ttl_secs değerini yükseltin (en fazla 600) ya da uzun süren işi o iş parçacığından çıkarın.

d.adb(...) 403 ile başarısız oluyor ADB erişimi kapalı. Ayarlar → Developer API → ADB komutlarına izin ver altından açın.

Bir seçici hiç eşleşmiyor print(d.hierarchy()), find işlevinin aradığı ağacın tam olarak kendisini gösterir. Metin birebir eşleştirilir; bu yüzden sondaki fazladan bir boşluk ya da yerelleştirilmiş bir etiket en sık rastlanan nedendir. resource_id ile eşleştirmek text ile eşleştirmekten daha kararlıdır.

Görev başarısız işaretlenmiş ama telefon iyi görünüyor Görev günlüğünü okuyun. Sıfırdan farklı bir çıkış — başarılı bir çalıştırmanın sonundaki yakalanmamış bir istisna dahil — otomasyonun kendisi işlemiş olsa bile görevi başarısız kılar.

Sonraki adımlar