{
  "nodes": [
    {
      "id": "cb2a1099-23d0-4f51-a63a-79d25ce0aec0",
      "name": "Main \u2014 Overview & Setup",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        0,
        -192
      ],
      "parameters": {
        "width": 400,
        "height": 860,
        "content": "## AI Bug Ticket Generator \u2014 WayinVideo + GPT-4o-mini + Google Sheets\nAutomatically triage customer bug reports from screen recordings. WayinVideo AI finds the exact bug moment in the video, GPT-4o-mini generates a structured support ticket, and it is saved to Google Sheets.\n\n### How it works\n1. A support agent submits a screen recording URL, customer name, and bug type via the web form.\n2. WayinVideo scans the recording to find the exact bug moment using AI.\n3. GPT-4o-mini analyzes the moment and generates a structured ticket (priority, steps to reproduce, fix suggestion).\n4. The completed ticket is appended to a Google Sheet for the support team.\n\n### Setup\n1. Replace YOUR_WAYINVIDEO_API_KEY in nodes \"2. WayinVideo \u2014 Find Bug Moments\" and \"4. WayinVideo \u2014 Get Bug Moments\".\n2. Add your OpenAI API key to the credential in node \"6a. OpenAI \u2014 Chat Model\".\n3. Replace YOUR_GOOGLE_SHEET_ID in node \"7. Google Sheets \u2014 Save Bug Ticket\".\n4. Connect your Google account in node \"7. Google Sheets \u2014 Save Bug Ticket\" via OAuth2.\n\n### Customization tips\n- Increase limit from 3 to 5 in node 2 to capture more bug moments.\n- Swap gpt-4o-mini for gpt-4o for higher-quality ticket generation.\n- Add a Slack node after step 7 to notify the dev team instantly."
      },
      "typeVersion": 1
    },
    {
      "id": "d9177c75-be48-44c0-b100-3795682426f4",
      "name": "Section \u2014 Input",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        432,
        0
      ],
      "parameters": {
        "color": 5,
        "width": 260,
        "height": 116,
        "content": "## 1. Input\nSupport agent submits a screen recording URL, customer name, and bug type via a web form."
      },
      "typeVersion": 1
    },
    {
      "id": "26209167-b590-4d98-b8dd-5307706fb2d4",
      "name": "Section \u2014 WayinVideo Bug Detection",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        736,
        0
      ],
      "parameters": {
        "color": 5,
        "width": 740,
        "height": 116,
        "content": "## 2. WayinVideo Bug Detection\nSubmits the recording to WayinVideo to find the exact bug moment. Waits 45s then polls for results."
      },
      "typeVersion": 1
    },
    {
      "id": "d3ec4e29-9ef6-4628-8a91-d8680a3da86c",
      "name": "Section \u2014 AI Ticket + Save",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1504,
        0
      ],
      "parameters": {
        "color": 5,
        "width": 900,
        "height": 116,
        "content": "## 3. AI Ticket Generation + Save\nIf bug moments found, GPT-4o-mini generates a structured ticket and saves it to Google Sheets. If not yet ready, loops back to wait 45s and poll again."
      },
      "typeVersion": 1
    },
    {
      "id": "669cb4a9-bdab-4271-a0ad-49f4a4062880",
      "name": "Warning \u2014 Infinite Loop Risk",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1472,
        512
      ],
      "parameters": {
        "color": 3,
        "width": 480,
        "height": 140,
        "content": "## \u26a0\ufe0f WARNING \u2014 Infinite Loop Risk\nIf WayinVideo never returns bug moments (invalid URL or unsupported format), this workflow loops forever. Add a max-retry counter to the If node to prevent runaway executions."
      },
      "typeVersion": 1
    },
    {
      "id": "ad5f1f47-ca06-40b6-a6c4-af449bdfcd55",
      "name": "Warning \u2014 Hardcoded API Key",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        736,
        352
      ],
      "parameters": {
        "color": 3,
        "width": 480,
        "height": 140,
        "content": "## \u26a0\ufe0f WARNING \u2014 Hardcoded API Key\nThe WayinVideo API key is stored in plain text inside node parameters. Move it to an n8n Credential (Header Auth) for security before sharing this workflow."
      },
      "typeVersion": 1
    },
    {
      "id": "69cf641d-65f0-4a9c-8553-6d09e8fb2571",
      "name": "1. Form \u2014 Bug Recording + Details",
      "type": "n8n-nodes-base.formTrigger",
      "position": [
        464,
        144
      ],
      "parameters": {
        "options": {},
        "formTitle": "\ud83d\udc1b Support Ticket \u2014 Video Bug Triage",
        "formFields": {
          "values": [
            {
              "fieldLabel": "Screen Recording URL",
              "placeholder": "https://zoom.us/rec/xxxxxxx or Loom/Drive link",
              "requiredField": true
            },
            {
              "fieldLabel": "Customer Name",
              "placeholder": "e.g. Rahul Sharma / Acme Corp",
              "requiredField": true
            },
            {
              "fieldLabel": "Bug Type",
              "placeholder": "e.g. Login Error, Payment Failure, UI Bug, App Crash",
              "requiredField": true
            }
          ]
        },
        "formDescription": "Submit a customer bug screen recording URL \u2014 AI will find the exact bug moment and create a support ticket automatically."
      },
      "typeVersion": 2.2
    },
    {
      "id": "fc5ff939-a877-4840-98bd-4ba302aad0ac",
      "name": "2. WayinVideo \u2014 Find Bug Moments",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        736,
        144
      ],
      "parameters": {
        "url": "https://wayinvideo-api.wayin.ai/api/v2/clips/find-moments",
        "method": "POST",
        "options": {},
        "jsonBody": "={\n  \"video_url\": \"{{ $json['Screen Recording URL'] }}\",\n  \"query\": \"{{ $json['Bug Type'] }} error or problem moment\",\n  \"project_name\": \"Bug - {{ $json['Customer Name'] }}\",\n  \"limit\": 3,\n  \"enable_export\": false,\n  \"target_lang\": \"en\"\n}",
        "sendBody": true,
        "sendHeaders": true,
        "specifyBody": "json",
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Bearer YOUR_TOKEN_HERE"
            },
            {
              "name": "x-wayinvideo-api-version",
              "value": "v2"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "4df19fbf-1bff-43d2-bb72-68f8047c3f9f",
      "name": "3. Wait \u2014 45 Seconds",
      "type": "n8n-nodes-base.wait",
      "position": [
        976,
        144
      ],
      "parameters": {
        "amount": 45
      },
      "typeVersion": 1.1
    },
    {
      "id": "14326553-d457-42e8-8ceb-5109198b71be",
      "name": "4. WayinVideo \u2014 Get Bug Moments",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1216,
        144
      ],
      "parameters": {
        "url": "=https://wayinvideo-api.wayin.ai/api/v2/clips/find-moments/results/{{ $('2. WayinVideo \u2014 Find Bug Moments').item.json.data.id }}",
        "options": {},
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Bearer YOUR_TOKEN_HERE"
            },
            {
              "name": "x-wayinvideo-api-version",
              "value": "v2"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "bd3d9449-8412-4030-9455-b71135e58548",
      "name": "5. If \u2014 Bug Moments Found?",
      "type": "n8n-nodes-base.if",
      "position": [
        1424,
        144
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "aea7f509-3809-4302-9a09-a0232541e1ac",
              "operator": {
                "type": "array",
                "operation": "notEmpty",
                "singleValue": true
              },
              "leftValue": "={{ $json.data.clips }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "a62356de-bf17-43ab-8089-fb1d5e74737a",
      "name": "6. AI Agent \u2014 Generate Bug Ticket",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        1648,
        128
      ],
      "parameters": {
        "text": "=You are a technical support engineer. Analyze the bug moments found in the customer's screen recording and create a structured support ticket.\n\nCustomer Name: {{ $('1. Form \u2014 Bug Recording + Details').item.json['Customer Name'] }}\nBug Type Reported: {{ $('1. Form \u2014 Bug Recording + Details').item.json['Bug Type'] }}\nRecording URL: {{ $('1. Form \u2014 Bug Recording + Details').item.json['Screen Recording URL'] }}\n\nBug Moments Found by WayinVideo:\n{{ $('4. WayinVideo \u2014 Get Bug Moments').item.json.data.clips.map(c => 'Moment ' + (c.idx + 1) + ': ' + c.title + ' | Time: ' + Math.floor(c.begin_ms/1000) + 's - ' + Math.floor(c.end_ms/1000) + 's | Description: ' + c.desc + ' | Relevance Score: ' + c.score).join('\\n') }}\n\nCreate a bug ticket using this exact format:\n\nBUG SUMMARY:\n[Write 1 clear sentence describing what the bug is]\n\nPRIORITY: [Choose one: Critical / High / Medium / Low]\n- Critical = payment, login, data loss, app crash\n- High = major feature not working\n- Medium = UI issue, minor feature broken\n- Low = cosmetic or text issue\n\nBUG CATEGORY: [Choose one: Authentication / Payment / UI / Performance / App Crash / API Error / Other]\n\nEXACT LOCATION IN VIDEO:\n[Timestamp where bug appears \u2014 from WayinVideo data above]\n\nSTEPS TO REPRODUCE:\n1. [What the user was doing based on the moment description]\n2. [What action triggered the bug]\n3. [What happened next]\n\nEXPECTED BEHAVIOR:\n[What should have happened]\n\nACTUAL BEHAVIOR:\n[What actually happened \u2014 based on the bug moment description]\n\nASSIGN TO: [Choose one: Backend Dev / Frontend Dev / QA Team / DevOps / Product Team]\n\nSUGGESTED FIX:\n[Write 1-2 lines on what might be causing this and how to investigate]\n\nSTATUS: Open",
        "options": {},
        "promptType": "define"
      },
      "typeVersion": 3.1
    },
    {
      "id": "711b5f37-961a-433a-bd54-e03501ccab65",
      "name": "6a. OpenAI \u2014 Chat Model (GPT-4o-mini)",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        1648,
        352
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4o-mini"
        },
        "options": {},
        "builtInTools": {}
      },
      "typeVersion": 1.3
    },
    {
      "id": "49c6b8dc-e28e-4c37-8bcb-4df879fe58d6",
      "name": "7. Google Sheets \u2014 Save Bug Ticket",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        2064,
        128
      ],
      "parameters": {
        "columns": {
          "value": {
            "Status": "Open",
            "Bug Type": "={{ $('1. Form \u2014 Bug Recording + Details').item.json['Bug Type'] }}",
            "Bug Ticket": "={{ $json.output }}",
            "Customer Name": "={{ $('1. Form \u2014 Bug Recording + Details').item.json['Customer Name'] }}",
            "Recording URL": "={{ $('1. Form \u2014 Bug Recording + Details').item.json['Screen Recording URL'] }}",
            "Date Submitted": "={{ $now }}",
            "Bug Moments Found": "={{ $('4. WayinVideo \u2014 Get Bug Moments').item.json.data.clips.length }}",
            "Top Bug Timestamp": "={{ Math.floor($('4. WayinVideo \u2014 Get Bug Moments').item.json.data.clips[0].begin_ms / 1000) }}s - {{ Math.floor($('4. WayinVideo \u2014 Get Bug Moments').item.json.data.clips[0].end_ms / 1000) }}s"
          },
          "schema": [],
          "mappingMode": "defineBelow",
          "matchingColumns": []
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "name",
          "value": "Bug Tickets"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "YOUR_GOOGLE_SHEET_ID"
        }
      },
      "typeVersion": 4.5
    }
  ],
  "connections": {
    "3. Wait \u2014 45 Seconds": {
      "main": [
        [
          {
            "node": "4. WayinVideo \u2014 Get Bug Moments",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "5. If \u2014 Bug Moments Found?": {
      "main": [
        [
          {
            "node": "6. AI Agent \u2014 Generate Bug Ticket",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "3. Wait \u2014 45 Seconds",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "4. WayinVideo \u2014 Get Bug Moments": {
      "main": [
        [
          {
            "node": "5. If \u2014 Bug Moments Found?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "2. WayinVideo \u2014 Find Bug Moments": {
      "main": [
        [
          {
            "node": "3. Wait \u2014 45 Seconds",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "1. Form \u2014 Bug Recording + Details": {
      "main": [
        [
          {
            "node": "2. WayinVideo \u2014 Find Bug Moments",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "6. AI Agent \u2014 Generate Bug Ticket": {
      "main": [
        [
          {
            "node": "7. Google Sheets \u2014 Save Bug Ticket",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "6a. OpenAI \u2014 Chat Model (GPT-4o-mini)": {
      "ai_languageModel": [
        [
          {
            "node": "6. AI Agent \u2014 Generate Bug Ticket",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    }
  }
}