AutomationFlowsAI & RAG › Automate Assignee Payroll Calculations with Dart, Gemini Ai, and Google Sheets

Automate Assignee Payroll Calculations with Dart, Gemini Ai, and Google Sheets

ByDart @dart-team on n8n.io

This workflow automates billing by scanning a target Dartboard on schedule, aggregating time logs from completed tasks, cross‑referencing assignee rates in Google Sheets, calculating total pay, and updating the sheet with final billable hours and amounts.

Cron / scheduled trigger★★★★☆ complexityAI-powered14 nodesN8N Nodes DartGoogle SheetsGoogle Gemini ChatAgent
AI & RAG Trigger: Cron / scheduled Nodes: 14 Complexity: ★★★★☆ AI nodes: yes Added:

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

This workflow follows the Agent → 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
{
  "id": "D6lfkWs2oDNbZlB7",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "Task\u2011Based Billing via Time Tracking",
  "tags": [],
  "nodes": [
    {
      "id": "cf6f064d-c4a5-4ac3-81fb-b4fe8cbf110e",
      "name": "List tasks",
      "type": "n8n-nodes-dart.dart",
      "position": [
        336,
        0
      ],
      "parameters": {
        "resource": "Task",
        "operation": "List Tasks",
        "requestOptions": {},
        "additionalFields": {
          "dartboard_id": "yccHfZwasnhc"
        }
      },
      "credentials": {
        "dartApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "a9a2c117-2981-4dc8-93d4-f7d811901503",
      "name": "Get row(s) in sheet",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        720,
        0
      ],
      "parameters": {
        "options": {},
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/13mDa4dCMkyq-rQPMCU3k883ZvHiq63RTlj4PzuuAfi0/edit#gid=0",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "13mDa4dCMkyq-rQPMCU3k883ZvHiq63RTlj4PzuuAfi0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/13mDa4dCMkyq-rQPMCU3k883ZvHiq63RTlj4PzuuAfi0/edit?usp=drivesdk",
          "cachedResultName": "Gsheets Timetracking"
        },
        "combineFilters": "OR"
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "c9112e57-9c89-4bb8-98c9-3bfffa550381",
      "name": "Aggregate",
      "type": "n8n-nodes-base.aggregate",
      "position": [
        912,
        0
      ],
      "parameters": {
        "options": {},
        "aggregate": "aggregateAllItemData"
      },
      "typeVersion": 1
    },
    {
      "id": "f6c98556-1d4e-414c-8281-c30009972a19",
      "name": "AI SCANNER",
      "type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
      "position": [
        1296,
        64
      ],
      "parameters": {
        "options": {},
        "modelName": "models/gemini-flash-latest"
      },
      "credentials": {
        "googlePalmApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "a6b7a2e9-ed77-48df-810c-715fce778944",
      "name": "Assignee & Time Scanner",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        1328,
        -96
      ],
      "parameters": {
        "text": "=You are an expert Payroll Calculator. Your goal is to calculate the total hours and final payout for employees based on a provided Rate Card and Task Log.\n\n### INSTRUCTIONS:\n\n1. **Analyze Input A (Rate Card):** Identify the authorized assignees and their specific Hourly Rate.\n\n2. **Analyze Input B (Task Logs):**\n   - Find all tasks assigned to the people listed in Input A (use fuzzy matching for names/emails).\n   - **Filter by Status:** Only include tasks where the \"Status\" is exactly \"Done\". Ignore any tasks with other statuses (e.g., \"In Progress\", \"Todo\").\n   - Extract the duration of each valid task.\n\n3. **Perform Calculations:**\n   - **Sum Duration:** Add up the time spent on the filtered \"Done\" tasks for each person. Convert the final sum into **HOURS** (e.g., if the log says \"90 minutes\", convert it to \"1.5\").\n   - **Calculate Pay:** Multiply the `TotalHours` by the person's `HourlyRate`.\n\n4. **Output Format:**\n   - Return a strictly valid JSON list.\n   - Do NOT list the individual tasks. Only output the aggregates.\n   - **Date Field:** Use the exact date provided in \"INPUT C\" below for the `DateCalculated` field.\n\n### INPUT A: Google Spreadsheet (Rate Card)\n\n\"\"\"\n{{ JSON.stringify($json.data) }}\n\"\"\"\n\n### INPUT B: List of Tasks (Dart Logs)\n\n\"\"\"\n{{ JSON.stringify($('List tasks').item.json.results) }}\n\"\"\"\n\n### INPUT C: Current Date (Use this exact date)\n\n\"\"\"\n{{ $now.toFormat('yyyy-MM-dd') }}\n\"\"\"\n\n### REQUIRED OUTPUT FORMAT (JSON ONLY):\n\n[\n  {\n    \"Name\": \"Employee Name\",\n    \"TotalHours\": 20.5,\n    \"TotalPay\": 10250,\n    \"DateCalculated\": \"2025-09-11\"\n  }\n]",
        "options": {},
        "promptType": "define"
      },
      "typeVersion": 3
    },
    {
      "id": "a322cf36-724b-4c55-a4d7-f011dc93b551",
      "name": "Parse Output",
      "type": "n8n-nodes-base.code",
      "position": [
        1856,
        -64
      ],
      "parameters": {
        "jsCode": "// Get raw input\nlet rawString = $input.first().json.output;\n\n// Clean up markdown formatting if present\nrawString = rawString\n  .trim()\n  .replace(/^```(json)?/i, '')  // remove leading ``` or ```json\n  .replace(/```$/i, '')         // remove trailing ```\n  .trim();\n\n// Try parsing the cleaned string\nlet parsed;\ntry {\n  parsed = JSON.parse(rawString);\n} catch (error) {\n  throw new Error(`Failed to parse JSON. Cleaned input was:\\n${rawString}\\n\\nError: ${error.message}`);\n}\n\nreturn parsed;"
      },
      "typeVersion": 2
    },
    {
      "id": "3f4a509f-1763-4498-a629-e8365df50a33",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -560,
        -336
      ],
      "parameters": {
        "width": 544,
        "height": 608,
        "content": "## Task-YOUR_OPENAI_KEY_HERE Assignee billing via Time Tracking\nThis workflow automates billing by scanning a target Dartboard on schedule, aggregating time logs from completed tasks, cross\u2011referencing assignee rates in Google Sheets, calculating total pay, and updating the sheet with final billable hours and amounts.\n\n### Who's it for\nIndividuals, agencies, companies, and project managers automating payroll or client invoicing from task data.\n\n### How to setup\n- Link your [Dart](https://help.dartai.com/en/articles/12313191-n8n-integration) and Google accounts.\n- Replace the dummy ID in the **List tasks** node with your actual target Dartboard ID.\n- Set your preferred run frequency (e.g., Weekly).\n- Create a Google Sheet with these exact headers: `Name`, `HourlyRate`, `TotalHours`, `TotalPay`, `DateCalculated`.\n- Connect the Sheet nodes to your file. Pre-fill `Name` (matching Dart Assignees exactly) and `HourlyRate` in your Google Spreadsheet.\n- Optional: Add a last header column in the sheet as a Status header to track if the bill is paid or pending.\n\n### Customizing the workflow\n- Choose your AI model for your AI time tracking and assignee scanner\n- Use your own google sheet account and target spreadsheet document\n\n\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "75d9a88e-2c2a-4674-aa7f-f7642103101f",
      "name": "Append row in sheet",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        2304,
        16
      ],
      "parameters": {
        "columns": {
          "value": {},
          "schema": [
            {
              "id": "Name",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "HourlyRate",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "HourlyRate",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "TotalHours",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "TotalHours",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "TotalPay",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "TotalPay",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Currency",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Currency",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Status",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Status",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "autoMapInputData",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/13mDa4dCMkyq-rQPMCU3k883ZvHiq63RTlj4PzuuAfi0/edit#gid=0",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "13mDa4dCMkyq-rQPMCU3k883ZvHiq63RTlj4PzuuAfi0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/13mDa4dCMkyq-rQPMCU3k883ZvHiq63RTlj4PzuuAfi0/edit?usp=drivesdk",
          "cachedResultName": "Gsheets Timetracking"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "5667f473-6178-428c-a7f4-be807d1c3c6d",
      "name": "Schedule Trigger",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        128,
        0
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "weeks",
              "triggerAtHour": 7
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "35165310-b834-448b-bbaa-1146e8a71a2b",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        64,
        -240
      ],
      "parameters": {
        "color": 7,
        "width": 448,
        "height": 432,
        "content": "## 1. Workflow launch through schedule\nTriggered by a preferred schedule (e.g. weekly, monthly, etc...)\n\n### Scanning of tasks\nThis step will scan and list all tasks in the target Dartboard. \n- Main goal is for the AI agent in this workflow to be able to identify tasks that are done and has a time tracking log."
      },
      "typeVersion": 1
    },
    {
      "id": "38bfedda-9295-4b83-b882-2562720f3c58",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        640,
        -240
      ],
      "parameters": {
        "color": 7,
        "width": 448,
        "height": 432,
        "content": "## 2. Gathering of data in the target Spreadsheet\nThis step scans all data in the spreadsheet. Goal is for the AI agent to able to scan for the pre-set column headers, assignee name, and hourly rate."
      },
      "typeVersion": 1
    },
    {
      "id": "1c5cf871-4d3a-4458-8551-8bf4a25a2c9b",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1216,
        -272
      ],
      "parameters": {
        "color": 7,
        "width": 448,
        "height": 480,
        "content": "## 3. AI time tracking calculator agent\nThis agent calculates employee payroll by cross-referencing the connected spreadsheet with Dart task logs. It filters specifically for tasks marked \"Done\", sums the total hours, and calculates the final payout based on the pre-set hourly rates.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "c33ea72c-8b49-4cf4-8d07-c967704eea0f",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1760,
        -208
      ],
      "parameters": {
        "color": 7,
        "width": 304,
        "height": 336,
        "content": "## 4. Parsing the AI output\nParse output into a usable format for the next node.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "a1c2c8ae-ebe5-4092-8b03-9cd137cefc68",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2160,
        -288
      ],
      "parameters": {
        "color": 7,
        "width": 400,
        "height": 480,
        "content": "## 5. Push output into the target Spreadsheet\nThis node will push the output data into the connected google spreadsheet.\n\n### Output each Assignee\n- Total time tracked\n- Total pay that is multiplied with the pre-set hourly rate\n- Date of calculation"
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "b2d7e392-3cf5-4d18-910c-497dc5e3e2f1",
  "connections": {
    "Aggregate": {
      "main": [
        [
          {
            "node": "Assignee & Time Scanner",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "AI SCANNER": {
      "ai_languageModel": [
        [
          {
            "node": "Assignee & Time Scanner",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "List tasks": {
      "main": [
        [
          {
            "node": "Get row(s) in sheet",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse Output": {
      "main": [
        [
          {
            "node": "Append row in sheet",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Schedule Trigger": {
      "main": [
        [
          {
            "node": "List tasks",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get row(s) in sheet": {
      "main": [
        [
          {
            "node": "Aggregate",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Assignee & Time Scanner": {
      "main": [
        [
          {
            "node": "Parse Output",
            "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 automates billing by scanning a target Dartboard on schedule, aggregating time logs from completed tasks, cross‑referencing assignee rates in Google Sheets, calculating total pay, and updating the sheet with final billable hours and amounts.

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

The Multi-Model Agency Content Engine is a high-performance editorial system designed for agencies. It solves the "blank page" problem by alternating between real-world social proof and strategic expe

Google Sheets, Gmail, Google Drive +6
AI & RAG

This workflow automates the complete blog publishing process. It removes manual work from content creation, image generation, category management, and WordPress publishing by using AI and n8n. It help

Google Gemini Chat, Output Parser Structured, Lm Chat Deep Seek +5
AI & RAG

This project is an automated news publisher for LinkedIn. It uses RSS feeds to fetch news, processes the content with the Gemini API to generate precise summaries, and automatically publishes to Linke

Agent, Google Gemini Chat, RSS Feed Read +4
AI & RAG

This template is for clinics, hospitals, care teams, and telemedicine providers who need a structured, automated system for post-surgery follow-up. It helps reduce manual workload while ensuring every

Google Sheets, Telegram, Telegram Trigger +7
AI & RAG

This workflow is the AI analysis and alerting engine for a complete social media monitoring system. It's designed to work with data scraped from X (formerly Twitter) using a tool like the Apify Tweet

Google Sheets, Google Gemini Chat, Google Sheets Tool +4