Type something to search...

Tareas por lotes de longarm

Volver a la documentación de longarm

Las tareas por lotes permiten guardar flujos reutilizables de varios pasos y ejecutarlos después desde la app, REST API o MCP.

Comportamiento clave

  • solo una ejecución por lotes puede estar activa a la vez
  • las solicitudes de ejecución devuelven inmediatamente un runId
  • el progreso se consulta mediante estado e historial
  • las capturas tomadas por pasos screenshot se guardan en el historial
  • la retención predeterminada es de 30 ejecuciones

Tareas grabadas

Detener una grabación en la pestaña Batch crea una tarea por lotes normal que contiene los pasos clasificados de tap, long-press, swipe y delay. Una tarea grabada no es un origen inmutable especial: puede editarse, duplicarse, eliminarse, ejecutarse o actualizarse con las mismas operaciones de app, REST y MCP que cualquier tarea creada manualmente.

Cuando la inspección de UI está habilitada en la configuración al iniciar la grabación, cada gesto grabado va precedido de una anotación ui_context que describe el estado de la UI justo antes de ese gesto. Se muestra como JSON de solo lectura en la app y se conserva en las tareas guardadas, en las exportaciones/importaciones JSON y en los datos de tarea de REST/MCP. El runner omite la anotación completa durante la ejecución — no cuenta como paso ejecutado ni genera entrada de log, y el gesto de coordenadas original no cambia. Los editores de IA pueden usar el texto del nodo, viewId, clase, límites, estado y acciones de la anotación para refinar un gesto grabado en un objetivo semántico.

Con la inspección de UI deshabilitada durante la grabación, esta guarda solo los gestos, sin anotación. Las tareas guardadas más antiguas con metadatos de grabación heredados se cargan como tareas por lotes normales; los metadatos obsoletos se descartan la próxima vez que se guarda la tarea.

Forma JSON de una tarea

Tarea de nivel superior:

{
  "id": "bt_...",
  "name": "Open Settings and capture",
  "steps": [],
  "repeat": 1,
  "variables": {},
  "createdAt": "2026-07-13T00:00:00.000Z",
  "updatedAt": "2026-07-13T00:00:00.000Z"
}

Para POST /api/batch y batch_save, proporciona name, steps, y de forma opcional repeat y variables. El servidor puede asignar IDs y timestamps.

Forma JSON de un paso

{
  "id": "step_1",
  "type": "tap",
  "params": { "x": 540, "y": 1200, "duration": 80 },
  "repeat": 1,
  "delayAfterMs": 0,
  "continueOnError": false,
  "children": []
}

children contiene pasos anidados y se usa en loop.

Tipos de paso admitidos

Gratis:

  • tap
  • long_press
  • screenshot
  • open_app
  • open_intent
  • app_function_query
  • app_function_call
  • overlay_show
  • overlay_hide
  • delay
  • set
  • ui_action
  • set_text
  • ui_scroll
  • wait_for_ui
  • loop

Plus:

  • swipe
  • pinch
  • two_finger_swipe
  • rotate

Ejemplos comunes

Tap

{
  "type": "tap",
  "params": { "x": 540, "y": 1200, "duration": 80 }
}

Tap basado en objetivo:

{
  "type": "tap",
  "params": {
    "target": { "text": "Sign in", "role": "button" },
    "mode": "semantic_then_gesture"
  }
}

Swipe (Plus)

{
  "type": "swipe",
  "params": {
    "startX": 540,
    "startY": 1800,
    "endX": 540,
    "endY": 600,
    "duration": 700
  }
}

Screenshot

{
  "type": "screenshot",
  "params": {
    "gridSize": 1,
    "gridUnit": "cm",
    "scale": true
  }
}

Open app

{
  "type": "open_app",
  "params": {
    "packageName": "com.android.settings"
  }
}

Delay

{
  "type": "delay",
  "params": { "ms": 1500 }
}

Consultar y llamar a una AppFunction

app_function_query puede guardar su resultado completo de descubrimiento en una variable de la tarea, y app_function_call puede referenciarla y guardar opcionalmente el valor de retorno decodificado:

{
  "steps": [
    {
      "type": "app_function_query",
      "params": {
        "packageName": "com.example.notes",
        "maxResults": 20,
        "resultVariable": "availableFunctions"
      }
    },
    {
      "type": "app_function_call",
      "params": {
        "packageName": "com.example.notes",
        "functionId": "{{availableFunctions.functions.0.functionId}}",
        "arguments": { "title": "Groceries" },
        "resultVariable": "createdNote"
      }
    }
  ]
}

Estos pasos no requieren accesibilidad. Sí requieren soporte de Android AppFunctions y autorización de Android para longarm y la función de destino.

UI action

{
  "type": "ui_action",
  "params": {
    "selector": { "text": "Continue" },
    "action": "click",
    "fallback": "none"
  }
}

Wait for UI

{
  "type": "wait_for_ui",
  "params": {
    "selector": { "text": "Welcome" },
    "condition": "exists",
    "timeoutMs": 5000,
    "stableForMs": 0
  }
}

