AutomationFlowsAI & RAG › Multi-agent Android Pipeline

Multi-agent Android Pipeline

Multi-Agent Android Pipeline. Uses httpRequest. Webhook trigger; 13 nodes.

Webhook trigger★★★★☆ complexity13 nodesHTTP Request
AI & RAG Trigger: Webhook Nodes: 13 Complexity: ★★★★☆ Added:

The workflow JSON

Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →

Download .json
{
  "name": "Multi-Agent Android Pipeline",
  "nodes": [
    {
      "parameters": {
        "httpMethod": "POST",
        "path": "android-task",
        "responseMode": "responseNode",
        "options": {}
      },
      "id": "webhook-trigger",
      "name": "Webhook Trigger",
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 1,
      "position": [
        250,
        300
      ]
    },
    {
      "parameters": {
        "functionCode": "// Parse and validate incoming task request\nconst body = $input.item.json.body || $input.item.json;\n\nif (!body.task) {\n  throw new Error('Missing required field: task');\n}\n\nreturn {\n  json: {\n    task: body.task,\n    deviceId: body.device_id || null,\n    priority: body.priority || 'normal',\n    timeout: body.timeout || 120,\n    callbackUrl: body.callback_url || null\n  }\n};"
      },
      "id": "parse-request",
      "name": "Parse Request",
      "type": "n8n-nodes-base.function",
      "typeVersion": 1,
      "position": [
        450,
        300
      ]
    },
    {
      "parameters": {
        "method": "GET",
        "url": "http://localhost:8080/api/v1/devices",
        "options": {}
      },
      "id": "list-devices",
      "name": "List Devices",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4,
      "position": [
        650,
        300
      ]
    },
    {
      "parameters": {
        "conditions": {
          "number": [
            {
              "value1": "={{ $json.count }}",
              "operation": "larger",
              "value2": 0
            }
          ]
        }
      },
      "id": "check-devices",
      "name": "Devices Available?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 1,
      "position": [
        850,
        300
      ]
    },
    {
      "parameters": {
        "functionCode": "// Select best device for task\nconst devices = $input.item.json.devices || [];\nconst requestedDevice = $('Parse Request').item.json.deviceId;\n\nlet selectedDevice = null;\n\n// If specific device requested\nif (requestedDevice) {\n  selectedDevice = devices.find(d => d.id === requestedDevice);\n}\n\n// Otherwise, select first connected device\nif (!selectedDevice) {\n  selectedDevice = devices.find(d => d.status === 'connected');\n}\n\nif (!selectedDevice) {\n  throw new Error('No suitable device available');\n}\n\nreturn {\n  json: {\n    device: selectedDevice,\n    task: $('Parse Request').item.json.task,\n    timeout: $('Parse Request').item.json.timeout\n  }\n};"
      },
      "id": "select-device",
      "name": "Select Device",
      "type": "n8n-nodes-base.function",
      "typeVersion": 1,
      "position": [
        1050,
        200
      ]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "http://localhost:8080/api/v1/tasks",
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={\n  \"description\": \"{{ $json.task }}\",\n  \"device_id\": \"{{ $json.device.id }}\",\n  \"timeout\": {{ $json.timeout }},\n  \"webhook_url\": \"{{ $('Parse Request').item.json.callbackUrl }}\"\n}",
        "options": {
          "timeout": 30000
        }
      },
      "id": "create-task",
      "name": "Create Task",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4,
      "position": [
        1250,
        200
      ]
    },
    {
      "parameters": {
        "loopCount": 30,
        "options": {
          "reset": false
        }
      },
      "id": "poll-loop",
      "name": "Poll Loop",
      "type": "n8n-nodes-base.splitInBatches",
      "typeVersion": 3,
      "position": [
        1450,
        200
      ]
    },
    {
      "parameters": {
        "amount": 2,
        "unit": "seconds"
      },
      "id": "poll-wait",
      "name": "Poll Wait",
      "type": "n8n-nodes-base.wait",
      "typeVersion": 1,
      "position": [
        1650,
        200
      ]
    },
    {
      "parameters": {
        "method": "GET",
        "url": "=http://localhost:8080/api/v1/tasks/{{ $('Create Task').item.json.task.id }}",
        "options": {}
      },
      "id": "get-status",
      "name": "Get Status",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4,
      "position": [
        1850,
        200
      ]
    },
    {
      "parameters": {
        "conditions": {
          "string": [
            {
              "value1": "={{ $json.task.status }}",
              "operation": "contains",
              "value2": "completed"
            }
          ]
        }
      },
      "id": "is-complete",
      "name": "Is Complete?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 1,
      "position": [
        2050,
        200
      ]
    },
    {
      "parameters": {
        "functionCode": "// Format successful response\nconst task = $input.item.json.task;\nconst result = task.result || {};\n\nreturn {\n  json: {\n    status: 'success',\n    taskId: task.id,\n    deviceId: task.device_id,\n    description: task.description,\n    executionTime: result.duration_seconds,\n    steps: result.steps || [],\n    screenshot: result.final_screenshot,\n    timestamp: new Date().toISOString()\n  }\n};"
      },
      "id": "format-success",
      "name": "Format Success",
      "type": "n8n-nodes-base.function",
      "typeVersion": 1,
      "position": [
        2250,
        100
      ]
    },
    {
      "parameters": {
        "respondWith": "json",
        "responseBody": "={{ $json }}",
        "options": {}
      },
      "id": "respond-success",
      "name": "Respond Success",
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1,
      "position": [
        2450,
        100
      ]
    },
    {
      "parameters": {
        "respondWith": "json",
        "responseBody": "={\n  \"status\": \"error\",\n  \"message\": \"No devices available\"\n}",
        "options": {
          "responseCode": 503
        }
      },
      "id": "no-devices-response",
      "name": "No Devices Response",
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1,
      "position": [
        1050,
        400
      ]
    }
  ],
  "connections": {
    "Webhook Trigger": {
      "main": [
        [
          {
            "node": "Parse Request",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse Request": {
      "main": [
        [
          {
            "node": "List Devices",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "List Devices": {
      "main": [
        [
          {
            "node": "Devices Available?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Devices Available?": {
      "main": [
        [
          {
            "node": "Select Device",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "No Devices Response",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Select Device": {
      "main": [
        [
          {
            "node": "Create Task",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Create Task": {
      "main": [
        [
          {
            "node": "Poll Loop",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Poll Loop": {
      "main": [
        [
          {
            "node": "Poll Wait",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Poll Wait": {
      "main": [
        [
          {
            "node": "Get Status",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Status": {
      "main": [
        [
          {
            "node": "Is Complete?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Is Complete?": {
      "main": [
        [
          {
            "node": "Format Success",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Poll Loop",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Format Success": {
      "main": [
        [
          {
            "node": "Respond Success",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {
    "executionOrder": "v1"
  },
  "staticData": null,
  "tags": [
    "android",
    "automation",
    "gelab",
    "multi-agent"
  ],
  "triggerCount": 0,
  "updatedAt": "2025-01-01T00:00:00.000Z",
  "versionId": "1"
}
Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

Multi-Agent Android Pipeline. Uses httpRequest. Webhook trigger; 13 nodes.

Source: https://github.com/thamizhelango/droid-flow/blob/e9dafcd70af69e1a7d8868816a26a93470965bfa/n8n-workflows/multi-agent-pipeline.json — original creator credit. Request a take-down →

More AI & RAG workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

AI & RAG

Jigsaw API key for image processing, I use this as a gatekeeper/second pair of eyes. LINK to their website https://jigsawstack.com/ SECOND A postgress DATABASE (I use Supabase) LlamaCloud for the pars

HTTP Request, Postgres, Stop And Error +2
AI & RAG

Onsite Photos to Jobs (SMS Agent). Uses dataTable, twilio, httpRequest, airtable. Webhook trigger; 62 nodes.

Data Table, Twilio, HTTP Request +1
AI & RAG

AML Alert Triage. Uses httpRequest. Webhook trigger; 57 nodes.

HTTP Request
AI & RAG

W1 - IN WhatsApp Adapter (Secure + Fast ACK). Uses postgres, redis, httpRequest. Webhook trigger; 50 nodes.

Postgres, Redis, HTTP Request
AI & RAG

W1 - IN WhatsApp Adapter (Secure + Fast ACK). Uses postgres, redis, httpRequest. Webhook trigger; 48 nodes.

Postgres, Redis, HTTP Request