AutomationFlowsAI & RAG › Classify Apify Scraped Dataset Rows with Openai and Google Sheets

Classify Apify Scraped Dataset Rows with Openai and Google Sheets

ByAbu @abu-rebooting on n8n.io

This workflow runs on demand to classify up to 1,000 items from an Apify dataset using OpenAI via the glueworks/llm-dataset-processor Actor, then upserts each item’s id, title, url, and category into a Google Sheets spreadsheet. Starts when you manually execute the workflow.…

Event trigger★★★★☆ complexity9 nodes@Apify/N8N Nodes ApifyGoogle Sheets
AI & RAG Trigger: Event Nodes: 9 Complexity: ★★★★☆ Added:

This workflow corresponds to n8n.io template #17559 — we link there as the canonical source.

This workflow follows the Apifyn8N Nodes Apify → Google Sheets recipe pattern — see all workflows that pair these two integrations.

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
{
  "meta": {
    "templateCredsSetupCompleted": false
  },
  "name": "Batch-classify & score scraped data with an LLM \u2192 Google Sheets",
  "nodes": [
    {
      "id": "2ecc26d3-4da9-4cfd-9ef2-52d4ef1ef4e0",
      "name": "When clicking Test",
      "type": "n8n-nodes-base.manualTrigger",
      "position": [
        240,
        300
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "07a18a92-4c13-4d3a-a725-ad4c7d069fcf",
      "name": "Configuration",
      "type": "n8n-nodes-base.set",
      "position": [
        460,
        300
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "bde88599-1a94-49c4-89c3-f70cc698508a",
              "name": "upstream_dataset_id",
              "type": "string",
              "value": "REPLACE_WITH_YOUR_APIFY_DATASET_ID"
            },
            {
              "id": "c5599341-0000-449b-884f-c0773011ed72",
              "name": "sheet_document_id",
              "type": "string",
              "value": "REPLACE_WITH_GOOGLE_SHEET_ID"
            },
            {
              "id": "817efcdc-b9e3-4b36-b329-f4c1049adb89",
              "name": "openai_model",
              "type": "string",
              "value": "gpt-4o-mini"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "06eadb32-61ae-4748-b050-70da41bbc1e5",
      "name": "Classify rows with LLM (Apify)",
      "type": "@apify/n8n-nodes-apify.apify",
      "position": [
        700,
        300
      ],
      "parameters": {
        "actorId": {
          "__rl": true,
          "mode": "list",
          "value": "glueworks~llm-dataset-processor",
          "cachedResultUrl": "https://console.apify.com/actors/glueworks~llm-dataset-processor/input",
          "cachedResultName": "glueworks/llm-dataset-processor"
        },
        "timeout": {},
        "customBody": "={\n  \"datasetId\": \"{{ $json.upstream_dataset_id }}\",\n  \"mode\": \"classify\",\n  \"prompt\": \"Classify this item into exactly one category: LEAD, SPAM, or NEUTRAL. Item: {{_json}}\",\n  \"provider\": \"openai\",\n  \"model\": \"{{ $json.openai_model }}\",\n  \"outputField\": \"category\",\n  \"maxItems\": 1000,\n  \"concurrency\": 4\n}",
        "actorSource": "store",
        "waitForFinish": true
      },
      "credentials": {
        "apifyApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "db68e8f4-a385-48b0-80b6-d5c161d42527",
      "name": "Get processed rows",
      "type": "@apify/n8n-nodes-apify.apify",
      "position": [
        920,
        300
      ],
      "parameters": {
        "limit": {},
        "offset": {},
        "resource": "Datasets",
        "datasetId": "={{ $json.defaultDatasetId }}",
        "operation": "Get items"
      },
      "credentials": {
        "apifyApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "7d06784b-4828-4b4f-94aa-06983fbb34c4",
      "name": "Save to Google Sheets",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        1140,
        300
      ],
      "parameters": {
        "columns": {
          "value": {
            "id": "={{ $json.id }}",
            "url": "={{ $json.url }}",
            "title": "={{ $json.title }}",
            "category": "={{ $json.category }}"
          },
          "schema": [
            {
              "id": "id",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "id",
              "defaultMatch": true,
              "canBeUsedToMatch": true
            },
            {
              "id": "title",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "title",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "url",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "url",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "category",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "category",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "id"
          ]
        },
        "options": {},
        "operation": "appendOrUpdate",
        "sheetName": {
          "__rl": true,
          "mode": "id",
          "value": "Sheet1",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $('Configuration').first().json.sheet_document_id }}"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "f2dc81e2-4859-49ee-8af7-d23ffeeecc1b",
      "name": "note-title",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        240,
        -60
      ],
      "parameters": {
        "color": 4,
        "width": 900,
        "height": 300,
        "content": "# Batch-classify scraped data with an LLM \u2192 Google Sheets\n\nTakes the dataset from ANY upstream Apify scraper, classifies/scores/labels every row with an LLM using **glueworks/llm-dataset-processor**, and upserts the results into a Google Sheet.\n\n**Setup:** add Apify + Google Sheets credentials, paste your upstream dataset ID and Sheet ID into the Configuration node, edit the classification prompt."
      },
      "typeVersion": 1
    },
    {
      "id": "dbef0566-4a08-4831-ae0e-fbdbdb6feb0a",
      "name": "note-1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        240,
        560
      ],
      "parameters": {
        "color": 7,
        "width": 440,
        "height": 220,
        "content": "## 1. Point at your scraped data\nPut the **dataset ID** of any Apify scraper run (Google Maps, LinkedIn, Instagram, your own crawler\u2026) into the Configuration node. This template is the AI 'downstream' stage."
      },
      "typeVersion": 1
    },
    {
      "id": "dcf1656f-2045-4912-852d-676aac45e851",
      "name": "note-2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        700,
        560
      ],
      "parameters": {
        "color": 7,
        "width": 440,
        "height": 240,
        "content": "## 2. LLM processes every row\nThe Actor runs your prompt over each row (modes: classify / score / extract / rewrite / custom). Result is written to a new field (`category` here). `{{field}}` / `{{_json}}` inject row values into the prompt."
      },
      "typeVersion": 1
    },
    {
      "id": "48cad57d-c475-4eb9-8b1f-a8da9bef2000",
      "name": "note-3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1140,
        560
      ],
      "parameters": {
        "color": 7,
        "width": 360,
        "height": 200,
        "content": "## 3. Upsert to Sheets\nappendOrUpdate keyed on `id` so re-runs update rather than duplicate. Point it at Airtable instead if you prefer."
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "connections": {
    "Configuration": {
      "main": [
        [
          {
            "node": "Classify rows with LLM (Apify)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get processed rows": {
      "main": [
        [
          {
            "node": "Save to Google Sheets",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "When clicking Test": {
      "main": [
        [
          {
            "node": "Configuration",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Classify rows with LLM (Apify)": {
      "main": [
        [
          {
            "node": "Get processed rows",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}

Credentials you'll need

Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.

Pro

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

About this workflow

This workflow runs on demand to classify up to 1,000 items from an Apify dataset using OpenAI via the glueworks/llm-dataset-processor Actor, then upserts each item’s id, title, url, and category into a Google Sheets spreadsheet. Starts when you manually execute the workflow.…

Source: https://n8n.io/workflows/17559/ — 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

Analyze Amazon product reviews with Gemini and save to Google Sheets

Slack, Google Sheets, Google Gemini +1
AI & RAG

Accountants and office managers who want to automatically classify and organize documents in Google Drive.

Google Drive, HTTP Request, Google Sheets +2
AI & RAG

This workflow collects an invoice PDF via an n8n Form, extracts text from the PDF, uses OpenAI to convert it into structured invoice JSON, logs invoice headers and line items to Google Sheets, validat

Form Trigger, HTTP Request, Google Sheets +1
AI & RAG

Extract title deed data and score risk factors with AI. Uses googleDriveTrigger, googleDrive, n8n-nodes-pdfvector, googleSheets. Event-driven trigger; 10 nodes.

Google Drive Trigger, Google Drive, N8N Nodes Pdfvector +2
AI & RAG

W11 - Meeting Notes & Action Item Extractor. Uses googleDriveTrigger, googleDrive, n8n-nodes-pdfvector, googleSheets. Event-driven trigger; 9 nodes.

Google Drive Trigger, Google Drive, N8N Nodes Pdfvector +2