Variables

Usa sustitución {{name}} dentro de parámetros string:

{
  "variables": {
    "packageName": "com.android.settings"
  },
  "steps": [
    {
      "type": "open_app",
      "params": { "packageName": "{{packageName}}" }
    }
  ]
}

Un parámetro cuyo valor completo sea un único placeholder {{name}} conserva el tipo JSON original de la variable (número, booleano, objeto) en lugar de convertirlo a string. También se admiten búsquedas anidadas, como {{user.name}}.

Bucles

Los pasos loop ejecutan sus children y admiten cuatro modos:

Conteo fijo:

{
  "type": "loop",
  "params": { "count": 3 },
  "children": [
    { "type": "tap", "params": { "x": 540, "y": 1800 } }
  ]
}

Rango numérico:

{
  "type": "loop",
  "params": { "var": "i", "from": 1, "to": 5, "step": 1 },
  "children": [
    { "type": "delay", "params": { "ms": 250 } }
  ]
}

For-each sobre una lista:

{
  "type": "loop",
  "params": {
    "var": "pkg",
    "in": ["com.android.settings", "com.android.chrome"]
  },
  "children": [
    { "type": "open_app", "params": { "packageName": "{{pkg}}" } }
  ]
}

Bucle tipo while:

{
  "type": "loop",
  "params": { "whileVar": "keepGoing", "max": 10 },
  "children": [
    { "type": "delay", "params": { "ms": 500 } }
  ]
}

Notas: la profundidad de anidamiento de bucles está limitada, un bucle con step: 0 no es válido, y los bucles whileVar requieren max.

Ejemplo completo

{
  "name": "Open Google News and scroll",
  "variables": {
    "packageName": "com.google.android.apps.magazines"
  },
  "steps": [
    {
      "type": "open_app",
      "params": { "packageName": "{{packageName}}" },
      "delayAfterMs": 2500
    },
    {
      "type": "swipe",
      "params": {
        "startX": 540,
        "startY": 1900,
        "endX": 540,
        "endY": 650,
        "duration": 700
      }
    },
    {
      "type": "screenshot",
      "params": { "gridSize": 1, "gridUnit": "cm", "scale": true }
    }
  ]
}

Operaciones REST

Guardar y listar tareas:

  • GET /api/batch
  • POST /api/batch
  • GET /api/batch/<id>
  • PUT /api/batch/<id>
  • DELETE /api/batch/<id>

La validación de la tarea requiere un name y un array steps no vacío.

Ejecutar una tarea: guardada con POST /api/batch/<id>/run, o una tarea inline sin guardar con POST /api/batch/run. Ambas rutas aceptan un booleano opcional keepScreenOn (en el cuerpo JSON, o como parámetro de consulta ?keepScreenOn=true). Cuando es true, longarm mantiene la pantalla encendida durante toda la ejecución y la libera en cuanto la ejecución termina, falla o se detiene — útil para ejecuciones largas que de otro modo activarían el bloqueo de pantalla del dispositivo. Pulsar el botón de encendido sigue apagando la pantalla. Esto coincide con el elemento Screen on del menú de una tarea en la app; por defecto es false para ejecuciones lanzadas por API.

{ "runId": "run_123", "status": "processing" }

Si ya hay otra ejecución activa, el servidor devuelve HTTP 409 Conflict con { "error": "Another batch task is already running" }.

Estado del runner — GET /api/batch/status:

{
  "state": "running",
  "currentTaskId": "bt_123",
  "currentRunId": "run_123",
  "currentStepIndex": 2,
  "totalSteps": 5
}

state es uno de: idle, running, stopping.

Historial de lotes

Lista el historial con GET /api/batch/history, o una ejecución con GET /api/batch/history/<runId>:

{
  "runId": "run_123",
  "taskId": "bt_123",
  "taskName": "Open Google News and scroll",
  "status": "finished",
  "startedAt": "2026-07-13T00:00:00.000Z",
  "endedAt": "2026-07-13T00:00:05.000Z",
  "totalSteps": 3,
  "executedSteps": 3,
  "message": "Completed",
  "screenshots": [
    {
      "id": "shot_1",
      "stepId": "step_3",
      "stepIndex": 3,
      "capturedAt": "2026-07-13T00:00:04.000Z"
    }
  ]
}

Valores de estado de ejecución: processing, finished, failed, aborted.

Elimina historial con DELETE /api/batch/history/<runId> (una ejecución) o DELETE /api/batch/history (todas).

La exportación de capturas requiere Plus:

  • GET /api/batch/history/<runId>/screenshots/<screenshotId> — una sola captura
  • GET /api/batch/history/<runId>/export — todas las capturas como zip

Equivalentes en MCP

Las mismas capacidades de lotes están disponibles a través de herramientas MCP: batch_list, batch_get, batch_save, batch_delete, batch_run, batch_run_inline, batch_status, batch_history_list, batch_history_get, batch_history_export, batch_history_delete.