⚡ Mission Control

⚙️ Procesos activos

No hay procesos activos

Dashboard

Resumen operativo en tiempo real

Total Phones 📱
0
modelos
Active IG 🟢
0
% del total
Con Link 🔗
0
de las activas
Errores / Dead 💀
0

📊 Resumen por Modelo

Modelo Total Activas Con Link Con Bio Muertas
TOTAL

🔌 Servicios

Server
GeeLark API Connected
FactoryM Connected
WhatsApp Active
Bouncy.ai Active

🚨 Errores recientes

✓ Sin errores

📋 Actividad reciente

Sin actividad

📱 Granja IG

Total
0
modelos
🟢 Activos
0
% con IG activo
📸 Con IG
0
mapeadas
⏳ Pendientes
0
@ por resolver
✅ Verificados
0
story-ready
❌ Sin IG
0
no instalado
🔌 ADB Offline
0
server caído
⚠️ Sin mapear
0
sin datos
seleccionados
📱
Cargando phones...
Phone Modelo Cuenta IG Estado 📝 🔗 Followers Lang Error Acciones

Selecciona phones para Multivista

➕ Crear Phones

🚫
Sin Proxy
LAN / Local
👑
ProxyEmpire
Auto + Sticky
✏️
Manual
Tus proxies
👑 ProxyEmpire — Residencial SOCKS5 · Sticky session · Auto-generado
Se generaran proxies unicos al crear los phones
Formato: protocolo://usuario:password@host:puerto
Resumen
Phones:
Nombre:
Region:
Proxy:
Grupo:
Creando phones...


      
      
creados errores

📸 Story Manager

Publicar IG Stories con link sticker via ADB

+
Nuevo modelo
📸
Selecciona un modelo para empezar
O crea uno nuevo con el botón +

📜 Historial de publicaciones

FechaModeloCuentasOKFailedLink
📂

Content Library

root /

Cargando...

📅 Programación diaria por modelo

Activos: Colas: items
Cargando...
No hay modelos configurados

📂 Stories Media

Media para stories — fotos y videos sin comprimir

📁 Nombre:
📥
Soltar archivos aquí
Cargando...
📂
Carpeta vacía
Sube archivos o crea subcarpetas

📚 Docs

Documentación completa del proyecto Cupido Elite — Granja IG

Arquitectura del Sistema

