{
  "workflow": {
    "id": 9837,
    "name": "Auto-generate developer invoices & compliance reminders with Jira and Gmail",
    "views": 73,
    "recentViews": 0,
    "totalViews": 73,
    "createdAt": "2025-10-17T12:42:47.654Z",
    "description": "## 📘 Description\nThis automation streamlines developer billing and compliance tracking by integrating Jira, Gmail, and n8n into a single intelligent workflow.\n It fetches all project issues from Jira, calculates logged hours per team member, identifies missing time entries, and automatically generates professional invoice summaries — complete with text attachments — which are then emailed to each developer.\nThe system ensures no time logs are missed, billing remains accurate, and finance teams receive transparent, auditable records — all without manual follow-ups.\n\n## ⚙️ What This Workflow Does (Step-by-Step)\n\n🟢 When Clicking ‘Execute Workflow’\nStarts the entire billing and compliance cycle manually or on schedule.\n\n📋 Fetch All Project Issues with Time Data\nRetrieves all Jira issues across projects, including:\n- Time spent (seconds → hours)\n- Assignee, project, sprint, and status info\n- Priority and issue summaries\n-  This serves as the foundation for billing calculations and compliance checks.\n\n📊 Aggregate Hours by Team Member\nGroups issues by assignee and calculates total hours logged per person.\n Outputs per-user data with:\n- Name & email\n- Total logged hours\n- Full issue breakdown (status, sprint, priority)\n-  Forms the core dataset for both invoice creation and reminder logic.\n\n⚠️ Identify Issues with Missing Time Logs\nScans aggregated data to find issues where time = 0 hours.\n Generates HTML reminders with:\n- Table of unlogged issues (key, summary, sprint, status)\n- Personalized note urging time entry completion\n-  Only sends reminders to users who actually missed logs.\n-  Prevents manual follow-up and ensures billing accuracy.\n\n💰 Generate Invoice Summary with Text Attachment\nCreates text-based invoice documents for each user with logged hours.\n Includes:\n- Itemized issue breakdowns\n- Hourly rate (default: $50/hr)\n- Total hours & billing amount\n- Auto-generated timestamp\n-  Exports invoices as text attachments (Invoice_{Assignee}.txt) in base64.\n\n🔗 Combine Reminder & Invoice Data Streams\nMerges invoice data and reminder data into one unified stream, ensuring:\n- All users (with or without logged hours) are processed\n- Emails contain correct context and attachments\n-  Enables complete communication coverage in a single workflow.\n\n🔧 Reconcile JSON & Binary Attachments\n- Smartly merges JSON email metadata and binary invoice files post-merge.\n-  Handles complex data cases (missing binary or JSON) using fallback logic.\n-  Guarantees each email has a valid recipient and invoice attachment.\n\n📧 Send Invoices & Reminders to Team\nSends personalized emails to each developer with:\n- Subject: project name\n- Body: hours summary & reminder message\n- Attachment: invoice text file (if available)\n-  Emails are automatically delivered via Gmail with audit trails.\n\n## 🧩 Prerequisites\nJira Software Cloud API credentials\nGmail OAuth2 connection\nConfigured hourly billing rate (default: $50/hr)\nActive n8n instance (self-hosted or cloud)\n\n## 💡 Key Benefits\n ✅ Eliminates manual invoice generation\n ✅ Ensures accurate time tracking & compliance\n ✅ Sends automated reminders for missing hours\n ✅ Provides transparent, auditable billing communication\n ✅ Saves finance & project teams hours of manual effort\n\n## 👥 Perfect For\n- Tech & IT service companies billing by developer hours\n- Project managers tracking time compliance\n- Finance teams ensuring timely invoicing\n- Agencies managing multiple sprint-based projects",
    "workflow": {
      "id": "VyFk3RnfdN7deOBG",
      "meta": {
        "instanceId": "8443f10082278c46aa5cf3acf8ff0f70061a2c58bce76efac814b16290845177",
        "templateCredsSetupCompleted": true
      },
      "name": "Time Tracking & Billing Automation:",
      "tags": [],
      "nodes": [
        {
          "id": "e62e8f45-3b5b-4a1d-a120-b0c07ebcc178",
          "name": "When clicking ‘Execute workflow’",
          "type": "n8n-nodes-base.manualTrigger",
          "position": [
            -128,
            0
          ],
          "parameters": {},
          "typeVersion": 1
        },
        {
          "id": "fadb2658-c02d-4819-b6eb-12114cc58127",
          "name": "Sticky Note",
          "type": "n8n-nodes-base.stickyNote",
          "position": [
            1120,
            -352
          ],
          "parameters": {
            "width": 256,
            "height": 336,
            "content": "Combine Reminder & Invoice Data Streams\n\nAction: Merges reminder and invoice outputs for unified processing.\nDescription:\n\nCombines both branches (missing hours and invoice data).\n\nEnsures all team members get relevant communication.\n\nKeeps all data intact for the next reconciliation step."
          },
          "typeVersion": 1
        },
        {
          "id": "4b5a9488-f7cd-436b-afaf-f698c756d933",
          "name": "Sticky Note1",
          "type": "n8n-nodes-base.stickyNote",
          "position": [
            736,
            -368
          ],
          "parameters": {
            "width": 288,
            "height": 336,
            "content": "Identify Issues with Missing Time Logs\n\nAction: Detects issues where time wasn’t logged.\nDescription:\n\nScans each user’s issues to find zero-hour entries.\n\nGenerates HTML reminder messages listing missing issues.\n\nCreates reminders only for users with actual missing logs.\n\nEnsures timely and accurate billing compliance."
          },
          "typeVersion": 1
        },
        {
          "id": "174d0eec-6cce-4d0c-8b38-045b67f12f76",
          "name": "Sticky Note2",
          "type": "n8n-nodes-base.stickyNote",
          "position": [
            368,
            -368
          ],
          "parameters": {
            "width": 288,
            "height": 336,
            "content": "Aggregate Hours by Team Member\n\nAction: Groups Jira issues by each assignee and totals their hours.\nDescription:\n\nCalculates total logged hours per user.\n\nKeeps issue details like summary, status, and sprint.\n\nHandles missing data (unassigned or null time entries).\n\nProduces structured user-level data for invoices and reminders."
          },
          "typeVersion": 1
        },
        {
          "id": "13457e31-0e46-48e0-88a1-91610a40b646",
          "name": "Sticky Note3",
          "type": "n8n-nodes-base.stickyNote",
          "position": [
            80,
            176
          ],
          "parameters": {
            "width": 304,
            "height": 368,
            "content": "Fetch All Project Issues with Time Data\n\nAction: Retrieves all Jira issues with time tracking info.\nDescription:\n\nUses Jira API to fetch every issue with getAll and returnAll.\n\nCollects essential fields like keys, summaries, time spent, and assignee.\n\nProvides project, sprint, and priority details.\n\nServes as the base dataset for billing and reporting."
          },
          "typeVersion": 1
        },
        {
          "id": "edcde860-f8c8-4229-be41-c4c026be9a46",
          "name": "Sticky Note4",
          "type": "n8n-nodes-base.stickyNote",
          "position": [
            720,
            560
          ],
          "parameters": {
            "width": 304,
            "height": 400,
            "content": "Generate Invoice Summary with Text Attachment\n\nAction: Creates detailed text-based invoices per user.\nDescription:\n\nCalculates billing using a default hourly rate ($50/hour).\n\nLists each issue with hours and status.\n\nExports a plain-text invoice as .txt (base64 encoded).\n\nSkips users with zero hours to avoid empty invoices.\n\nSends structured JSON + binary data for email delivery"
          },
          "typeVersion": 1
        },
        {
          "id": "d2450d54-f3e7-4732-bccd-2bc0e29b8238",
          "name": "Sticky Note5",
          "type": "n8n-nodes-base.stickyNote",
          "position": [
            1760,
            208
          ],
          "parameters": {
            "width": 272,
            "height": 384,
            "content": "Send Invoices & Reminders to Team\n\nAction: Sends personalized emails with invoices and reminders.\nDescription:\n\nSends to each developer’s email dynamically.\n\nIncludes name, project, and total hours in the message.\n\nAttaches generated invoice files.\n\nCan be extended to CC managers or finance.\n\nFinal delivery step for automated billing communication."
          },
          "typeVersion": 1
        },
        {
          "id": "559bf371-f7b3-477f-82d9-a022ed54856f",
          "name": "Sticky Note6",
          "type": "n8n-nodes-base.stickyNote",
          "position": [
            1424,
            -384
          ],
          "parameters": {
            "width": 288,
            "height": 368,
            "content": "Reconcile JSON & Binary Attachments\n\nAction: Aligns JSON data with corresponding invoice files.\nDescription:\n\nMatches items using assignee name as identifier.\n\nFixes cases where JSON or binary is missing.\n\nGuarantees each record includes both email info and invoice.\n\nPrevents send failures and ensures complete data merging."
          },
          "typeVersion": 1
        },
        {
          "id": "0da5f2fa-32f6-4c7e-85a0-474bf3550f4e",
          "name": " Fetch All Project Issues with Time Data",
          "type": "n8n-nodes-base.jira",
          "position": [
            176,
            0
          ],
          "parameters": {
            "options": {},
            "operation": "getAll",
            "returnAll": true
          },
          "credentials": {
            "jiraSoftwareCloudApi": {
              "id": "credential-id",
              "name": "jiraSoftwareCloudApi Credential"
            }
          },
          "typeVersion": 1
        },
        {
          "id": "76eca7bd-8b7d-4119-a18f-81ae5c142653",
          "name": "Aggregate Hours by Team Member",
          "type": "n8n-nodes-base.code",
          "position": [
            448,
            0
          ],
          "parameters": {
            "jsCode": "// Get all Jira issues from input\nconst items = $input.all().map(i => i.json);\n\n// Initialize grouped output\nconst grouped = {};\n\n// Iterate over each issue\nfor (const issue of items) {\n  const f = issue.fields || {};\n\n  const assigneeName = f.assignee?.displayName || 'Unassigned';\n  const email = f.assignee?.emailAddress || 'user@example.com';\n  const projectName = f.project?.name || 'Unknown Project';\n  const sprint = f.customfield_10020?.[0]?.name || 'No Sprint';\n  const timeSpentSeconds = f.timespent || 0;\n  const timeSpentHours = (timeSpentSeconds / 3600).toFixed(2);\n\n  if (!grouped[assigneeName]) {\n    grouped[assigneeName] = {\n      assignee: assigneeName,\n      email,\n      project_name: projectName,\n      total_hours: 0,\n      issues: []\n    };\n  }\n\n  grouped[assigneeName].total_hours += parseFloat(timeSpentHours);\n  grouped[assigneeName].issues.push({\n    issue_key: issue.key,\n    summary: f.summary,\n    timespent_hours: timeSpentHours,\n    status: f.status?.name || 'Unknown',\n    priority: f.priority?.name || 'None',\n    sprint,\n  });\n}\n\n// Convert grouped object into array format\nconst output = Object.values(grouped).map(user => ({\n  json: {\n    assignee: user.assignee,\n    email: user.email,\n    project_name: user.project_name,\n    total_hours: user.total_hours.toFixed(2),\n    issues: user.issues,\n  }\n}));\n\nreturn output;\n"
          },
          "typeVersion": 2,
          "alwaysOutputData": false
        },
        {
          "id": "3ef99004-e0bd-4346-8ac0-6e83a88260f0",
          "name": "Identify Issues with Missing Time Logs",
          "type": "n8n-nodes-base.code",
          "position": [
            832,
            0
          ],
          "parameters": {
            "jsCode": "const users = $input.all().map(i => i.json);\n\nconst reminders = [];\n\nfor (const user of users) {\n  const missing = user.issues.filter(i => parseFloat(i.timespent_hours) === 0);\n\n  if (missing.length > 0) {\n    const table = missing.map(i => \n      `<tr>\n        <td>${i.issue_key}</td>\n        <td>${i.summary}</td>\n        <td>${i.status}</td>\n        <td>${i.priority}</td>\n        <td>${i.sprint}</td>\n      </tr>`\n    ).join('');\n\n    reminders.push({\n      json: {\n        assignee: user.assignee,\n        email: user.email,\n        missing_count: missing.length,\n        project_name: user.project_name,\n        html_message: `\n          <p>Hi ${user.assignee},</p>\n          <p>Our system found ${missing.length} issues where no time is logged:</p>\n          <table border=\"1\" cellspacing=\"0\" cellpadding=\"5\">\n            <tr><th>Issue Key</th><th>Summary</th><th>Status</th><th>Priority</th><th>Sprint</th></tr>\n            ${table}\n          </table>\n          <p>Please log your hours for these issues before EOD to ensure accurate billing.</p>\n          <p>Thank you,<br>Automation Bot 🤖</p>\n        `\n      }\n    });\n  }\n}\n\nreturn reminders;\n"
          },
          "typeVersion": 2
        },
        {
          "id": "db74c4fe-3bf1-45f9-a971-64ffc74695df",
          "name": "Generate Invoice Summary with Text Attachment",
          "type": "n8n-nodes-base.code",
          "position": [
            832,
            384
          ],
          "parameters": {
            "jsCode": "// Combined Invoice Generator + Text File Export\n\nconst users = $input.all().map(i => i.json);\nconst RATE = 50; // hourly rate\nconst results = [];\n\nfor (const user of users) {\n  const totalHours = parseFloat(user.total_hours || 0);\n  if (totalHours === 0) continue;\n\n  const totalAmount = totalHours * RATE;\n\n  // Build the plain text table\n  const issueLines = user.issues.map(i =>\n    `${i.issue_key.padEnd(10)} | ${i.summary.padEnd(30)} | ${i.timespent_hours} hrs | ${i.status}`\n  ).join('\\n');\n\n  // Final plain-text invoice content\n  const text = `\nYOUR_AWS_SECRET_KEY_HERE===\nINVOICE SUMMARY — ${user.project_name}\nYOUR_AWS_SECRET_KEY_HERE===\n\nAssignee: ${user.assignee}\nEmail: ${user.email}\nRate: $${RATE}/hour\n\n-------------------------------------------\nIssues\n-------------------------------------------\n${issueLines}\n\n-------------------------------------------\nTotal Hours: ${totalHours.toFixed(2)}\nTotal Amount: $${totalAmount.toFixed(2)}\n-------------------------------------------\n\nGenerated automatically by Techdome Billing Automation Bot.\n`;\n\n  // Push JSON + Binary for email attachment\n  results.push({\n    json: {\n      assignee: user.assignee,\n      email: user.email,\n      project_name: user.project_name,\n      total_hours: totalHours.toFixed(2),\n      total_amount: totalAmount.toFixed(2)\n    },\n    binary: {\n      data: {\n        fileName: `Invoice_${user.assignee}.txt`,\n        mimeType: 'text/plain',\n        data: Buffer.from(text, 'utf8').toString('base64')\n      }\n    }\n  });\n}\n\nreturn results;\n"
          },
          "typeVersion": 2
        },
        {
          "id": "064ef92a-f13c-4926-8526-a1eb398fa3db",
          "name": "Combine Reminder & Invoice Data Streams",
          "type": "n8n-nodes-base.merge",
          "position": [
            1216,
            16
          ],
          "parameters": {},
          "typeVersion": 3.2
        },
        {
          "id": "d3aec18e-05de-4ca9-8b19-263695b105b7",
          "name": "Reconcile JSON & Binary Attachments",
          "type": "n8n-nodes-base.code",
          "position": [
            1488,
            16
          ],
          "parameters": {
            "jsCode": "// Combine JSON + Binary after Merge node\n// Safe for n8n v1.112.6 and later\n\nconst combined = [];\n\n// Get all incoming items\nconst items = $input.all();\n\n// We might have duplicates or partials, so we merge smartly\nfor (const item of items) {\n  const json = item.json || {};\n  const binary = item.binary || {};\n\n  // Case 1: this item already has both\n  if (json.email && binary.data) {\n    combined.push({ json, binary });\n    continue;\n  }\n\n  // Case 2: only has JSON\n  if (json.email && !binary.data) {\n    // Try to find its binary partner\n    const match = items.find(\n      (i) => i.binary && i.binary.data && i.json?.assignee === json.assignee\n    );\n\n    if (match) {\n      combined.push({ json, binary: match.binary });\n    } else {\n      combined.push({ json }); // fallback\n    }\n    continue;\n  }\n\n  // Case 3: only has Binary\n  if (binary.data && !json.email) {\n    // Try to find its JSON partner\n    const match = items.find(\n      (i) => i.json && i.json.assignee && i.binary === undefined\n    );\n    if (match) {\n      combined.push({ json: match.json, binary });\n    } else {\n      combined.push({ binary });\n    }\n    continue;\n  }\n}\n\nreturn combined;\n"
          },
          "typeVersion": 2
        },
        {
          "id": "94b59a38-4e45-47dc-8c3d-d133ddd07455",
          "name": "Send Invoices & Reminders to Team",
          "type": "n8n-nodes-base.gmail",
          "position": [
            1808,
            16
          ],
          "webhookId": "0c82c299-6938-42ed-bda6-5007d79af34f",
          "parameters": {
            "sendTo": "={{ $json.email }}",
            "message": "=Hi {{$json[\"assignee\"]}},<br><br>\nPlease find attached your invoice summary for <strong>{{$json[\"project_name\"]}}</strong>.<br><br>\n📊 <b>Total Hours:</b> {{ $('Aggregate Hours by Team Member').item.json.total_hours }}<br>\nRegards,<br>\nTechdome Billing Automation Bot\n",
            "options": {
              "attachmentsUi": {
                "attachmentsBinary": [
                  {}
                ]
              }
            },
            "subject": "={{ $json.project_name }}"
          },
          "credentials": {
            "gmailOAuth2": {
              "id": "credential-id",
              "name": "gmailOAuth2 Credential"
            }
          },
          "typeVersion": 2.1
        }
      ],
      "active": false,
      "pinData": {},
      "settings": {
        "executionOrder": "v1"
      },
      "versionId": "c7c9ac45-c34e-4b9e-a15d-0aea4da1f6d6",
      "connections": {
        "Aggregate Hours by Team Member": {
          "main": [
            [
              {
                "node": "Identify Issues with Missing Time Logs",
                "type": "main",
                "index": 0
              },
              {
                "node": "Generate Invoice Summary with Text Attachment",
                "type": "main",
                "index": 0
              }
            ]
          ]
        },
        "Send Invoices & Reminders to Team": {
          "main": [
            []
          ]
        },
        "Reconcile JSON & Binary Attachments": {
          "main": [
            [
              {
                "node": "Send Invoices & Reminders to Team",
                "type": "main",
                "index": 0
              }
            ]
          ]
        },
        "When clicking ‘Execute workflow’": {
          "main": [
            [
              {
                "node": " Fetch All Project Issues with Time Data",
                "type": "main",
                "index": 0
              }
            ]
          ]
        },
        "Identify Issues with Missing Time Logs": {
          "main": [
            [
              {
                "node": "Combine Reminder & Invoice Data Streams",
                "type": "main",
                "index": 0
              }
            ]
          ]
        },
        "Combine Reminder & Invoice Data Streams": {
          "main": [
            [
              {
                "node": "Reconcile JSON & Binary Attachments",
                "type": "main",
                "index": 0
              }
            ]
          ]
        },
        " Fetch All Project Issues with Time Data": {
          "main": [
            [
              {
                "node": "Aggregate Hours by Team Member",
                "type": "main",
                "index": 0
              }
            ]
          ]
        },
        "Generate Invoice Summary with Text Attachment": {
          "main": [
            [
              {
                "node": "Combine Reminder & Invoice Data Streams",
                "type": "main",
                "index": 1
              }
            ]
          ]
        }
      }
    },
    "lastUpdatedBy": 1,
    "workflowInfo": {
      "nodeCount": 15,
      "nodeTypes": {
        "n8n-nodes-base.code": {
          "count": 4
        },
        "n8n-nodes-base.jira": {
          "count": 1
        },
        "n8n-nodes-base.gmail": {
          "count": 1
        },
        "n8n-nodes-base.merge": {
          "count": 1
        },
        "n8n-nodes-base.stickyNote": {
          "count": 7
        },
        "n8n-nodes-base.manualTrigger": {
          "count": 1
        }
      }
    },
    "status": "published",
    "user": {
      "name": "Rahul Joshi",
      "username": "rahul08",
      "bio": "Rahul Joshi is a seasoned technology leader specializing in the n8n automation tool and AI-driven workflow automation. With deep expertise in building open-source workflow automation and self-hosted automation platforms, he helps organizations eliminate manual processes through intelligent n8n ai agent automation solutions.\n\n",
      "verified": true,
      "links": [
        "https://www.linkedin.com/in/callrahul/"
      ],
      "avatar": "https://gravatar.com/avatar/b6cf57822463143589b36ada06fbf6cb1509223a740fae3160b28f1ce41ccc12?r=pg&d=retro&size=200"
    },
    "nodes": [
      {
        "id": 24,
        "icon": "file:merge.svg",
        "name": "n8n-nodes-base.merge",
        "codex": {
          "data": {
            "alias": [
              "Join",
              "Concatenate",
              "Wait"
            ],
            "resources": {
              "generic": [
                {
                  "url": "https://n8n.io/blog/how-to-sync-data-between-two-systems/",
                  "icon": "🏬",
                  "label": "How to synchronize data between two systems (one-way vs. two-way sync"
                },
                {
                  "url": "https://n8n.io/blog/supercharging-your-conference-registration-process-with-n8n/",
                  "icon": "🎫",
                  "label": "Supercharging your conference registration process with n8n"
                },
                {
                  "url": "https://n8n.io/blog/migrating-community-metrics-to-orbit-using-n8n/",
                  "icon": "📈",
                  "label": "Migrating Community Metrics to Orbit using n8n"
                },
                {
                  "url": "https://n8n.io/blog/build-your-own-virtual-assistant-with-n8n-a-step-by-step-guide/",
                  "icon": "👦",
                  "label": "Build your own virtual assistant with n8n: A step by step guide"
                },
                {
                  "url": "https://n8n.io/blog/sending-automated-congratulations-with-google-sheets-twilio-and-n8n/",
                  "icon": "🙌",
                  "label": "Sending Automated Congratulations with Google Sheets, Twilio, and n8n "
                },
                {
                  "url": "https://n8n.io/blog/aws-workflow-automation/",
                  "label": "7 no-code workflow automations for Amazon Web Services"
                }
              ],
              "primaryDocumentation": [
                {
                  "url": "https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.merge/"
                }
              ]
            },
            "categories": [
              "Core Nodes"
            ],
            "nodeVersion": "1.0",
            "codexVersion": "1.0",
            "subcategories": {
              "Core Nodes": [
                "Flow",
                "Data Transformation"
              ]
            }
          }
        },
        "group": "[\"transform\"]",
        "defaults": {
          "name": "Merge"
        },
        "iconData": {
          "type": "file",
          "fileBuffer": "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTEyIiBoZWlnaHQ9IjUxMiIgdmlld0JveD0iMCAwIDUxMiA1MTIiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMF8xMTc3XzUxOCkiPgo8cGF0aCBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGNsaXAtcnVsZT0iZXZlbm9kZCIgZD0iTTAgNDhDMCAyMS40OTAzIDIxLjQ5MDMgMCA0OCAwSDExMkMxMzguNTEgMCAxNjAgMjEuNDkwMyAxNjAgNDhWNTZIMTk2LjI1MkMyNDAuNDM1IDU2IDI3Ni4yNTIgOTEuODE3MiAyNzYuMjUyIDEzNlYxOTJDMjc2LjI1MiAyMTQuMDkxIDI5NC4xNjEgMjMyIDMxNi4yNTIgMjMySDM1MlYyMjRDMzUyIDE5Ny40OSAzNzMuNDkgMTc2IDQwMCAxNzZINDY0QzQ5MC41MSAxNzYgNTEyIDE5Ny40OSA1MTIgMjI0VjI4OEM1MTIgMzE0LjUxIDQ5MC41MSAzMzYgNDY0IDMzNkg0MDBDMzczLjQ5IDMzNiAzNTIgMzE0LjUxIDM1MiAyODhWMjgwSDMxNi4yNTJDMjk0LjE2MSAyODAgMjc2LjI1MiAyOTcuOTA5IDI3Ni4yNTIgMzIwVjM3NkMyNzYuMjUyIDQyMC4xODMgMjQwLjQzNSA0NTYgMTk2LjI1MiA0NTZIMTYwVjQ2NEMxNjAgNDkwLjUxIDEzOC41MSA1MTIgMTEyIDUxMkg0OEMyMS40OTAzIDUxMiAwIDQ5MC41MSAwIDQ2NFY0MDBDMCAzNzMuNDkgMjEuNDkwMyAzNTIgNDggMzUySDExMkMxMzguNTEgMzUyIDE2MCAzNzMuNDkgMTYwIDQwMFY0MDhIMTk2LjI1MkMyMTMuOTI1IDQwOCAyMjguMjUyIDM5My42NzMgMjI4LjI1MiAzNzZWMzIwQzIyOC4yNTIgMjk0Ljc4NCAyMzguODU5IDI3Mi4wNDQgMjU1Ljg1MyAyNTZDMjM4Ljg1OSAyMzkuOTU2IDIyOC4yNTIgMjE3LjIxNiAyMjguMjUyIDE5MlYxMzZDMjI4LjI1MiAxMTguMzI3IDIxMy45MjUgMTA0IDE5Ni4yNTIgMTA0SDE2MFYxMTJDMTYwIDEzOC41MSAxMzguNTEgMTYwIDExMiAxNjBINDhDMjEuNDkwMyAxNjAgMCAxMzguNTEgMCAxMTJWNDhaTTEwNCA0OEMxMDguNDE4IDQ4IDExMiA1MS41ODE3IDExMiA1NlYxMDRDMTEyIDEwOC40MTggMTA4LjQxOCAxMTIgMTA0IDExMkg1NkM1MS41ODE3IDExMiA0OCAxMDguNDE4IDQ4IDEwNFY1NkM0OCA1MS41ODE3IDUxLjU4MTcgNDggNTYgNDhIMTA0Wk00NTYgMjI0QzQ2MC40MTggMjI0IDQ2NCAyMjcuNTgyIDQ2NCAyMzJWMjgwQzQ2NCAyODQuNDE4IDQ2MC40MTggMjg4IDQ1NiAyODhINDA4QzQwMy41ODIgMjg4IDQwMCAyODQuNDE4IDQwMCAyODBWMjMyQzQwMCAyMjcuNTgyIDQwMy41ODIgMjI0IDQwOCAyMjRINDU2Wk0xMTIgNDA4QzExMiA0MDMuNTgyIDEwOC40MTggNDAwIDEwNCA0MDBINTZDNTEuNTgxNyA0MDAgNDggNDAzLjU4MiA0OCA0MDhWNDU2QzQ4IDQ2MC40MTggNTEuNTgxNyA0NjQgNTYgNDY0SDEwNEMxMDguNDE4IDQ2NCAxMTIgNDYwLjQxOCAxMTIgNDU2VjQwOFoiIGZpbGw9IiM1NEI4QzkiLz4KPC9nPgo8ZGVmcz4KPGNsaXBQYXRoIGlkPSJjbGlwMF8xMTc3XzUxOCI+CjxyZWN0IHdpZHRoPSI1MTIiIGhlaWdodD0iNTEyIiBmaWxsPSJ3aGl0ZSIvPgo8L2NsaXBQYXRoPgo8L2RlZnM+Cjwvc3ZnPgo="
        },
        "displayName": "Merge",
        "typeVersion": 3,
        "nodeCategories": [
          {
            "id": 9,
            "name": "Core Nodes"
          }
        ]
      },
      {
        "id": 77,
        "icon": "file:jira.svg",
        "name": "n8n-nodes-base.jira",
        "codex": {
          "data": {
            "resources": {
              "generic": [
                {
                  "url": "https://n8n.io/blog/5-workflow-automations-for-mattermost-that-we-love-at-n8n/",
                  "icon": "🤖",
                  "label": "5 workflow automations for Mattermost that we love at n8n"
                },
                {
                  "url": "https://n8n.io/blog/creating-custom-incident-response-workflows-with-n8n/",
                  "label": "How to automate every step of an incident response workflow"
                }
              ],
              "primaryDocumentation": [
                {
                  "url": "https://docs.n8n.io/integrations/builtin/app-nodes/n8n-nodes-base.jira/"
                }
              ],
              "credentialDocumentation": [
                {
                  "url": "https://docs.n8n.io/integrations/builtin/credentials/jira/"
                }
              ]
            },
            "categories": [
              "Development",
              "Productivity"
            ],
            "nodeVersion": "1.0",
            "codexVersion": "1.0"
          }
        },
        "group": "[\"output\"]",
        "defaults": {
          "name": "Jira Software"
        },
        "iconData": {
          "type": "file",
          "fileBuffer": "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiBmaWxsPSIjZmZmIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiB2aWV3Qm94PSIwIDAgNjguMjUgNzEuMjUiPjx1c2UgeGxpbms6aHJlZj0iI2EiIHg9IjMuMTI1IiB5PSIzLjEyNSIvPjxkZWZzPjxsaW5lYXJHcmFkaWVudCBpZD0iYiIgeDE9IjkxLjklIiB4Mj0iMjguNDklIiB5MT0iNDAuMjIlIiB5Mj0iODEuNjMlIj48c3RvcCBvZmZzZXQ9IjE4JSIgc3RvcC1jb2xvcj0iIzAwNTJjYyIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iIzI2ODRmZiIvPjwvbGluZWFyR3JhZGllbnQ+PGxpbmVhckdyYWRpZW50IGlkPSJjIiB4MT0iOC43JSIgeDI9IjcyLjI2JSIgeTE9IjU5LjE3JSIgeTI9IjE3Ljk5JSI+PHN0b3Agb2Zmc2V0PSIxOCUiIHN0b3AtY29sb3I9IiMwMDUyY2MiLz48c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiMyNjg0ZmYiLz48L2xpbmVhckdyYWRpZW50PjwvZGVmcz48c3ltYm9sIGlkPSJhIiBvdmVyZmxvdz0idmlzaWJsZSI+PGcgZmlsbC1ydWxlPSJub256ZXJvIiBzdHJva2U9Im5vbmUiPjxwYXRoIGZpbGw9IiMyNjg0ZmYiIGQ9Ik02MS4xNjEgMzAuMjExIDMwLjk1IDAgLjc0IDMwLjIxMWEyLjU0IDIuNTQgMCAwIDAgMCAzLjU4MWwzMC4yMTEgMzAuMjEgMzAuMjExLTMwLjIxYTIuNTQgMi41NCAwIDAgMCAwLTMuNTgxek0zMC45NSA0MS40NmwtOS40NjItOS40NjIgOS40NjItOS40NjIgOS40NjIgOS40NjJ6Ii8+PHBhdGggZmlsbD0idXJsKCNiKSIgZD0iTTMwLjk1IDIyLjU5OUMyNC43NTUgMTYuNDA1IDI0LjcyNCA2LjM3IDMwLjg4MS4xMzhMMTAuMTE0IDIwLjc3NGwxMS4yNjggMTEuMjY4eiIvPjxwYXRoIGZpbGw9InVybCgjYykiIGQ9Ik00MC40MzcgMzEuOTczIDMwLjk1IDQxLjQ2YTE1LjkzIDE1LjkzIDAgMCAxIDAgMjIuNTM2bDIwLjc0OS0yMC43NDl6Ii8+PC9nPjwvc3ltYm9sPjwvc3ZnPg=="
        },
        "displayName": "Jira Software",
        "typeVersion": 1,
        "nodeCategories": [
          {
            "id": 4,
            "name": "Productivity"
          },
          {
            "id": 5,
            "name": "Development"
          }
        ]
      },
      {
        "id": 356,
        "icon": "file:gmail.svg",
        "name": "n8n-nodes-base.gmail",
        "codex": {
          "data": {
            "alias": [
              "email",
              "human",
              "form",
              "wait",
              "hitl",
              "approval"
            ],
            "resources": {
              "generic": [
                {
                  "url": "https://n8n.io/blog/why-business-process-automation-with-n8n-can-change-your-daily-life/",
                  "icon": "🧬",
                  "label": "Why business process automation with n8n can change your daily life"
                },
                {
                  "url": "https://n8n.io/blog/supercharging-your-conference-registration-process-with-n8n/",
                  "icon": "🎫",
                  "label": "Supercharging your conference registration process with n8n"
                },
                {
                  "url": "https://n8n.io/blog/no-code-ecommerce-workflow-automations/",
                  "icon": "store",
                  "label": "6 e-commerce workflows to power up your Shopify s"
                },
                {
                  "url": "https://n8n.io/blog/how-to-get-started-with-crm-automation-and-no-code-workflow-ideas/",
                  "icon": "👥",
                  "label": "How to get started with CRM automation (with 3 no-code workflow ideas"
                },
                {
                  "url": "https://n8n.io/blog/automate-google-apps-for-productivity/",
                  "icon": "💡",
                  "label": "15 Google apps you can combine and automate to increase productivity"
                },
                {
                  "url": "https://n8n.io/blog/your-business-doesnt-need-you-to-operate/",
                  "icon": " 🖥️",
                  "label": "Hey founders! Your business doesn't need you to operate"
                },
                {
                  "url": "https://n8n.io/blog/using-automation-to-boost-productivity-in-the-workplace/",
                  "icon": "💪",
                  "label": "Using Automation to Boost Productivity in the Workplace"
                }
              ],
              "primaryDocumentation": [
                {
                  "url": "https://docs.n8n.io/integrations/builtin/app-nodes/n8n-nodes-base.gmail/"
                }
              ],
              "credentialDocumentation": [
                {
                  "url": "https://docs.n8n.io/integrations/builtin/credentials/google/oauth-single-service/"
                }
              ]
            },
            "categories": [
              "Communication",
              "HITL"
            ],
            "nodeVersion": "1.0",
            "codexVersion": "1.0",
            "subcategories": {
              "HITL": [
                "Human in the Loop"
              ]
            }
          }
        },
        "group": "[\"transform\"]",
        "defaults": {
          "name": "Gmail"
        },
        "iconData": {
          "type": "file",
          "fileBuffer": "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNTYiIGhlaWdodD0iMTkzIiBwcmVzZXJ2ZUFzcGVjdFJhdGlvPSJ4TWlkWU1pZCI+PHBhdGggZmlsbD0iIzQyODVGNCIgZD0iTTU4LjE4MiAxOTIuMDVWOTMuMTRMMjcuNTA3IDY1LjA3NyAwIDQ5LjUwNHYxMjUuMDkxYzAgOS42NTggNy44MjUgMTcuNDU1IDE3LjQ1NSAxNy40NTV6Ii8+PHBhdGggZmlsbD0iIzM0QTg1MyIgZD0iTTE5Ny44MTggMTkyLjA1aDQwLjcyN2M5LjY1OSAwIDE3LjQ1NS03LjgyNiAxNy40NTUtMTcuNDU1VjQ5LjUwNWwtMzEuMTU2IDE3LjgzNy0yNy4wMjYgMjUuNzk4eiIvPjxwYXRoIGZpbGw9IiNFQTQzMzUiIGQ9Im01OC4xODIgOTMuMTQtNC4xNzQtMzguNjQ3IDQuMTc0LTM2Ljk4OUwxMjggNjkuODY4bDY5LjgxOC01Mi4zNjQgNC42NyAzNC45OTItNC42NyA0MC42NDRMMTI4IDE0NS41MDR6Ii8+PHBhdGggZmlsbD0iI0ZCQkMwNCIgZD0iTTE5Ny44MTggMTcuNTA0VjkzLjE0TDI1NiA0OS41MDRWMjYuMjMxYzAtMjEuNTg1LTI0LjY0LTMzLjg5LTQxLjg5LTIwLjk0NXoiLz48cGF0aCBmaWxsPSIjQzUyMjFGIiBkPSJtMCA0OS41MDQgMjYuNzU5IDIwLjA3TDU4LjE4MiA5My4xNFYxNy41MDRMNDEuODkgNS4yODZDMjQuNjEtNy42NiAwIDQuNjQ2IDAgMjYuMjN6Ii8+PC9zdmc+"
        },
        "displayName": "Gmail",
        "typeVersion": 2,
        "nodeCategories": [
          {
            "id": 6,
            "name": "Communication"
          },
          {
            "id": 28,
            "name": "HITL"
          }
        ]
      },
      {
        "id": 565,
        "icon": "fa:sticky-note",
        "name": "n8n-nodes-base.stickyNote",
        "codex": {
          "data": {
            "alias": [
              "Comments",
              "Notes",
              "Sticky"
            ],
            "categories": [
              "Core Nodes"
            ],
            "nodeVersion": "1.0",
            "codexVersion": "1.0",
            "subcategories": {
              "Core Nodes": [
                "Helpers"
              ]
            }
          }
        },
        "group": "[\"input\"]",
        "defaults": {
          "name": "Sticky Note",
          "color": "#FFD233"
        },
        "iconData": {
          "icon": "sticky-note",
          "type": "icon"
        },
        "displayName": "Sticky Note",
        "typeVersion": 1,
        "nodeCategories": [
          {
            "id": 9,
            "name": "Core Nodes"
          }
        ]
      },
      {
        "id": 834,
        "icon": "file:code.svg",
        "name": "n8n-nodes-base.code",
        "codex": {
          "data": {
            "alias": [
              "cpde",
              "Javascript",
              "JS",
              "Python",
              "Script",
              "Custom Code",
              "Function"
            ],
            "details": "The Code node allows you to execute JavaScript in your workflow.",
            "resources": {
              "primaryDocumentation": [
                {
                  "url": "https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.code/"
                }
              ]
            },
            "categories": [
              "Development",
              "Core Nodes"
            ],
            "nodeVersion": "1.0",
            "codexVersion": "1.0",
            "subcategories": {
              "Core Nodes": [
                "Helpers",
                "Data Transformation"
              ]
            }
          }
        },
        "group": "[\"transform\"]",
        "defaults": {
          "name": "Code"
        },
        "iconData": {
          "type": "file",
          "fileBuffer": "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTEyIiBoZWlnaHQ9IjUxMiIgdmlld0JveD0iMCAwIDUxMiA1MTIiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMF8xMTcxXzQ0MSkiPgo8cGF0aCBkPSJNMTcwLjI4MyA0OEgxOTYuNUMyMDMuMTI3IDQ4IDIwOC41IDQyLjYyNzQgMjA4LjUgMzZWMTJDMjA4LjUgNS4zNzI1OCAyMDMuMTI3IDAgMTk2LjUgMEgxNzAuMjgzQzEyNi4xIDAgOTAuMjgzIDM1LjgxNzIgOTAuMjgzIDgwVjE3NkM5MC4yODMgMjA2LjkyOCA2NS4yMTA5IDIzMiAzNC4yODMgMjMySDIzQzE2LjM3MjYgMjMyIDExIDIzNy4zNzIgMTEgMjQ0VjI2OEMxMSAyNzQuNjI3IDE2LjM3MjQgMjgwIDIyLjk5OTYgMjgwTDM0LjI4MyAyODBDNjUuMjEwOSAyODAgOTAuMjgzIDMwNS4wNzIgOTAuMjgzIDMzNlY0NDBDOTAuMjgzIDQ3OS43NjQgMTIyLjUxOCA1MTIgMTYyLjI4MyA1MTJIMTk2LjVDMjAzLjEyNyA1MTIgMjA4LjUgNTA2LjYyNyAyMDguNSA1MDBWNDc2QzIwOC41IDQ2OS4zNzMgMjAzLjEyNyA0NjQgMTk2LjUgNDY0SDE2Mi4yODNDMTQ5LjAyOCA0NjQgMTM4LjI4MyA0NTMuMjU1IDEzOC4yODMgNDQwVjMzNkMxMzguMjgzIDMwOS4wMjIgMTI4LjAxMSAyODQuNDQzIDExMS4xNjQgMjY1Ljk2MUMxMDYuMTA5IDI2MC40MTYgMTA2LjEwOSAyNTEuNTg0IDExMS4xNjQgMjQ2LjAzOUMxMjguMDExIDIyNy41NTcgMTM4LjI4MyAyMDIuOTc4IDEzOC4yODMgMTc2VjgwQzEzOC4yODMgNjIuMzI2OSAxNTIuNjEgNDggMTcwLjI4MyA0OFoiIGZpbGw9IiNGRjk5MjIiLz4KPHBhdGggZD0iTTMwNSAzNkMzMDUgNDIuNjI3NCAzMTAuMzczIDQ4IDMxNyA0OEgzNDIuOTc5QzM2MC42NTIgNDggMzc0Ljk3OCA2Mi4zMjY5IDM3NC45NzggODBWMTc2QzM3NC45NzggMjAyLjk3OCAzODUuMjUxIDIyNy41NTcgNDAyLjA5OCAyNDYuMDM5QzQwNy4xNTMgMjUxLjU4NCA0MDcuMTUzIDI2MC40MTYgNDAyLjA5OCAyNjUuOTYxQzM4NS4yNTEgMjg0LjQ0MyAzNzQuOTc4IDMwOS4wMjIgMzc0Ljk3OCAzMzZWNDMyQzM3NC45NzggNDQ5LjY3MyAzNjAuNjUyIDQ2NCAzNDIuOTc5IDQ2NEgzMTdDMzEwLjM3MyA0NjQgMzA1IDQ2OS4zNzMgMzA1IDQ3NlY1MDBDMzA1IDUwNi42MjcgMzEwLjM3MyA1MTIgMzE3IDUxMkgzNDIuOTc5QzM4Ny4xNjEgNTEyIDQyMi45NzggNDc2LjE4MyA0MjIuOTc4IDQzMlYzMzZDNDIyLjk3OCAzMDUuMDcyIDQ0OC4wNTEgMjgwIDQ3OC45NzkgMjgwSDQ5MEM0OTYuNjI3IDI4MCA1MDIgMjc0LjYyOCA1MDIgMjY4VjI0NEM1MDIgMjM3LjM3MyA0OTYuNjI4IDIzMiA0OTAgMjMyTDQ3OC45NzkgMjMyQzQ0OC4wNTEgMjMyIDQyMi45NzggMjA2LjkyOCA0MjIuOTc4IDE3NlY4MEM0MjIuOTc4IDM1LjgxNzIgMzg3LjE2MSAwIDM0Mi45NzkgMEgzMTdDMzEwLjM3MyAwIDMwNSA1LjM3MjU4IDMwNSAxMlYzNloiIGZpbGw9IiNGRjk5MjIiLz4KPC9nPgo8ZGVmcz4KPGNsaXBQYXRoIGlkPSJjbGlwMF8xMTcxXzQ0MSI+CjxyZWN0IHdpZHRoPSI1MTIiIGhlaWdodD0iNTEyIiBmaWxsPSJ3aGl0ZSIvPgo8L2NsaXBQYXRoPgo8L2RlZnM+Cjwvc3ZnPgo="
        },
        "displayName": "Code",
        "typeVersion": 2,
        "nodeCategories": [
          {
            "id": 5,
            "name": "Development"
          },
          {
            "id": 9,
            "name": "Core Nodes"
          }
        ]
      },
      {
        "id": 838,
        "icon": "fa:mouse-pointer",
        "name": "n8n-nodes-base.manualTrigger",
        "codex": {
          "data": {
            "resources": {
              "generic": [],
              "primaryDocumentation": [
                {
                  "url": "https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.manualworkflowtrigger/"
                }
              ]
            },
            "categories": [
              "Core Nodes"
            ],
            "nodeVersion": "1.0",
            "codexVersion": "1.0"
          }
        },
        "group": "[\"trigger\"]",
        "defaults": {
          "name": "When clicking ‘Execute workflow’",
          "color": "#909298"
        },
        "iconData": {
          "icon": "mouse-pointer",
          "type": "icon"
        },
        "displayName": "Manual Trigger",
        "typeVersion": 1,
        "nodeCategories": [
          {
            "id": 9,
            "name": "Core Nodes"
          }
        ]
      }
    ],
    "categories": [
      {
        "id": 35,
        "name": "Document Extraction"
      }
    ],
    "image": []
  }
}