AutomationFlowsAI & RAG › AI Report Agent for Google Drive & Sheets

AI Report Agent for Google Drive & Sheets

Original n8n title: Report Agent Workflow

REPORT Agent Workflow. Uses googleDrive, chainLlm, lmChatGoogleGemini, googleSheets. Event-driven trigger; 25 nodes.

Event trigger★★★★☆ complexityAI-powered25 nodesGoogle DriveChain LlmGoogle Gemini ChatGoogle Sheets
AI & RAG Trigger: Event Nodes: 25 Complexity: ★★★★☆ AI nodes: yes Added:

This workflow follows the Chainllm → Google Drive 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
{
  "name": "REPORT Agent Workflow",
  "nodes": [
    {
      "parameters": {},
      "id": "manual_trigger_report",
      "name": "Manual Trigger",
      "type": "n8n-nodes-base.manualTrigger",
      "typeVersion": 1,
      "position": [
        1856,
        96
      ]
    },
    {
      "parameters": {
        "resource": "fileFolder",
        "searchMethod": "query",
        "queryString": "'YOUR_GOLD_FOLDER_ID' in parents and mimeType!='application/vnd.google-apps.folder'",
        "returnAll": true,
        "filter": {},
        "options": {}
      },
      "type": "n8n-nodes-base.googleDrive",
      "typeVersion": 3,
      "position": [
        2192,
        -144
      ],
      "id": "list_gold_files",
      "name": "Google Drive \u2014 List Files (GOLD folder)",
      "credentials": {
        "googleDriveOAuth2Api": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "resource": "fileFolder",
        "searchMethod": "query",
        "queryString": "'YOUR_CLEAN_FOLDER_ID' in parents",
        "returnAll": true,
        "filter": {},
        "options": {}
      },
      "type": "n8n-nodes-base.googleDrive",
      "typeVersion": 3,
      "position": [
        2176,
        272
      ],
      "id": "list_clean_files",
      "name": "Google Drive \u2014 List Files (CLEAN folder)",
      "credentials": {
        "googleDriveOAuth2Api": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "operation": "download",
        "fileId": {
          "__rl": true,
          "value": "={{ $json[\"id\"] }}",
          "mode": "id"
        },
        "options": {}
      },
      "type": "n8n-nodes-base.googleDrive",
      "typeVersion": 3,
      "position": [
        2640,
        -144
      ],
      "id": "download_gold",
      "name": "Google Drive \u2014 Download Gold file",
      "credentials": {
        "googleDriveOAuth2Api": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "options": {}
      },
      "type": "n8n-nodes-base.splitInBatches",
      "typeVersion": 3,
      "position": [
        2496,
        272
      ],
      "id": "split_clean_batches",
      "name": "Split In Batches \u2014 FOR EACH CLEAN FILE"
    },
    {
      "parameters": {
        "operation": "download",
        "fileId": {
          "__rl": true,
          "value": "={{ $json[\"id\"] }}",
          "mode": "id"
        },
        "options": {}
      },
      "type": "n8n-nodes-base.googleDrive",
      "typeVersion": 3,
      "position": [
        2736,
        512
      ],
      "id": "download_clean",
      "name": "Google Drive \u2014 Download CLEAN file",
      "credentials": {
        "googleDriveOAuth2Api": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "rules": {
          "values": [
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict",
                  "version": 2
                },
                "conditions": [
                  {
                    "leftValue": "={{ $binary.data.mimeType }}",
                    "rightValue": "text/csv",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "id": "csv_condition"
                  }
                ],
                "combinator": "and"
              }
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict",
                  "version": 2
                },
                "conditions": [
                  {
                    "id": "json_condition",
                    "leftValue": "={{ $binary.data.mimeType }}",
                    "rightValue": "application/json",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    }
                  }
                ],
                "combinator": "and"
              }
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict",
                  "version": 2
                },
                "conditions": [
                  {
                    "id": "txt_condition",
                    "leftValue": "={{ $binary.data.mimeType }}",
                    "rightValue": "text/plain",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    }
                  }
                ],
                "combinator": "and"
              }
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.switch",
      "typeVersion": 3.3,
      "position": [
        2960,
        656
      ],
      "id": "switch_file_type",
      "name": "Switch \u2014 File Type (by mimeType)"
    },
    {
      "parameters": {
        "options": {}
      },
      "type": "n8n-nodes-base.extractFromFile",
      "typeVersion": 1,
      "position": [
        3168,
        -144
      ],
      "id": "extract_gold_csv",
      "name": "Extract from CSV File from GOLD"
    },
    {
      "parameters": {
        "options": {}
      },
      "type": "n8n-nodes-base.extractFromFile",
      "typeVersion": 1,
      "position": [
        3232,
        480
      ],
      "id": "extract_clean_csv",
      "name": "Extract from CSV File from CLEAN"
    },
    {
      "parameters": {
        "operation": "fromJson",
        "options": {}
      },
      "type": "n8n-nodes-base.extractFromFile",
      "typeVersion": 1,
      "position": [
        3232,
        672
      ],
      "id": "extract_clean_json",
      "name": "Extract from JSON File from CLEAN"
    },
    {
      "parameters": {
        "operation": "text",
        "options": {}
      },
      "type": "n8n-nodes-base.extractFromFile",
      "typeVersion": 1,
      "position": [
        3232,
        848
      ],
      "id": "extract_clean_txt",
      "name": "Extract from TXT File from CLEAN"
    },
    {
      "parameters": {
        "jsCode": "const fileMeta = $node[\"Google Drive \u2014 Download CLEAN file\"].json;\n\nconst rows = items.map(i => i.json);\nconst sampleRows = rows.slice(0, 5);\n\nreturn [{\n  json: {\n    fileName: fileMeta.name,\n    mimeType: fileMeta.mimeType,\n    source: \"csv\",\n    rowCount: rows.length,\n    sampleRows,\n  }\n}];"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        3472,
        480
      ],
      "id": "build_csv_sample",
      "name": "Function \u2014 Build Sample (CSV)"
    },
    {
      "parameters": {
        "jsCode": "const fileMeta = $node[\"Google Drive \u2014 Download CLEAN file\"].json;\n\nconst rows = items.map(i => i.json);\nconst sampleRows = rows.slice(0, 5);\n\nreturn [{\n  json: {\n    fileName: fileMeta.name,\n    mimeType: fileMeta.mimeType,\n    source: \"json\",\n    rowCount: rows.length,\n    sampleRows,\n  }\n}];"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        3472,
        672
      ],
      "id": "build_json_sample",
      "name": "Function \u2014 Build Sample (JSON)"
    },
    {
      "parameters": {
        "jsCode": "const fileMeta = $node[\"Google Drive \u2014 Download CLEAN file\"].json;\n\nconst raw = items[0].json.data ?? items[0].json ?? \"\";\n\nlet text;\nif (typeof raw === 'string') {\n  text = raw;\n} else {\n  text = JSON.stringify(raw, null, 2);\n}\n\nreturn [{\n  json: {\n    fileName: fileMeta.name,\n    mimeType: fileMeta.mimeType,\n    source: \"txt\",\n    textPreview: text.slice(0, 2000)\n  }\n}];"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        3472,
        848
      ],
      "id": "build_txt_sample",
      "name": "Function \u2014 Build Sample (TXT)"
    },
    {
      "parameters": {
        "numberInputs": 3
      },
      "type": "n8n-nodes-base.merge",
      "typeVersion": 3.2,
      "position": [
        3824,
        896
      ],
      "id": "merge_clean_samples",
      "name": "Merge \u2014 CLEAN Samples"
    },
    {
      "parameters": {
        "jsCode": "const item = (items[0] && items[0].json) || {};\n\nconst kpis = {};\n\nif (item.kpis && typeof item.kpis === 'object') {\n  for (const [metric, raw] of Object.entries(item.kpis)) {\n    let value = raw;\n    if (typeof value === 'string') {\n      const n = Number(value);\n      value = isNaN(n) ? value : n;\n    }\n    kpis[metric] = value;\n  }\n} else {\n  for (const key of Object.keys(item)) {\n    if (!key.startsWith('kpis.')) continue;\n    const metric = key.slice('kpis.'.length);\n    let value = item[key];\n    if (typeof value === 'string') {\n      const n = Number(value);\n      value = isNaN(n) ? value : n;\n    }\n    kpis[metric] = value;\n  }\n}\n\nconst summary = item.summary || null;\nconst fileMeta = $node[\"Google Drive \u2014 Download Gold file\"].json;\n\nreturn [{\n  json: {\n    kpis,\n    kpiSource: {\n      fileName: fileMeta.name,\n      fileId: fileMeta.id,\n    },\n    summary,\n  }\n}];"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        3664,
        -144
      ],
      "id": "build_kpi_object",
      "name": "Function \u2014 Build KPI Object from GOLD"
    },
    {
      "parameters": {
        "jsCode": "const samples = $input.all().map(i => i.json);\n\nreturn [{\n  json: {\n    cleanSummary: {\n      fileCount: samples.length,\n      files: samples,\n    }\n  }\n}];"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        3664,
        256
      ],
      "id": "unified_clean_summary",
      "name": "Function \u2014 Unified CLEAN Summary"
    },
    {
      "parameters": {
        "mode": "combine",
        "combineBy": "combineByPosition",
        "options": {}
      },
      "type": "n8n-nodes-base.merge",
      "typeVersion": 3.2,
      "position": [
        3952,
        112
      ],
      "id": "merge_kpi_clean",
      "name": "Merge \u2014 KPI + CLEAN Summary"
    },
    {
      "parameters": {
        "promptType": "define",
        "text": "Stub prompt \u2013 use chat messages below.",
        "messages": {
          "messageValues": [
            {
              "message": "You are the REPORT AI agent inside the Personal AI Factory v1 (ANIS). You receive one JSON object with: kpis (numeric metrics), kpiSource (metadata), summary (plain text hint), and cleanSummary (fileCount and files array). Rules: Use kpis as the only numeric truth source. Do not invent numbers. Do not infer KPIs from cleanSummary sampleRows. Do not use external knowledge. Output (plain text, no JSON, no markdown): 1) KPI Overview, 2) Data Processed, 3) Key Insights (3-5 bullet-style sentences starting with '-'), 4) Recommended Actions (3-5 action-oriented sentences). Tone: professional, concise, business-focused."
            },
            {
              "type": "text",
              "message": "=Here is the merged JSON for today's report:\n\n{{ JSON.stringify($json, null, 2) }}\n\nGenerate the report according to the system instructions."
            }
          ]
        },
        "batching": {}
      },
      "type": "@n8n/n8n-nodes-langchain.chainLlm",
      "typeVersion": 1.7,
      "position": [
        4160,
        112
      ],
      "id": "llm_chain",
      "name": "Basic LLM Chain"
    },
    {
      "parameters": {
        "options": {}
      },
      "type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
      "typeVersion": 1,
      "position": [
        4256,
        368
      ],
      "id": "gemini_model",
      "name": "Google Gemini Chat Model",
      "credentials": {
        "googlePalmApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "const geminiOutput = $json.text || \"\";\n\nconst d = new Date();\nconst year = d.getFullYear();\nconst month = String(d.getMonth() + 1).padStart(2, \"0\");\nconst day = String(d.getDate()).padStart(2, \"0\");\nconst today = `${year}-${month}-${day}`;\n\nconst reportFileName = `${today}_REPORT.txt`;\n\nreturn [{\n  json: {\n    reportText: geminiOutput,\n    reportFileName,\n  }\n}];"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        4480,
        112
      ],
      "id": "format_report",
      "name": "Function \u2014 Format REPORT"
    },
    {
      "parameters": {
        "operation": "toText",
        "sourceProperty": "reportText",
        "options": {}
      },
      "type": "n8n-nodes-base.convertToFile",
      "typeVersion": 1.1,
      "position": [
        4688,
        112
      ],
      "id": "convert_txt",
      "name": "Convert to TXT File"
    },
    {
      "parameters": {
        "name": "={{ $node[\"Function \u2014 Format REPORT\"].json[\"reportFileName\"] }}",
        "driveId": {
          "__rl": true,
          "mode": "list",
          "value": "My Drive"
        },
        "folderId": {
          "__rl": true,
          "value": "YOUR_REPORT_FOLDER_ID",
          "mode": "id"
        },
        "options": {}
      },
      "type": "n8n-nodes-base.googleDrive",
      "typeVersion": 3,
      "position": [
        4912,
        112
      ],
      "id": "upload_report",
      "name": "Google Drive \u2014 Upload to REPORT folder",
      "credentials": {
        "googleDriveOAuth2Api": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "operation": "append",
        "documentId": {
          "__rl": true,
          "value": "YOUR_SPREADSHEET_ID",
          "mode": "list",
          "cachedResultName": "AI_Factory_Control"
        },
        "sheetName": {
          "__rl": true,
          "value": "YOUR_SHEET_ID",
          "mode": "list",
          "cachedResultName": "EVENT_LOG"
        },
        "columns": {
          "mappingMode": "defineBelow",
          "value": {
            "ts": "={{ $now }}",
            "agent": "report",
            "input": "={{ $node[\"Function \u2014 Format REPORT\"].json[\"reportFileName\"] }}",
            "output": "={{ $node[\"Google Drive \u2014 Upload to REPORT folder\"].json[\"webViewLink\"] }}",
            "notes": "Generated KPI summary and uploaded TXT to REPORT folder",
            "status": "success",
            "action": "generate_report"
          },
          "matchingColumns": [],
          "schema": [
            {
              "id": "ts",
              "displayName": "ts",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "agent",
              "displayName": "agent",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "action",
              "displayName": "action",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "input",
              "displayName": "input",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "output",
              "displayName": "output",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "status",
              "displayName": "status",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "notes",
              "displayName": "notes",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            }
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {}
      },
      "type": "n8n-nodes-base.googleSheets",
      "typeVersion": 4.7,
      "position": [
        5136,
        112
      ],
      "id": "append_event_log",
      "name": "Google Sheets \u2014 Append EVENT_LOG",
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "content": "REPORT Agent - Independent Workflow",
        "height": 1440,
        "width": 3696,
        "color": 4
      },
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1728,
        -256
      ],
      "typeVersion": 1,
      "id": "sticky_note",
      "name": "Sticky Note"
    }
  ],
  "connections": {
    "Manual Trigger": {
      "main": [
        [
          {
            "node": "Google Drive \u2014 List Files (GOLD folder)",
            "type": "main",
            "index": 0
          },
          {
            "node": "Google Drive \u2014 List Files (CLEAN folder)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Google Drive \u2014 List Files (GOLD folder)": {
      "main": [
        [
          {
            "node": "Google Drive \u2014 Download Gold file",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Google Drive \u2014 List Files (CLEAN folder)": {
      "main": [
        [
          {
            "node": "Split In Batches \u2014 FOR EACH CLEAN FILE",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Google Drive \u2014 Download Gold file": {
      "main": [
        [
          {
            "node": "Extract from CSV File from GOLD",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Split In Batches \u2014 FOR EACH CLEAN FILE": {
      "main": [
        [
          {
            "node": "Function \u2014 Unified CLEAN Summary",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Google Drive \u2014 Download CLEAN file",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Google Drive \u2014 Download CLEAN file": {
      "main": [
        [
          {
            "node": "Switch \u2014 File Type (by mimeType)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Switch \u2014 File Type (by mimeType)": {
      "main": [
        [
          {
            "node": "Extract from CSV File from CLEAN",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Extract from JSON File from CLEAN",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Extract from TXT File from CLEAN",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract from CSV File from GOLD": {
      "main": [
        [
          {
            "node": "Function \u2014 Build KPI Object from GOLD",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract from CSV File from CLEAN": {
      "main": [
        [
          {
            "node": "Function \u2014 Build Sample (CSV)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract from JSON File from CLEAN": {
      "main": [
        [
          {
            "node": "Function \u2014 Build Sample (JSON)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract from TXT File from CLEAN": {
      "main": [
        [
          {
            "node": "Function \u2014 Build Sample (TXT)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Function \u2014 Build Sample (CSV)": {
      "main": [
        [
          {
            "node": "Merge \u2014 CLEAN Samples",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Function \u2014 Build Sample (JSON)": {
      "main": [
        [
          {
            "node": "Merge \u2014 CLEAN Samples",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Function \u2014 Build Sample (TXT)": {
      "main": [
        [
          {
            "node": "Merge \u2014 CLEAN Samples",
            "type": "main",
            "index": 2
          }
        ]
      ]
    },
    "Merge \u2014 CLEAN Samples": {
      "main": [
        [
          {
            "node": "Split In Batches \u2014 FOR EACH CLEAN FILE",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Function \u2014 Build KPI Object from GOLD": {
      "main": [
        [
          {
            "node": "Merge \u2014 KPI + CLEAN Summary",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Function \u2014 Unified CLEAN Summary": {
      "main": [
        [
          {
            "node": "Merge \u2014 KPI + CLEAN Summary",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Merge \u2014 KPI + CLEAN Summary": {
      "main": [
        [
          {
            "node": "Basic LLM Chain",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Basic LLM Chain": {
      "main": [
        [
          {
            "node": "Function \u2014 Format REPORT",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Google Gemini Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "Basic LLM Chain",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Function \u2014 Format REPORT": {
      "main": [
        [
          {
            "node": "Convert to TXT File",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Convert to TXT File": {
      "main": [
        [
          {
            "node": "Google Drive \u2014 Upload to REPORT folder",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Google Drive \u2014 Upload to REPORT folder": {
      "main": [
        [
          {
            "node": "Google Sheets \u2014 Append EVENT_LOG",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "tags": []
}

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

REPORT Agent Workflow. Uses googleDrive, chainLlm, lmChatGoogleGemini, googleSheets. Event-driven trigger; 25 nodes.

Source: https://github.com/anshwysmcbel2710/anis-personal-ai-factory-controller/blob/main/workflows/agents/report_agent.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

This n8n template demonstrates how to create an automated emotional story generation system that produces structured video prompts and generates corresponding images using AI. The workflow creates a c

Google Drive, Output Parser Structured, Chain Llm +3
AI & RAG

Generate AI images using Pollinations API, or Generate blog articles using Gemini AI

Google Gemini Chat, Telegram Trigger, Telegram +4
AI & RAG

REPORT Agent Sub-Workflow. Uses executeWorkflowTrigger, googleDrive, lmChatGoogleGemini, chainLlm. Event-driven trigger; 25 nodes.

Execute Workflow Trigger, Google Drive, Google Gemini Chat +2
AI & RAG

🚀 AI Resume Screener (n8n Workflow Template)

Form Trigger, Information Extractor, Chain Summarization +5
AI & RAG

How it works Reads product image links from a Google Sheet. Analyzes each image, generates an AI prompt, and combines the product with a human model image. Creates final AI advertising photos and: Sav

Google Sheets, HTTP Request, Chain Llm +3