┌──────────────────────────────────────────────────────────────────────────────────────────┐
│                          MISSION CONTROL (localhost:9999)                                │
│  ┌─────────┐ ┌────────┐ ┌─────────┐ ┌──────────┐ ┌──────────┐ ┌─────────┐ ┌──────────┐ │
│  │Dashboard│ │ Phones │ │ Stories │ │Cookie Fix│ │Link Mgr  │ │ Cerebro │ │Publisher │ │
│  │  KPIs   │ │Grid/Ops│ │ Publish │ │ Cookies  │ │ Bio Link │ │AI Brain │ │Reel/Post │ │
│  └─────────┘ └────────┘ └─────────┘ └──────────┘ └──────────┘ └─────────┘ └──────────┘ │
│  ┌──────────┐ ┌──────────┐ ┌──────────┐                                                │
│  │ Account  │ │ CAPTCHA  │ │ Profile  │                                                │
│  │ Creator  │ │ Solver   │ │ Editor   │                                                │
│  └──────────┘ └──────────┘ └──────────┘                                                │
│                      mc_server.py (Python http.server)                                  │
│        Proxy: /proxy/geelark/*    Skills: subprocess    DB: data/mc.db                  │
└──────────┬──────────────────────┬───────────────────────┬───────────────────┬────────────┘
           │                      │                       │                   │
           ▼                      ▼                       ▼                   ▼
  ┌─────────────────┐  ┌──────────────────┐  ┌─────────────────────────┐  ┌──────────────┐
  │  GeeLark API    │  │  FactoryM API    │  │  Skills (subprocess)    │  │External APIs │
  │  openapi.gee…   │  │  factorym.io     │  │  ig-profile-checker     │  │  SMSPool     │
  │  Bearer Token   │  │  Bearer Token    │  │  geelark-story-publisher│  │  2captcha    │
  └────────┬────────┘  └──────────────────┘  │  ig-cookie-accepter     │  └──────────────┘
           │                                  │  ig-link-manager        │
           ▼                                  │  ig-account-creator     │
  ┌──────────────────────────────────────┐    │  ig-captcha-solver      │
  │   GeeLark Cloud Phones (~100)       │    │  ig-profile-editor      │
  │  ┌──────┐ ┌───────┐ ┌──────┐       │    └─────────────────────────┘
  │  │Luna  │ │Natalia│ │Emma  │  …    │
  │  └──┬───┘ └───┬───┘ └──┬───┘       │
  │     └─────────┴────────┘            │
  │   ADB over TCP (ip:port + glogin)   │
  └──────────────────┬──────────────────┘
                     │
                     ▼
             ┌──────────────────┐
             │   Instagram      │
             │  Stories / Bio   │
             │  Cookies / Scan  │
             │  Accounts/CAPTCHA│
             └──────────────────┘

Flujo de datos

Mission Control UI → fetch() → mc_server.py (localhost:9999)

mc_server.py → proxy → GeeLark API (evita CORS del browser)

mc_server.py → subprocess → skills/*/scripts/*.py (jobs en background thread)

Skills → ADB TCP → Cloud phones → Instagram

Account Creator / CAPTCHA SolverSMSPool (números SMS) + 2captcha (resolución CAPTCHA)

• Configs (*_accounts.json) en data/accounts/, leídos/escritos por mc_server.py y los skills

• Registry global en data/phones_registry.json — estado de todos los phones

• Base de datos SQLite en data/mc.db — tablas: ig_accounts, publish_tasks

Estructura de archivos

MissionControlPhones/
├── mc_server.py          ← Servidor principal (puerto 9999)
├── config.py             ← Carga credenciales desde .env
├── start.sh              ← Script de arranque
├── index.html            ← Frontend (panel)
├── data/
│   ├── accounts/         ← *_accounts.json por modelo
│   ├── mc.db             ← SQLite: ig_accounts, publish_tasks
│   ├── phones_registry.json
│   ├── story_configs.json
│   ├── publish_history.json
│   ├── phone_errors.json
│   └── agents_status.json
├── scripts/              ← Utilidades standalone
│   ├── scan_model.py
│   ├── map_all_accounts.py
│   ├── publish_story_api.py
│   └── update_status.py
├── skills/               ← Automatizaciones ADB
│   ├── ig-profile-checker/scripts/check_profile.py
│   ├── geelark-story-publisher/scripts/
│   │   ├── publish_story_v2.py   (archivado)
│   │   └── publish_story_v4_human.py  ← activo
│   ├── ig-cookie-accepter/scripts/accept_cookies_v2.py
│   ├── ig-link-manager/scripts/set_link_v2_threaded.py
│   ├── ig-account-creator/scripts/create_account.py
│   ├── ig-captcha-solver/scripts/solve_captcha.py
│   └── ig-profile-editor/scripts/edit_profile.py
└── content/              ← Imágenes/videos para stories
    ├── Luna/
    ├── Natalia/
    └── ...

API Endpoints — mc_server.py

Todos los endpoints servidos en http://localhost:9999

Estado / Info

MethodPathDescripciónResponse clave
GET/api/statusHealth check + uptime{status, uptime, uptime_fmt}
GET/api/phones/fullLista phones con datos de scan del registry{phones: [{id, name, ig, model, ...}]}
GET/api/phonesConfigs por modelo (de data/accounts/)[{model, accounts, ...}]
GET/api/configsResumen de todos los *_accounts.json[{file, model, totalAccounts, verifiedAccounts, ...}]
GET/api/config/:modelConfig completo de un modeloContenido de data/accounts/<model>_accounts.json
GET/api/scan/resultsResultados del último scan{results: [...]}
GET/api/publish/historyHistorial de publicaciones[{timestamp, model, total, success, failed, link}]

Phones

MethodPathDescripción
POST/api/phones/syncSincroniza lista de phones desde GeeLark API
POST/api/phones/stopallPara todos los phones encendidos (emergencia)
POST/api/phones/deleteElimina phone de GeeLark + FactoryM + config local

Scan IG

MethodPathDescripción
POST/api/phone/scanLanza scan de perfil IG individual — body: {phoneId}
POST/api/phone/scan/statusEstado del scan individual — body: {jobId}
GET/api/phone/scan/activeLista scans individuales activos
POST/api/phone/scan/bulkScan masivo de un modelo — body: {model, ...}
GET/api/phone/scan/bulk/statusEstado del scan masivo — query: ?jobId=…
GET/api/phone/scan/bulk/activeLista scans masivos activos
POST/api/phone/scan/bulk/cancelCancela scan masivo — body: {jobId}

Acciones IG

MethodPathDescripción
POST/api/publish/startLanza job de publicación de story
GET/api/publish/statusEstado del job de publicación — query: ?jobId=…
POST/api/cookies/acceptLanza aceptación de cookies en phones
GET/api/cookies/statusEstado del job de cookies
GET/api/cookies/activeLista cookie jobs activos
POST/api/linkbio/startLanza set de link en bio
GET/api/linkbio/statusEstado del job de link bio
GET/api/linkbio/activeLista link bio jobs activos

Profile Editor

MethodPathDescripción
POST/api/profile/startInicia job de edición de perfil — body: {model, field, value, target, phones, ...}
POST/api/profile/statusEstado del job — body: {jobId}
POST/api/profile/cancelCancela job de edición — body: {jobId}
GET/api/profile/activeLista profile jobs activos

CAPTCHA Solver

MethodPathDescripción
POST/api/captcha/startInicia resolución CAPTCHA — body: {phoneId, phoneName, twocaptchaKey?, smsKey?, country?}
POST/api/captcha/statusEstado del job — body: {jobId} → {status, output, step, totalSteps, result?}
POST/api/captcha/cancelCancela job y para el phone — body: {jobId}

Account Creator

MethodPathDescripción
POST/api/accounts/startInicia job de creación de cuenta — body: {phoneId, phoneName, fullName, username, password, smsMode, ...}
POST/api/accounts/statusEstado del job — body: {jobId} → {status, output, step, waitingFor, result}
POST/api/accounts/cancelCancela job — body: {jobId}
POST/api/accounts/provide_inputEnvía número o código SMS al script — body: {jobId, input}
POST/api/accounts/resend_smsSeñaliza reenvío SMS — body: {jobId}
POST/api/accounts/hero-balanceConsulta saldo SMSPool

SMSPool

MethodPathDescripción
POST/api/smspool/get_numberPide número temporal a SMSPool desde el panel
POST/api/smspool/poll_codeComprobación única del código SMS (no bloqueante, 3s entre llamadas)
POST/api/smspool/cancelCancela orden SMSPool activa

Base de Datos

MethodPathDescripción
POST/api/db/statsKPIs: total cuentas, creadas, errores, hoy, tasa de éxito
POST/api/db/accountsLista cuentas con filtros (search, status, offset, limit)
POST/api/db/accounts/updateEdita campos de una cuenta por ID
POST/api/db/accounts/deleteElimina una cuenta por ID

Contenido

MethodPathDescripción
GET/api/content/listLista archivos en content/ con estructura por carpeta
POST/api/content/uploadSube archivo a content/ — multipart/form-data
POST/api/content/mkdirCrea carpeta en content/ — body: {path}
POST/api/content/deleteElimina archivo de content/ — body: {path}
PROXY/proxy/geelark/*Proxy POST a GeeLark API (evita CORS del browser)
GET/sseServer-Sent Events para integración MCP con Claude Code

POST /api/publish/start — Parámetros

CampoTipoRequeridoDescripción
modelstringNombre del modelo (lee data/accounts/<model>_accounts.json)
mediastringRuta al archivo de imagen/video (ej: content/Luna/IMG_4506.PNG)
linkstringURL para link sticker
stickerTextstringTexto del sticker (ej: "Free Today!!")
targetstringverified|all|failed|selected (default: verified)
phonesstringIDs separados por coma (para target=selected)
skipLinkboolPublicar sin link sticker
dryRunboolSolo chequear conexiones sin publicar
bootWaitintSegundos espera tras boot (default 30)
workersintWorkers paralelos (default 3)
screenshotsboolGuardar screenshot post-publish
keepRunningboolNo parar phones después

Story Publisher — Flujo Completo

Script: publish_story_api.py — Publica stories con link sticker via ADB en phones GeeLark

1Check Phone Status

Lista phones via GeeLark API /phone/list, identifica cuáles necesitan arrancar

2Start Phones

Arranca phones parados via /phone/start, espera boot-wait (default 30s)

3Enable ADB + Connect

/adb/setStatus/adb/getDataadb connect ip:portglogin pwd

4Push Media + Launch Editor

adb push imagen → MEDIA_SCANNER_SCAN_FILEam start ADD_TO_STORY intent

5Find Sticker Tray

3 estrategias: S1 Coords guardadas → S2 content-desc="Stickers" → S3 Toolbar icons derecha

6Enter Link + Sticker Text

Tap Link → EditText → input text URL → segundo EditText para sticker text → Done

7Publish + Cleanup

Tap "Your story"/"Tu historia" → screenshot (opcional) → rm media → stop phone (save credits)

Retry Logic

max_retries=2 — si no encuentra LINK sticker, vuelve atrás y reintenta

• Cada retry: force-stop IG → relanzar story editor → espera 22s (más que intento inicial)

• Si todos los retries fallan → fallback: publica SIN link sticker

• Detección de restricción: si IG muestra "You need more followers" → marca como restricted y para

• Coords exitosas se guardan en config para acelerar próximas ejecuciones

Sticker Strategies (3 niveles)

EstrategiaCómo funcionaCuándo se usa
S1 — Saved CoordsUsa stickerCoords + linkStickerCoords del configSi hay coords de éxito previo
S2 — Content DescBusca content-desc="Stickers"/"Pegatinas" en UI XMLFallback si S1 falla
S3 — Toolbar IconsPrueba todos los NAF clickable icons en toolbar derechaÚltimo recurso, itera hasta 5 botones
📸

publish_story_v2.py

skills/geelark-story-publisher/scripts/publish_story_v2.py

✅ Probado OK

Publica una story en Instagram con link sticker y texto personalizado. Soporta múltiples phones en paralelo. Usa agent-device para árbol de accesibilidad con fallback a uiautomator XML + coordenadas para phones 720x1440.

Uso

python3 publish_story_v2.py \
  --phones <ids_separados_por_coma | group:NombreModelo> \
  --media content/Natalia/12334.jpg \
  --link clickmysocials.com/nataliapariish \
  --link-text "Gratis Hoy!!" \
  [--skip-link] [--dry-run]

Comportamiento por resolución

ResoluciónADD_TO_STORY intentagent-deviceMétodoEstado
1080x2340 Abre cámara sin imagen ✅ Funciona agent-device (árbol accesibilidad) OK
720x1440 Abre editor con imagen ❌ Árbol vacío uiautomator XML + coordenadas OK

Toolbar derecho — coordenadas en phones 720x1440

IconoPosición
Aa (Texto)x=94%, y=4%
Sticker ⭐x=94%, y=8–22% (loop)
Música 🎵x=94%, y=15%
Dibujo ✏️x=94%, y=17%

⚠️ Comportamiento conocido

La posición del sticker varía según versión de IG

El código prueba y=8%→13%→18%→22% en loop

Detecta panel Aa por text_overlay / font_option en XML

NO usar nombres de fuente ("Modern","Classic") → falsos positivos

Fallbacks activos para 720x1440

PasoFallback
Detectar editor abiertouiautomator dump → busca "Your story / Add a caption / Tu historia"
Icono stickeruiautomator content-desc "Add sticker" → loop coordenadas y=8%→13%→18%→22% hasta que no se detecte panel Aa
Link Sticker en tray1) tap directo text/desc "Link Sticker/Link/LINK" → 2) buscar "link" en search bar del tray (evita que teclado tape los stickers) → 3) scroll + último intento
Campo URLSi url_node=None → tap EditText via uiautomator → input text ADB
Texto del stickerinput text ADB directo
Botón Doneuiautomator text="Done" → KEYCODE_BACK
Botón "Your story"uiautomator text="Your story / Your Story / Tu historia"
Verificación post-publishuiautomator busca story ring, feed, "Stories archive" popup
⛔ Abortar si no hay linkSi se pidió link pero no se pudo añadir → force-stop IG → FAILED (nunca publica sin link)

Conexión ADB — tiempos y reintentos

Boot wait

28s

tras /phone/start

ADB wait

8s

tras /adb/setStatus

getData reintentos

8×15s

≈1.75 min de margen

📦 Archivado — sustituido por v4

v2 se mantiene en scripts/archive/ como fallback. El servidor usa publish_story_v4_human.py para todos los modelos.

🧵

publish_story_v3_threaded.py

skills/geelark-story-publisher/scripts/publish_story_v3_threaded.py

📦 Archivado

Sustituido por v4. Disponible en scripts/archive/ como fallback. Versión con threading de v2 sin human behavior.

Uso

python3 publish_story_v3_threaded.py \
  --phones <ids_separados_por_coma | group:NombreModelo> \
  --media content/Lucia/foto.jpg \
  --link https://myotherprofiles.com/luciii \
  --link-text "Gratis Hoy!!🤗" \
  [--skip-link] [--dry-run]

Fixes añadidos en v3 (2026-02-27)

FixDescripción
Gallery early-return Tras tap de galería, comprueba _has_editor() antes de intentar tap de foto. Si el editor ya está abierto, retorna inmediatamente. Evita que taps en banners/ImageView incorrectos rompan el estado del editor.
Sticker tray retry Si el tray no se detecta tras el primer tap, reintenta en y=25%→28%→32%→35%→40%. Detecta y cierra panel Aa (text_overlay/font_option) en cada intento.
Sesión expirada Si el editor nunca abre y el XML contiene Forgot password / log_in_buttonFAILED: Instagram session expired. Phones con sesión expirada se eliminan via /api/phones/delete.
Text editor al inicio Si IG arranca con panel de texto activo (text_overlay/font_option en XML), cierra con KEYCODE_BACK antes de navegar a galería.
Popup story-to-story Modal "Introducing story-to-story sharing" bloquea el toolbar. Se detecta por Introducing / View settings en XML y se descarta tapeando "OK".
Emoji en sticker text adb input text no soporta emojis (chars 4-byte UTF-8). Cadena de fallback:
1) fill_ref via agent-device (soporta Unicode completo)
2) Si nodos vacíos → tap EditText via uiautomator + re-snap + fill_ref
3) Si re-snap vacío (720x1440) → ADB sin emoji (re.sub([^\x00-\x7F]))

Comportamiento por resolución (igual que v2)

ResoluciónADD_TO_STORY intentagent-deviceEstado
1080x2340 Abre cámara → gallery tap (43,1144) → editor abierto ✅ Funciona OK
720x1440 Abre editor con imagen directamente ❌ Árbol vacío OK (uiautomator)
🧠

publish_story_v4_human.py

skills/geelark-story-publisher/scripts/publish_story_v4_human.py

✅ Probado OK — 6/6 Luna

v3 + human behavior anti-detección: delays variables, jitter en taps, tipeo por chunks, nombre de archivo tipo cámara, micro-pausas. Activo para Luna. Mantiene threading.

Uso

python3 publish_story_v4_human.py \
  --phones <ids_separados_por_coma | group:NombreModelo> \
  --media content/Luna/foto.jpg \
  --link clickmysocials.com/lunaa \
  --link-text "Free Today!!" \
  [--skip-link] [--dry-run]

Cambios anti-detección respecto a v3

HelperComportamientoImpacto
_sleep(base) Cada espera = base × uniform(0.65, 1.35) — varía ±35% 🔴 Alto
_tap(x, y) Jitter ±5px en todas las coordenadas (dedo humano impreciso) 🔴 Alto
_type(text) Tipeo en chunks 2–5 chars con 80–200ms entre cada uno 🔴 Alto
ui_tap() Jitter ±4px inline en bounds calculados de uiautomator 🟡 Medio
_pause() Micro-pausa 0.4–1.4s antes de: sticker icon, link sticker, URL, texto del sticker 🟡 Medio
Nombre media IMG_YYYYMMDD_HHMMSS.JPG en DCIM/Camera/ (timestamp real de cámara) 🟡 Medio
Swipe velocidad Duración aleatoria randint(320, 550)ms en scroll del sticker tray 🟢 Bajo

✅ Resultado del primer run — Luna (2026-02-27)

6/6 stories publicadas. Threading paralelo: Luna7/8/11 publicando mientras Luna10/12/13 aún conectaban ADB. Luna8 encontró sticker via scroll tras 4 intentos fallidos en el toolbar — se resolvió automáticamente.

🔍

check_profile.py

skills/ig-profile-checker/scripts/check_profile.py

✅ Probado OK

Escanea el perfil de Instagram de un phone: detecta username, followers, posts, link en bio, idioma, foto de perfil. Escribe resultados en data/accounts/*_accounts.json.

python3 check_profile.py --phone <phoneId> [--model NombreModelo]
🍪

accept_cookies_v2.py

skills/ig-cookie-accepter/scripts/accept_cookies_v2.py

✅ Probado OK

Acepta automáticamente el popup de cookies de Instagram al abrir la app por primera vez o tras actualizaciones.

python3 accept_cookies_v2.py --phone <phoneId>
🔗

set_link_v2_threaded.py (activo)

skills/ig-link-manager/scripts/set_link_v2_threaded.py

✅ Activo

Establece el link en bio de Instagram. Threading: cada phone corre en paralelo. Corrige bug crítico de v1 (cmd /c Windows-only que rompía agent-device en macOS).

python3 set_link_v2_threaded.py --phones <id1,id2,...> --link <url> --batch 3
Cambiov1v2
agent-devicecmd /c (Windows-only → roto en macOS)subprocess directo (macOS ✓)
Boot wait55s28s
ADB retry7 × 10s8 × 15s
ThreadingSecuencialThreadPoolExecutor(max_workers=batch)
URL inputADB input textagent-device fill → ADB fallback
Columna VerifiedMostraba r.screenshotMuestra r.verified (✅/⚠️/—)
Done button (save)BACK si no se encuentra → descarta la URLCoordinate tap escalada → guarda siempre
ResoluciónCoordenadas hardcoded 720×1440 → falla en otras resolucioneswm size + _scale() auto-escalado ✓
XML node matching<node[^/]/> solo self-closing → no encuentra "Add link" (nodo contenedor)<node\s[^>]*> + filtro clickable="true"
URL EditTextRetornaba primer EditText en orden XML → podía ser campo Title (y=806)Retorna EditText con menor y (topmost = campo URL) + sanity check 35%

Navegación multi-resolución — coordenadas auto-escaladas

El script detecta adb shell wm size y escala todas las coordenadas con _scale(x, y, base=720×1440). agent-device devuelve árbol vacío en todas las resoluciones probadas.

PasoMétodo720×14401080×24001200×2652
Profile tabcoord fallback(648,1340)(972,2233)(1080,2467)
Edit profileXML tap~(171,496)~(255,826)~(283,912)
Add link (Edit Profile)XML tap → coord~(360,993)~(540,1507)~(600,1657)
+ Add link (Links page)coord fallback(200,180)(300,300)(333,331)
URL EditTextXML find~(360,211)~(540,352)~(600,440)
Done buttonXML → coord(661,84)(985,140)(1083,157)
⚠️ Barra sistema Android (Back/Home) en y≈1395–1440 (720×1440). Barra Instagram en y≈1300–1360. No confundir.
✅ Fix 2026-02-27: luciii_lovely (1200×2652), lucita_lovelys (1080×2400) y luci febrero 63/64/65 (1080×2640) fallaban con "Edit profile not found" porque (648,1340) iba al lugar incorrecto. Auto-escalado resuelve el problema para cualquier resolución.
✅ Fix 2026-03-02: Luna13 (1080×2376) nunca ponía el link. Causa: "Add link" en Edit Profile es nodo XML contenedor no-self-closing → invisible para regex antiguo. Fix: <node\s[^>]*> + filtro clickable="true". También xml_find_edittext retornaba campo Title (y=806) en vez de URL (y=349) → sanity check cy > 35% screen height.

ADB proxy GeeLark — quirks descubiertos (2026-02-27)

1. exec-out y adb pull NO funcionan

El proxy ADB de GeeLark solo soporta adb shell. Para XML dump usar:

adb shell uiautomator dump /sdcard/ui_lm.xml
adb shell cat /sdcard/ui_lm.xml

2. Proxy cierra conexiones idle tras ~2-3s

Después de esperar 12s al arranque de Instagram, ADB queda "device offline". Fix: llamar getData de nuevo, disconnect explícito, luego connect fresco + verify.

3. "already connected" pero "device offline" — estado TCP stale

adb disconnect + adb connect devuelve "already connected" pero sigue offline. Solución: gl_api("/adb/getData") → connect al port devuelto → verify loop 8×10s.

4. Initial connect — NO hacer disconnect previo

En la primera conexión, no desconectar antes. El proxy GeeLark necesita tiempo para estabilizar el túnel subyacente. Solo connect + sleep 3s + verify.

5. Resolución múltiple — detectar con wm size (fix 2026-02-27)

Phones con 1080×2400, 1080×2640, 1200×2652 fallaban con "Edit profile not found" porque las coordenadas hardcoded para 720×1440 apuntaban al lugar incorrecto.

_, out, _ = adb_cmd(f"-s {addr} shell wm size")
# → "Physical size: 1200x2652"
_res_w, _res_h = 1200, 2652

def _scale(x, y, base_w=720, base_h=1440):
    return int(x * _res_w / base_w), int(y * _res_h / base_h)

px, py = _scale(648, 1340)  # → (1080, 2467)

XML uiautomator — quirks descubiertos (2026-03-02)

6. "Add link" es un nodo contenedor no-self-closing

En Instagram, ciertos elementos de Edit Profile (como "Add link") son <node ...> con hijos, no <node .../>. El regex antiguo <node[^/]/> los ignoraba silenciosamente.

# Fix: regex + filtro clickable
for node_str in re.findall(r'<node\s[^>]*>', xml):
    if 'clickable="true"' not in node_str:
        continue  # Evita thumbnails, pics, nodos no-interactivos

7. "Add External Link" — dos EditText: URL arriba, Title abajo

La página de añadir link externo tiene dos campos. El XML puede devolver el Title field (y≈800) antes que el URL field (y≈350). Siempre usar el EditText con menor y.

# Retornar EditText topmost (menor cy)
if best is None or cy < best[0]:
    best = (cy, cx)
# Sanity check: si cy > 35% pantalla = Title field → blind tap
if cy > _res_h * 0.35:
    coords = None  # fallback a _scale(360, 150)
📦 v1 archivado en skills/ig-link-manager/scripts/archive/set_link_v1_sequential.py
⏱️

Tiempos ADB — Boot Wait

Probado con 14 phones Natalia (2026-02-26/27). Si ADB devuelve 42002 "phone is not running", no es un error permanente — el phone no ha terminado de arrancar.

EventoEspera mínimaNotas
Tras /phone/start28 segundosBoot completo del sistema
Tras /adb/setStatus8 segundosAntes de llamar /adb/getData
Si getData falla (42002)reintentar ×8 cada 15sTodos los phones conectan con tiempo correcto
Tras abrir Instagram (monkey)Re-connect ADBIG reinicia daemon ADB → la conexión cae. Llamar getData de nuevo, disconnect+connect+verify

Regla: si ADB parece roto, primero esperar más — NO asumir phone dañado

Los 13/13 phones Natalia con ADB "offline" conectaron correctamente con los tiempos correctos.

👤

create_account.py

skills/ig-account-creator/scripts/create_account.py

✅ Activo

Crea cuentas de Instagram desde cero en phones GeeLark. Flujo de 20 pasos con verificación SMS vía SMSPool. Resultados guardados en data/mc.db.

Modos SMS

ModoDescripciónTimeout código
auto SMSPool gestiona número y código internamente 20 min
manual Script pausa — el panel puede usar SMSPool directamente o introducir código a mano 30 min

Flujo panel-assisted (modo manual + SMSPool desde panel)

Paso 2 → Script pausa (===WAITING_PHONE===)
→ Panel muestra botón "📱 Pedir número a SMSPool"
→ Panel llama /api/smspool/get_number → obtiene número
→ Usuario confirma → /api/accounts/provide_input → script continúa
Paso 13 → Script pausa (===WAITING_CODE===)
→ Panel auto-inicia polling /api/smspool/poll_code cada 3s
→ Cuando llega código → se muestra y se envía automáticamente al script

Timeouts (actualizados 01/03/2026)

ParámetroAntesAhoraMotivo
Manual: esperar número/código 10 min 30 min Instagram puede tardar mucho
Auto SMSPool: get_status 5 min 20 min Misma razón
Panel: poll código SMS 10s 3s Respuesta más rápida al usuario

Persistencia entre pestañas

El panel guarda mc_acctJobId, mc_acctOutput y mc_acctStep en localStorage. Al volver a la pestaña Account Creator con un job activo, el polling y el log se recuperan automáticamente.

Base de Datos

EndpointDescripción
/api/db/statsKPIs: total, creadas, errores, hoy, tasa de éxito
/api/db/accountsLista con filtros (search, status, paginación)
/api/db/accounts/updateEditar campos de una cuenta por ID
/api/db/accounts/deleteEliminar cuenta por ID
/api/smspool/get_numberPide número a SMSPool desde el panel
/api/smspool/poll_codeComprobación única del código (no bloqueante, 3s entre llamadas)
/api/smspool/cancelCancela orden SMSPool activa
✏️

edit_profile.py

skills/ig-profile-editor/scripts/edit_profile.py

✅ Activo

Edición masiva de bio, nombre y foto de perfil via ADB. Threading con batch size configurable. Soporta "Same for all" y "Per account".

Quirks conocidos

Bio abre pantalla separada — tap Bio → nueva pantalla con Done

Gboard autocorrect — Fix: ime set com.zixun.cph/.util.GeeInputMethodService

Triple-tap + DEL para limpiar campo (no DEL spam en vacío)

ad_fill NO soporta Unicode/emoji en GeeLark

🔐

solve_captcha.py

skills/ig-captcha-solver/scripts/solve_captcha.py

🚧 En desarrollo

Resuelve "Confirm you're human" via 2captcha.com + verificación SMS con SMSPool post-CAPTCHA. 8 pasos, 3 reintentos CAPTCHA, timeout SMS 5 min.

Servicios requeridos

2captcha.comTWOCAPTCHA_KEY en .env (~$2-3/1000 CAPTCHAs)

SMSPoolSMSPOOL_KEY en .env (~$0.15/SMS, solo si IG pide verificación)

Pillowpip3 install Pillow (crop de imagen CAPTCHA)

Config Schema — *_accounts.json

Cada modelo tiene un archivo data/accounts/<model>_accounts.json

Campos raíz

CampoTipoDescripción
modelstringNombre del modelo (Luna, Natalia, etc.)
defaultLinkstringURL por defecto para link sticker
defaultStickerTextstringTexto sticker (%s = espacio). Ej: "Free%sToday%s!!"
lastPublishISO dateTimestamp última publicación
totalAccountsintTotal cuentas (auto-calculado)
verifiedAccountsintCuentas verificadas (auto-calculado)
notesstringNotas libres
accountsarrayLista de cuentas (ver abajo)

Campos por cuenta (accounts[])

CampoTipoDescripción
namestringID interno (Luna3, Luna9...)
phoneIdstringID de phone GeeLark (18 dígitos)
igstringHandle IG (@luniitaa.mrt)
verifiedbooltrue si última publicación fue exitosa
lastResultstringsuccess | adb_offline | error
issuestring?Descripción del último error
stickerStrategystringright_toolbar_button_2 | compose_view_button_2 | content_desc_stickers
stickerCoords[x,y]Coords del botón sticker (descubiertas automáticamente)
linkStickerCoords[x,y]Coords del sticker LINK en tray
screenResstringResolución pantalla (720x1362)
igVersionstringVersión IG detectada
igLanguagestringIdioma UI detectado (en/es)
successCountintPublicaciones exitosas acumuladas
failCountintFallos acumulados
restrictedbooltrue si IG bloqueó link sticker
lastPublishTimeISO dateTimestamp última publicación
lastScreenshotstringPath al último screenshot
needsRestartboolSi el phone necesita restart antes de publicar

Modelos y Cuentas

119 phones GeeLark, 43 cuentas IG mapeadas con @username real

ModeloPhonesCon IGSin IGADB OfflineCuentas mapeadas
🌙 Luna25 889 @luunita.i23, @luuniitaaa.022, @luunita.x, @luunitaa12, @luuniita.04, @lunaxx.gmz, @lunitaa.gmz, @luunaax.22
✨ Emma5 401 @emma_kattx, @emma_kattx2, @emma_kattx3, @emma_kattx5
🎀 Mimi12 804 @mimiii_gtf2-6, @mimiii_gtf8-10
💃 Natalia22 5413 @natalyy.reel, @natalia.yummy, @natalii.parish + 2 pendientes
❤️ Lucia/Luci38 171011 @lucii.lovelyy5, @lucix.lovelyx, @lucia.chik3, @luu.lovv4, @lu_lovelysx, +12 más
🌸 Cindy6 123 @cindyystrm
📦 Otros11 0110 Reddit, Pruebas, Test, API-Created

Datos del 19 Feb 2026. Los números en vivo están en la sección Granja IG (KPIs + auto-refresh 30s).

Luna — Detalle de cuentas

NombreIGStatusSticker StrategyResoluciónIssue
Luna2@luniitaa.mrtofflineunknownServer 199.190.44.226 ADB unresponsive
Luna3@luunita.i23verifiedright_toolbar_button_2720x1362
Luna4@lunitax.profflineunknownADB unresponsive
Luna5@lunnitaa.222offlineunknownADB unresponsive
Luna6@lunita.rdxofflineunknownADB unresponsive
Luna7@luuniitaaa.022verifiedright_toolbar_button_2720x1362
Luna8@luunita.xverifiedright_toolbar_button_2720x1362
Luna9@luunitaa12verifiedcompose_view_button_2
Luna10@luuniita.94verifiedcompose_view_button_2
Luna11@lunaxx.gmzverifiedright_toolbar_button_2720x1362
Luna12@lunitaa.gmzverifiedcompose_view_button_2
Luna13@luunaax.22verifiedcontent_desc_stickers

📡 Mapeo de Cuentas IG

Cómo se extrae el @username de Instagram de cada phone GeeLark

Flujo de mapeo (3 pasos)

1Conectar al phone via ADB

Boot phone → /adb/setStatus open → /adb/getDataadb connect ip:portglogin pwd

2Extraer ID numérico de IG

adb shell dumpsys account | grep www.instagram.com → extrae name=XXXXXXXXX (ID numérico de la cuenta IG)

Este comando lee las cuentas Android registradas. Si IG está instalado y logueado, aparece con su ID numérico.

3Resolver ID → @username (desde el phone)

adb shell curl -s "https://i.instagram.com/api/v1/users/{ID}/info/"

⚡ La petición se hace DESDE el phone, no desde el PC. Cada phone tiene su propia IP → sin rate limits de IG.

Devuelve: username, biography, external_url, follower_count, following_count, media_count, profile_pic

⚡ Por qué desde el phone (Phone-Proxy)

❌ Método viejo (desde PC): PC llama a la API de IG → tras ~30 peticiones IG bloquea la IP del PC por horas ("Please wait a few minutes")

✅ Método actual (Phone-Proxy): Cada phone ejecuta curl internamente → IG ve tráfico normal desde la IP del proxy del phone → sin límites

💡 Este método escala a cualquier número de phones. Se usa para mapeo, audits, y cualquier scraping futuro de IG.

Scripts

ScriptFunciónUso
scripts/map_all_accounts.py Mapeo masivo de todos los modelos. Boot → ADB → dumpsys → curl desde phone → stop. Workers paralelos. Guarda en data/phones_registry.json. python3 scripts/map_all_accounts.py --group all --workers 5 --skip-mapped --retry
skills/ig-profile-checker/scripts/check_profile.py Scan de perfil IG via ADB. Abre IG en el phone, navega al perfil, extrae datos via uiautomator dump. python3 scripts/scan_model.py --model Luna --batch 5

Estados posibles de un phone

EstadoIndicadorSignificadoAcción
success @username visible Mapeado correctamente con @ real Listo para publicar
api_resolve_failed ⏳ IG detectado — @ pendiente Tiene ID numérico pero no se pudo resolver el @ Ejecutar resolve_via_phone.py
no_ig_account ❌ Sin IG instalado Phone no tiene IG instalado o no está logueado Instalar IG desde GeeLark panel
adb_data: code=42002 ⚡ ADB offline Servidor GeeLark no permite activar ADB Contactar GeeLark o recrear phone en otro servidor
adb_offline ⚡ ADB offline ADB se activó pero el phone no responde Reiniciar phone y reintentar
sin datos Sin mapear No se ha intentado mapear aún Ejecutar map_all_accounts.py

Datos del registry (phones_registry.json)

Archivo central que almacena el estado de todos los phones. Leído por server.py para mostrar en el panel.

CampoTipoEjemploDescripción
igstring@luunita.i23Username de IG (@ real o @id:XXXXX si pendiente)
igNumericIdstring80173762029ID numérico de la cuenta IG (de dumpsys)
hasBioboolfalse¿Tiene bio configurada?
bioTextstring"Link in bio 💕"Texto de la bio (max 200 chars)
hasLinkboolfalse¿Tiene enlace externo?
linkTextstringhttps://clickmy...URL del enlace externo
followerCountstring142Número de seguidores
followingCountstring88Número de seguidos
postCountstring5Número de publicaciones
hasProfilePicbooltrue¿Tiene foto de perfil?
screenResstring720x1440Resolución de pantalla del phone
lastResultstringsuccessResultado del último intento de mapeo
lastAuditISO date2026-02-18T22:46ZTimestamp del último check
auditMethodstringdumpsys+ig_apiMétodo usado para el mapeo

📊 Estado actual del mapeo

43
@ mapeados
2
@ pendientes
25
sin IG
51
ADB offline
5
sin intentar
119
total phones

Última actualización: 19 Feb 2026. Los KPIs en vivo están en la sección Granja IG.

🔍 Check Feed IG

Auditoría masiva de cuentas IG: verifica foto de perfil, bio, enlace, estado de login, y captura screenshots

Dos modos de operación

📡 Modo Map

• Extrae @username de cada phone

• Usa dumpsys account + IG API desde phone

• Rápido: ~35s por phone (boot + ADB + query)

• No abre Instagram en el phone

• Resultado: @username + stats básicos

🔍 Modo Audit

• Todo lo de Map + abre IG en el phone

• Navega al perfil y captura screenshot

• Verifica visualmente: foto, bio, link, feed

• Más lento: ~60s por phone

• Resultado: todo de Map + screenshots

API Endpoints del Check Feed

MethodPathDescripción
POST/api/check/startLanzar job de mapeo/audit. Body: {mode, group, workers, bootWait}
POST/api/check/statusEstado de un job. Body: {jobId}
POST/api/check/jobsLista todos los jobs
POST/api/screenshotsLista screenshots del audit
GET/screenshots/audit/*Servir imágenes de screenshots

Integración con Granja IG (Phones)

Flujo de datos: Check Feed → phones_registry.json → Panel Phones

Cuando un job de Check Feed termina, los resultados se escriben automáticamente en el registry. La sección Phones lee del mismo registry, así que los datos aparecen automáticamente (auto-refresh cada 30s).

Datos que pasan de Check Feed → Phone Card

@username
📝 Bio
🔗 Link
📷 Foto perfil
Followers
Following
Posts
📸 Screenshots

Click en cualquier tarjeta de phone para ver el detalle completo incluyendo screenshots del audit.

🛡️ Reglas de seguridad

🔴 Auto-stop obligatorio: Todos los phones se apagan al terminar el job o en caso de error. Cada minuto encendido cuesta dinero.

🔴 Botón Stop All: Emergencia — apaga TODOS los phones con un click (POST /api/phones/stopall)

🟡 --keep-running: Opt-in. Solo si explícitamente se pide, los phones se quedan encendidos después.

🟢 Phone-proxy: Las peticiones a IG API se hacen desde dentro del phone via ADB curl. Sin rate limits.

Troubleshooting

⚡ ADB falla / code=42002 / "No ADB data" — LO MÁS COMÚN

→ Primera causa a revisar SIEMPRE: Boot Wait insuficiente

Síntoma: code=42002, "No ADB data after 5 attempts", o "adb_offline" en todos o varios phones

Causa más frecuente: El phone no ha terminado de arrancar cuando se llama a /adb/getData. El daemon ADB tarda en iniciarse.

Tiempos mínimos probados (14 phones Natalia, 26/02/2026):

  • • Boot wait: 28s mínimo tras /phone/start
  • • Tras /adb/setStatus: 8s antes de llamar /adb/getData
  • • Si falla: reintentar getData hasta 5 veces con 12s entre intentos

✅ Los 14 phones de Natalia que parecían "ADB offline" conectaron perfectamente con el tiempo correcto.

Fix: Aumentar boot wait. Si tras 5 reintentos sigue fallando, entonces sí puede ser problema de servidor GeeLark → recrear phone.

🔴 ADB Offline / No credentials (problema real de servidor)

Síntoma: Falla incluso con boot wait largo y múltiples reintentos

Causa: Servidor GeeLark con ADB bloqueado o phone corrupto

Fix: Recrear phone en GeeLark panel (se asigna a otro servidor) o contactar soporte GeeLark.

🟡 No LINK Sticker Found

Síntoma: Script no encuentra sticker LINK tras 3 estrategias

Causa: UI de IG cambió, resolución diferente, o idioma no detectado

Fix: 1) Verificar manualmente que la cuenta tiene acceso a link sticker. 2) Borrar stickerCoords del config para forzar redescubrimiento. 3) Tomar screenshot para inspeccionar UI.

🔴 Link Sticker Restricted

Síntoma: "You need more followers" / restricted=true en config

Causa: IG requiere cierto número de seguidores para link sticker

Fix: Warmup la cuenta con más followers/engagement. Mientras tanto, usar --skip-link para publicar sin sticker.

🟡 UI Dump Failed

Síntoma: uiautomator dump devuelve vacío

Causa: IG aún cargando, phone lento, o ADB desconectado mid-session

Fix: Aumentar --boot-wait. Verificar conexión ADB. Reintentar (el script tiene retry automático).

🟡 IG Not in Foreground

Síntoma: "IG not in foreground" en output

Causa: Intent ADD_TO_STORY no abrió IG correctamente (popup, otra app encima)

Fix: Force-stop IG y reintentar. Verificar que no hay diálogos del sistema bloqueando.

🔵 Coords Hardcoded Fallan

Síntoma: Taps caen en lugar equivocado

Causa: Diferentes phones tienen diferentes resoluciones (720x1362 vs 1080x1920)

Fix: Borrar stickerCoords/linkStickerCoords del config para forzar auto-descubrimiento vía UI XML.

GeeLark API

Base: https://openapi.geelark.com/open/v1 — Todo POST con JSON body — Auth: Bearer token

EndpointDescripciónParams clave
/phone/listLista phones con paginación{page, pageSize} → data.items[]
/phone/startArrancar phones (max 100/call){ids: [...]}
/phone/stopParar phones{ids: [...]}
/adb/setStatusHabilitar/deshabilitar ADB{ids: [...], open: true}
/adb/getDataObtener IP:port:pwd para ADB{ids: [...]} → data.items[{ip, port, pwd, code}]
/task/runEjecutar Task Flow en phone{phoneId, flowId, params}
/phone/group/listLista grupos de phones{} → data.items[]

Rate Limits & Quirks

200 req/min, 24,000 req/hora

• Todos los endpoints son POST con JSON body (incluso los que "leen")

• El campo es ids (no phoneIds)

• ADB enable es /adb/setStatus (no /phone/adb/enable)

• Max 100 phones por llamada a start/stop/adb

adb connect requiere glogin <pwd> después para autenticar

• Phones en servidor 199.190.44.226 tienen problemas recurrentes de ADB

• Task Flows nativos NO funcionan para stories con link sticker → por eso usamos ADB directo

Agentes del Sistema

Agentes especializados orquestados vía Claude Code (MCP en /sse)

🏠main

Orquestador principal. Coordina todos los agentes, gestiona el panel Mission Control, toma decisiones estratégicas.

📊cm-assistant

Community Manager. Monitoriza WhatsApp grupo "Cupido Elite Chats", gestiona comunicación.

📱geelark-phones

GeeLark Manager. Controla la granja de phones, ejecuta Task Flows, sube contenido a las cuentas.

🔎ig-checker

IG Checker. Audita cuentas via ADB: verifica foto perfil, enlace bio, estado de cada cuenta.

🎬content-researcher

Content Researcher. Busca videos virales, descarga reels trending para reutilizar como stories.

🤖rpa-builder

RPA Builder. Crea automatizaciones ADB para GeeLark: scripts de publicación, edición de perfiles, warmup.

🔗bouncy

Bouncy Link Manager. Gestiona tracking links via Bouncy.ai API: short links, analytics de clicks, geo, devices.

📡 Phone Scanner — Scan de Perfiles IG

Sistema de escaneo masivo que extrae datos de perfil IG directamente desde la UI del phone via ADB

Flujo de scan (por phone)

1Boot Phone

GeeLark API /phone/start → espera status=1 (max 90s) → cada phone sale con su IP única via proxy ProxyEmpire

2Connect ADB

/adb/setStatus {open:true}/adb/getDataadb connect ip:portglogin pwd

3Screen Resolution

adb shell wm size → ej: 1080x2400. Variaciones: 720x1440, 1080x2340-2712, 1200x2652, 1236x2750

4Open IG Profile

Launch IG → tap profile tab (bottom-right, coords calculados según resolución) → espera 3s

5UI Dump + Parse

uiautomator dump → parse XML → extraer username, followers, posts, bio, link, idioma IG

6Cleanup

adb disconnect/phone/stop → guardar resultado en JSON → siguiente phone

⚠️ Regla Crítica — 1 Phone = 1 IP

NUNCA escanear múltiples phones simultáneamente.

Cada phone GeeLark tiene su propio proxy ProxyEmpire con IP española o USA única. Al arrancar, IG ve tráfico desde esa IP.

Si arrancas 2+ phones del mismo servidor a la vez, podrían compartir IP → ban de IG por actividad sospechosa.

✅ Flujo correcto: boot 1 → scan → stop → boot siguiente → scan → stop → ...

Username Detection — Patrones regex

El scan usa múltiples regex sobre el UI XML dump para encontrar el @username:

PrioridadPatrónDescripción
1action_bar_title text="..."Título del action bar (IG clásico)
2action_bar_textview_titleVariante del action bar
3title_text text="..."IG versiones nuevas
4Fallback: lowercase text matchesBusca textos cortos a-z que parezcan usernames, filtrando palabras comunes

⚠️ Algunos phones devuelven "???" — IG versiones muy nuevas cambian el layout del XML. Requiere actualizar patrones.

Datos extraídos

CampoFuenteEjemplo
usernameUI XML regex@lucii_loveex
followerscontent-desc="N followers"142
postscontent-desc="N posts"5
bioprofile_header_bio_text"Link in bio 💕"
linkprofile_header_websiteclickmy.bio/xxx
screenResadb shell wm size1080x2400
igLanguageUI keywords (Posts/Publicaciones)en / es
statusDetection logicok / not_logged_in / no_ig / error

Scripts

ScriptFunciónUso
skills/ig-profile-checker/scripts/check_profile.py Scan individual o masivo via ADB. Llamado por mc_server.py para los endpoints /api/phone/scan y /api/phone/scan/bulk. python3 scripts/scan_model.py --model Luna
scripts/scan_model.py Wrapper standalone. Lee error registry, calcula boot-wait y batch size óptimos, lanza check_profile.py, guarda log. python3 scripts/scan_model.py --model Natalia --batch 5 --retry

Resultados en el panel

Los resultados se guardan en data/accounts/<model>_accounts.json y se integran en la respuesta de /api/phones/full.

Cada phone card en la sección Phones muestra: @username, idioma IG (badge en/es), resolución de pantalla, y estado del scan.

El botón 🔍 en cada card lanza un scan individual (/api/phone/scan). Los botones por modelo lanzan scans en bulk (/api/phone/scan/bulk).

El registry global data/phones_registry.json almacena el historial de todos los phones y es leído por /api/phones/full.

📤

Publisher — Reels & Posts via GeeLark RPA

Sin ADB · Sin boot wait · Scheduling nativo · SQLite local

⚠️ Test pendiente
🎬
Reel
instagramPubReels
campo: video
🖼️
Post
instagramPubReelsImages
campo: photo
☁️
CDN Upload
/file/upload (multipart)
caché por mtime

Endpoints del panel

MétodoPathDescripción
POST/api/publish/reelPublica reel en N phones. Body: {phones, phoneNames, igUsernames, model, media, caption, scheduleAt, intervalMinutes}
POST/api/publish/postPublica post (imagen) en N phones. Mismos campos que /reel
GET/api/publish/tasksLista tareas. Params: ?date=today|week, ?type=reel|post|all, ?status=all|pending|done|failed

Flujo por publicación

1. Upload mediaupload_to_geelark(path) → CDN URL (caché por path+mtime → 1 upload para N phones)

2. Para cada phone: calcular scheduleAt = base + (idx × intervalMinutes × 60) × 1000ms

3. POST GeeLark RPA/rpa/task/instagramPubReels o instagramPubReelsImages

4. Guardar en SQLite tabla publish_tasks con task ID, status y respuesta completa

5. GeeLark enciende el phone automáticamente en scheduleAt y ejecuta la tarea RPA

⚠️ Pendiente verificar (02/03/2026)

• Formato exacto de respuesta de /file/upload (se asume data.url)

• Nombres exactos de endpoints RPA (instagramPubReels / instagramPubReelsImages)

• Campos adicionales que pueda requerir la API RPA de GeeLark

Tabla publish_tasks (SQLite data/mc.db)

CampoTipoDescripción
job_idTEXTTask ID devuelto por GeeLark RPA
typeTEXTreel | post
methodTEXTrpa (siempre)
mediaTEXTURL en CDN de GeeLark (no ruta local)
schedule_atINTEGERUnix timestamp en segundos (NULL = inmediato)
statusTEXTscheduled | running | done | failed
result_detailTEXTJSON completo de respuesta GeeLark
👤

Account Creator — Creación de cuentas IG

skills/ig-account-creator/scripts/create_account.py

✅ Activo

Crea cuentas de Instagram desde cero en phones GeeLark. Flujo de 20 pasos: boot ADB → SMSPool número → abrir IG → rellenar formulario → verificar SMS → configurar perfil. Resultados guardados en data/mc.db (tabla ig_accounts).

Argumentos del script

ArgumentoDescripción
--phone-idID GeeLark del phone
--phone-nameNombre del phone
--full-nameNombre completo de la cuenta
--usernameUsername tentativo (el script prueba variantes si está tomado)
--passwordContraseña
--sms-keyAPI key de SMSPool
--countryCódigo de país para SMSPool (default: "es")
--sms-mode"auto" | "manual" (default: "auto")
--job-idID del job (comunicación IPC con mc_server.py)

Modos SMS

ModoDescripciónTimeout
auto SMSPool gestiona número y código internamente 20 min
manual Script pausa — el panel puede usar SMSPool directamente o introducir código a mano 30 min
panel-assisted UI: "Pedir a SMSPool" + auto-poll código. Internamente es modo manual, pero el panel llama a SMSPool 30 min

Comunicación IPC (modo manual)

El script usa archivos /tmp/ como canal IPC con mc_server.py:

ArchivoDirecciónPropósito
/tmp/acct_{job_id}_phone.txtpanel → scriptNúmero de teléfono a registrar
/tmp/acct_{job_id}_code.txtpanel → scriptCódigo SMS de 6 dígitos
/tmp/acct_{job_id}_resend.txtpanel → scriptSeñal de reenvío SMS

Marcadores stdout (IPC)

===WAITING_PHONE===job['waitingFor'] = 'phone'
===WAITING_CODE===job['waitingFor'] = 'code'
===STEP===N===TOTALjob['step'] = N
===JSON_OUTPUT=== → Resultado final (JSON)

Flujo panel-assisted

Paso 2 → Script pausa (===WAITING_PHONE===)
→ Panel muestra botón "📱 Pedir número a SMSPool"
→ Panel llama /api/smspool/get_number → obtiene número
→ Usuario confirma → /api/accounts/provide_input → script continúa
Paso 13 → Script pausa (===WAITING_CODE===)
→ Panel auto-inicia polling /api/smspool/poll_code cada 3s
→ Cuando llega código → se muestra y se envía automáticamente al script

Timeouts (actualizados 01/03/2026)

ParámetroAntesAhoraMotivo
Manual: esperar número/código10 min30 minIG puede tardar mucho
Auto SMSPool: get_status5 min20 minMisma razón
Panel: poll código SMS10s3sRespuesta más rápida

Base de Datos — tabla ig_accounts

CampoTipoDescripción
idINTEGER PKAutoincrement
created_atTEXTTimestamp ISO
job_idTEXTID del job que creó la cuenta
phone_idTEXTID del phone GeeLark
phone_nameTEXTNombre del phone
full_nameTEXTNombre completo
usernameTEXTUsername tentativo
ig_usernameTEXTUsername final asignado por IG
passwordTEXTContraseña
birthdateTEXTFecha de nacimiento (YYYY-MM-DD)
phone_numberTEXTEmail iCloud o número SMS usado
activation_idTEXTOrder ID de SMSPool (o "manual")
countryTEXTPaís del número SMS
statusTEXTcreated / sms_timeout / username_taken / error
step_failedTEXTNombre del paso donde falló

Endpoints del panel

EndpointDescripción
POST /api/accounts/startInicia job de creación
POST /api/accounts/statusEstado del job (output, step, waitingFor, result)
POST /api/accounts/cancelCancela job
POST /api/accounts/provide_inputEnvía número o código al script vía /tmp/
POST /api/accounts/resend_smsSeñaliza reenvío SMS
POST /api/accounts/hero-balanceConsulta saldo SMSPool
POST /api/smspool/get_numberPide número a SMSPool
POST /api/smspool/poll_codePoll único del código SMS (3s entre llamadas)
POST /api/smspool/cancelCancela orden SMSPool activa

Persistencia (localStorage)

El panel guarda mc_acctJobId, mc_acctOutput y mc_acctStep en localStorage. Al volver a la pestaña Account Creator con un job activo, el polling y el log se recuperan automáticamente.
🔐

CAPTCHA Solver — Resolución automática de CAPTCHAs

skills/ig-captcha-solver/scripts/solve_captcha.py

🚧 En desarrollo

Resuelve automáticamente el challenge "Confirm you're human" de Instagram (CAPTCHA de texto distorsionado) usando 2captcha.com. Si después del CAPTCHA aparece verificación de número móvil, la gestiona automáticamente con SMSPool.

Argumentos del script

ArgumentoDescripción
--phone-idID GeeLark del phone
--phone-nameNombre del phone
--twocaptcha-keyAPI key de 2captcha.com
--sms-keyAPI key de SMSPool (para verificación móvil post-CAPTCHA)
--countryCódigo de país para SMSPool (default: "es")

Requisitos

ServicioVariable .envCostePara qué
2captcha.comTWOCAPTCHA_KEY~$2-3/1000Resolver imagen CAPTCHA
SMSPoolSMSPOOL_KEY~$0.15/SMSVerificación móvil post-CAPTCHA
Pillowpip3 install PillowGratisCrop de imagen CAPTCHA

Flujo (8 pasos)

1Arrancar phone + conectar ADB

10 reintentos × 12s. Boot wait + adb connect + glogin

2Abrir Instagram

Intent directo a la app

3Detectar CAPTCHA via XML

Busca "Confirm you're human" en UI dump. Si no hay CAPTCHA → detecta phone verification o sale

4Screenshot → crop → 2captcha → introducir código

Hasta 3 intentos con "Get a new code" entre cada uno. Crop del ImageView mejora precisión

5Detectar si pide verificación móvil

Si no pide → proceso completado

6Obtener número temporal de SMSPool

País: España (ES +34). Pools fallback: 3 → 12 → 7 → auto

7Esperar código SMS

Max 5 min. Cancel + refund si timeout

8Introducir código SMS → confirmar

Multi-button search: Next / Confirm / Continue

Detección de pantallas

PantallaTexto detectado en XMLFunción
CAPTCHA"Confirm you're human"detect_captcha()
Phone verification"Enter your mobile number"detect_phone_verification()
SMS code input"Enter the code", "confirmation code"detect_sms_code_screen()

Crop de imagen CAPTCHA

El script localiza el ImageView del CAPTCHA en el XML (típicamente bounds [146,546][934,743] en 1080x2340) y recorta solo esa área para enviar a 2captcha.

• Bounds: width > 200px, height > 80px, y > 200 (descarta iconos)

• Crop con Pillow + 10px padding

• Fallback: si Pillow no está instalado, envía screenshot completo

2captcha API

PasoEndpointParams clave
SubmitPOST 2captcha.com/in.phpmethod=base64, body=<img>, numeric=1, min_len=4, max_len=8
PollGET 2captcha.com/res.phpaction=get, id=<captcha_id>

• Polling cada 5s, timeout 120s

• Tasa de éxito esperada: ~95-99% (CAPTCHAs de texto numérico distorsionado)

• Si falla, el script pide "Get a new code" y reintenta (hasta 3 veces)

Verificación de móvil post-CAPTCHA

Instagram puede pedir verificación de número después del CAPTCHA. El script usa un número nuevo temporal de SMSPool — no necesita ser el mismo con el que se creó la cuenta.

• País por defecto: España (ES +34)

• SMSPool cancela y devuelve el crédito si el SMS no llega en 5 min

Endpoints del panel

EndpointDescripción
POST /api/captcha/startInicia job. Body: {phoneId, phoneName, twocaptchaKey?, smsKey?, country?}
POST /api/captcha/statusEstado: {status, output, step, totalSteps, result?}
POST /api/captcha/cancelCancela job y para el phone

Resultados posibles

result.statusSignificado
solvedCAPTCHA resuelto + teléfono verificado
captcha_onlyCAPTCHA resuelto, no pidió verificación de móvil
no_captchaNo se detectó CAPTCHA al abrir Instagram
partialAlgún paso completó pero el estado final no es claro
errorFallo con stepFailed indicando el paso exacto
✏️

Profile Editor — Edición bulk de perfiles IG

skills/ig-profile-editor/scripts/edit_profile.py

✅ Activo

Edición masiva de bio, nombre y foto de perfil via ADB en phones GeeLark. Soporta modo "Same for all" (mismo valor para todos) y "Per account" (valor distinto por cuenta). Threading con batch size configurable.

Campos editables

CampoMétodo ADBNotas
BioTap Bio EditText → pantalla separada → triple-tap select all → DEL → type texto → tap DoneBio abre pantalla separada en IG
NombreTap Name EditText → triple-tap select all → DEL → type texto → backad_fill NO soporta Unicode/emoji
Foto de perfiladb push → media scanner → tap "Edit picture" → "Choose from library" → gallery selecciona la más recienteFunciona con JPG/PNG

Flujo por phone (13 pasos)

1Arrancar phone + conectar ADB

Boot wait 28s + ADB retry 8×15s

2Configurar IME

Cambiar a GeeInputMethodService (sin autocorrect de Gboard)

3Abrir Instagram → navegar a perfil

Intent + tap profile tab

4Tap "Edit profile"

Busca "Edit profile"/"Editar perfil" en XML

5-8Editar campo(s) seleccionado(s)

Bio: pantalla separada con Done. Name: inline. Photo: push + gallery

9-13Guardar + verificar + cleanup

Tap checkmark/Done → verificar cambios → stop phone

Quirks importantes

Bio abre pantalla separada

Al tocar el campo Bio en Edit Profile, Instagram abre una pantalla nueva con botón Done/checkmark arriba. No es inline como Name.

Gboard autocorrect

settings put secure spell_checker_enabled 0 NO funciona. Fix real: ime set com.zixun.cph/.util.GeeInputMethodService (IME de GeeLark sin autocorrect)

Limpiar campo: Triple-tap + DEL

NO hacer DEL spam excesivo (160 DELs) en campo vacío — Android interpreta backspace en vacío como "back" → sale de la pantalla

ad_fill NO soporta Unicode/emoji

En GeeLark: "Non-ASCII text input is not supported". Usar solo texto ASCII para nombres.

Modos de valor

ModoDescripción
Same for allEl mismo valor se aplica a todos los phones seleccionados
Per accountSe especifica un valor distinto para cada phone/cuenta

Endpoints del panel

EndpointDescripción
POST /api/profile/startInicia job de edición. Body: {model, field, value, target, phones, ...}
POST /api/profile/statusEstado del job — {jobId}
POST /api/profile/cancelCancela job de edición
GET /api/profile/activeLista profile jobs activos

Threading

Usa ThreadPoolExecutor con batch size configurable (default 3). Cada phone se procesa en su propio thread con boot + ADB independiente. El job dict _profile_jobs en mc_server.py trackea progreso de cada phone individual.

🍪 Cookie Accepter

Accept cookie consent popups on Instagram for active phones.

Select Phones

Settings

Selected: phones

Progress

Log


      

Results

Phone Name Result Details
👤

Profile & Links

Manage Instagram bios, names, photos, and website links in bulk via ADB.

📱
0
Total Active
0
Con Link
0
Sin Link

All Active Phones

Settings

Selected: phones
⚠️ ya tienen link (se reemplazará)

Progress

Log


      

Results

✅ enlaces puestos
❌ fallidos
total
Phone Name Result Link Verified

Apply to all selected

Edit per account

Phone Name Bio

Progress

Output


      

Results

Phone Name Bio Photo Status

👤 Account Creator

Crea cuentas de Instagram en phones GeeLark usando verificación SMS Pool o Email

⏳ Creando...
✅ Creada

📱 Phone

Cargando phones...

👤 Datos de cuenta

@
📅 Fecha de nacimiento generada automáticamente (persona mayor de edad, 18-35 años)

🔐 Método de verificación

El script pausará cuando IG envíe el código — introdúcelo manualmente desde el panel.

El script pausará en paso 2 y paso 13 — tú introduces el número y el código SMS desde el panel.

Saldo: $

📊 Progreso

📋 Log

LIVE
Sin log aún

📱 Número de teléfono

Número obtenido de SMSPool
Order ID:
o introduce manualmente

📨 Código SMS

Esperando SMS para
Comprobando cada 10s · Order:
¡Código recibido! Enviando al script...

📧 Código de verificación Email

Esperando código enviado a:
Revisa tu bandeja de entrada (o spam) y copia el código de 6 dígitos

🏆 Resultado

✅ Cuenta creada correctamente
Username:
Teléfono:
Email:
Phone:
Activación:
Falló en:

📋 Historial de cuentas creadas

Guardado permanentemente en data/created_accounts.json

creadas · fallidas
Sin historial aún — las cuentas creadas aparecerán aquí automáticamente
Fecha Phone Nombre @Username IG Contraseña Cumpleaños Email / SMS Estado Info
Total
✅ Creadas
❌ Fallidas
Hoy
Tasa éxito
# Fecha Phone Nombre completo @Username IG Contraseña Cumpleaños Email / SMS País Estado Error en Acciones

✏️ Editar Cuenta

Apply to all accounts

Edit per account

Phone Name Bio

Progress

Output


      

Results

Phone Name Bio Photo Status

CAPTCHA Solver 🚧

Resuelve CAPTCHAs "Confirm you're human" via 2captcha + verificacion SMS via SMSPool

Resolviendo...
Resuelto

En desarrollo — Requiere API key de 2captcha.com (TWOCAPTCHA_KEY en .env). La verificacion SMS usa SMSPool (misma key que Account Creator).

Phone

Cargando phones...

Configuracion

Como funciona: 1) Arranca el phone y abre Instagram → 2) Detecta el CAPTCHA "Confirm you're human" → 3) Envia la imagen a 2captcha para resolver → 4) Introduce el codigo y pulsa Next → 5) Si aparece verificacion de movil, usa SMSPool automaticamente

Progreso

Log


        

Resultado

Estado:
Codigo CAPTCHA:
Telefono SMS:
CAPTCHA resuelto
Telefono verificado
Fallo en:

📤 Manual Publisher

Publica Reels y Posts via GeeLark RPA — sin ADB, sin boot wait

1
Tipo de publicación
Elige qué quieres publicar
2
Cuentas
Selecciona las cuentas donde publicar
seleccionadas
Cargando cuentas...
Selecciona un modelo para ver las cuentas
Sin cuentas para este modelo
3
Contenido & Opciones
Media, caption y scheduling
🎬
Total hoy
✅ OK
❌ Fallos
Pendiente
Cargando tareas...
Sin tareas para este período — publica algo en la pestaña Publicar
Hora Phone / @IG Tipo Caption Programado Estado

📋 Mis Tareas

Vista unificada de todas las publicaciones — Stories, Reels y Posts

En espera
En curso
Completadas
Fallidas
Ayer
📸 🎬 🖼️ Total:
Hoy
📸 🎬 🖼️ Total:
Mañana
📸 🎬 🖼️ Total:
Cargando tareas...
No hay tareas para los filtros seleccionados

🤖 AutoPublisher

Supabase + VPS — publicaciones automatizadas

Pendientes de Caption

ModeloCuenta ArchivoCaption Acciones

Próximas Publicaciones

No hay publicaciones programadas
Modelo Cuenta Archivo Programado Countdown Estado

Cuentas por Modelo

No hay datos de cuentas. Ejecuta un Scan de inventario primero.
Modelo Cuentas Usernames Estado

Historial de Publicaciones

No hay historial
Modelo Cuenta Archivo Fecha Estado Error

Contenido por Modelo

📁 carpetas 🎬 sin publicar 📦 total
Cargando...
Carpeta vacía o no configurada

🔄 Repurpose

Genera variantes con hashes unicos via FFmpeg

Modificaciones que aplica FFmpeg
Velocidad (0.97x-1.03x)Brillo y contrasteSaturacion de color Rotacion minima (±1.5°)Zoom sutil (hasta 1.08x)Padding (0-8px borde) Volumen de audioBitrate (2800-3400k)Ruido visual ligero Metadata y timestamp Recorte silencios inicio/final [TikTok] FPS 29.97/25 + flip + crop + escala
📁 Origen
Ninguna seleccionada
Salida:
/root/content/
Sin subcarpetas
·
Esta carpeta no tiene videos ni subcarpetas
Subiendo al VPS...
Historial completados · fallidos
Modo TikTok — FPS 29.97/25 · recorte de bordes · escala 1076x1916
Flip espejo
📁 Carpeta origen
Ninguna carpeta seleccionada
Destino:
Comando para Terminal

        
Requiere FFmpeg: brew install ffmpeg

📈 Analytics

Estadísticas de cuentas de Instagram

Total Followers
Total Views
Total Likes
Cuentas Trackeadas

Crecimiento de Followers

Followers Views Likes
Cuenta Modelo Followers Views Likes Comments Saves Posts Engage% Karma
No hay datos aún. Se sincroniza automáticamente al entrar.
Requiere GL_APP_ID y GL_API_KEY en .env
🐦

Twitter Automation

🤖
-
📸 Fotos
0
✅ Publicados
0
📋 En Cola
-
💛 Engagement

⚙️ Configuración

Cargando...

🕐 Horarios (Madrid)

Distribución de estilos

🔥 Provocativo30%
❓ Pregunta25%
👀 Teaser20%
📖 Storytelling15%
📍 Situacional10%

🐦 Cola de Tweets

No hay tweets en cola

🚀 Growth Engine

@-
— Último engage: nunca · Menciones pendientes: -

Settings