{
  "name": "YouTube Comment Responder",
  "nodes": [
    {
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "hours",
              "triggerAtMinute": 5
            }
          ]
        }
      },
      "type": "n8n-nodes-base.scheduleTrigger",
      "typeVersion": 1.2,
      "position": [
        -160,
        0
      ],
      "id": "457187f0-c6de-42f8-b147-e893a8304787",
      "name": "Schedule Trigger"
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 2
          },
          "conditions": [
            {
              "id": "d544837c-aa4c-4ed1-b26a-bc1406fcd54c",
              "leftValue": "={{ $json['YouTube Comments File'] }}",
              "rightValue": "",
              "operator": {
                "type": "string",
                "operation": "empty",
                "singleValue": true
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        220,
        0
      ],
      "id": "b442b19b-d8ea-4abd-97c6-acfc32b45e2a",
      "name": "If"
    },
    {
      "parameters": {
        "operation": "move",
        "fileId": {
          "__rl": true,
          "value": "={{ $json.spreadsheetId }}",
          "mode": "id"
        },
        "driveId": {
          "__rl": true,
          "mode": "list",
          "value": "My Drive"
        },
        "folderId": {
          "__rl": true,
          "value": "18Ry_Rd4EsqLicro6I-3UxZoiDppHugme",
          "mode": "list",
          "cachedResultName": "Comment Files",
          "cachedResultUrl": "https://drive.google.com/drive/folders/18Ry_Rd4EsqLicro6I-3UxZoiDppHugme"
        }
      },
      "type": "n8n-nodes-base.googleDrive",
      "typeVersion": 3,
      "position": [
        1040,
        -160
      ],
      "id": "8d61cce7-2553-481f-a4da-0e9996e5387e",
      "name": "Google Drive",
      "credentials": {
        "googleDriveOAuth2Api": {
          "id": "6b09vfNjQ0BTsy8h",
          "name": "Google Drive account"
        }
      }
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "700068da-76db-47f3-866e-ec82aa4c21aa",
              "name": "rows",
              "value": "=Comment,Response,Commenter Name,Sentiment,Comment Time,Response Approved?,Response Submitted?,Response Time",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        1220,
        -160
      ],
      "id": "debd8d10-b504-4a60-8198-f3de252db99d",
      "name": "Edit Fields"
    },
    {
      "parameters": {
        "jsCode": "// Split the comma-separated string from $json.rows\nconst headersArray = $json.rows.split(',');\n\n// Create an object where each key is a header (trimmed) and its value is the header text\nconst headersObject = {};\nheadersArray.forEach(header => {\n  const trimmedHeader = header.trim();\n  headersObject[trimmedHeader] = trimmedHeader;\n});\n\n// Return the object so that each header becomes a column in the first row of your sheet\nreturn [\n  {\n    json: headersObject\n  }\n];\n"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1400,
        -160
      ],
      "id": "5200c536-94a1-4544-b43d-d0f8a2d29d02",
      "name": "Code1"
    },
    {
      "parameters": {
        "resource": "spreadsheet",
        "title": "={{ $('Pull From YouTube Video Info Sheet').item.json['Video File'] }}",
        "sheetsUi": {
          "sheetValues": [
            {
              "title": "Comments and Responses"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.googleSheets",
      "typeVersion": 4.5,
      "position": [
        860,
        -160
      ],
      "id": "1040fa22-cfb0-4eaf-8ddb-e2bcf1c41006",
      "name": "Create Google Sheets Doc",
      "credentials": {
        "googleSheetsOAuth2Api": {
          "id": "gbV7ZDvk1w563Bec",
          "name": "Google Sheets account"
        }
      }
    },
    {
      "parameters": {
        "operation": "append",
        "documentId": {
          "__rl": true,
          "value": "={{ $('Google Drive').item.json.id }}",
          "mode": "id"
        },
        "sheetName": {
          "__rl": true,
          "value": "={{ $('Create Google Sheets Doc').item.json.sheets[0].properties.sheetId }}",
          "mode": "id"
        },
        "columns": {
          "mappingMode": "defineBelow",
          "value": {},
          "matchingColumns": [
            "data"
          ],
          "schema": [
            {
              "id": "Comment",
              "displayName": "Comment",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "removed": false
            },
            {
              "id": "Response",
              "displayName": "Response",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "removed": false
            },
            {
              "id": "Commenter Name",
              "displayName": "Commenter Name",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "removed": false
            },
            {
              "id": "Sentiment",
              "displayName": "Sentiment",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "removed": false
            },
            {
              "id": "Comment Time",
              "displayName": "Comment Time",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "removed": false
            },
            {
              "id": "Response Approved?",
              "displayName": "Response Approved?",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "removed": false
            },
            {
              "id": "Response Submitted?",
              "displayName": "Response Submitted?",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "removed": false
            },
            {
              "id": "Response Time",
              "displayName": "Response Time",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "removed": false
            }
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {}
      },
      "type": "n8n-nodes-base.googleSheets",
      "typeVersion": 4.5,
      "position": [
        1580,
        -160
      ],
      "id": "4ad833ba-5124-41eb-906f-d44314b490fc",
      "name": "Add Row Headings",
      "credentials": {
        "googleSheetsOAuth2Api": {
          "id": "gbV7ZDvk1w563Bec",
          "name": "Google Sheets account"
        }
      }
    },
    {
      "parameters": {
        "operation": "delete",
        "documentId": {
          "__rl": true,
          "value": "={{ $('Create Google Sheets Doc').item.json.spreadsheetId }}",
          "mode": "id"
        },
        "sheetName": {
          "__rl": true,
          "value": "Comments and Responses",
          "mode": "name"
        }
      },
      "type": "n8n-nodes-base.googleSheets",
      "typeVersion": 4.5,
      "position": [
        1760,
        -160
      ],
      "id": "14a94fa2-9853-4d78-a095-cee5bd79582d",
      "name": "Remove Extra Row",
      "credentials": {
        "googleSheetsOAuth2Api": {
          "id": "gbV7ZDvk1w563Bec",
          "name": "Google Sheets account"
        }
      }
    },
    {
      "parameters": {
        "options": {}
      },
      "type": "n8n-nodes-base.splitInBatches",
      "typeVersion": 3,
      "position": [
        560,
        180
      ],
      "id": "17f4d919-fc87-4313-8127-fd82d9c507d8",
      "name": "Loop Over Items"
    },
    {
      "parameters": {
        "url": "https://www.googleapis.com/youtube/v3/commentThreads",
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "youTubeOAuth2Api",
        "sendQuery": true,
        "queryParameters": {
          "parameters": [
            {
              "name": "part",
              "value": "snippet"
            },
            {
              "name": "videoId",
              "value": "={{ $('Pull From YouTube Video Info Sheet').item.json['YouTube Video ID'] }}"
            },
            {
              "name": "order",
              "value": "time"
            },
            {
              "name": "maxResults",
              "value": "10"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        740,
        280
      ],
      "id": "02cc5380-ce81-47b5-8834-b617dd9abde7",
      "name": "HTTP Request",
      "credentials": {
        "youTubeOAuth2Api": {
          "id": "KoZgM87eamK22Dxu",
          "name": "YouTube account 2"
        }
      }
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "loose",
            "version": 2
          },
          "conditions": [
            {
              "id": "d382aa0c-04a8-4c71-9873-e3443109e122",
              "leftValue": "={{ $json.snippet.topLevelComment.snippet.publishedAt }}",
              "rightValue": "={{ $('Pull From YouTube Video Info Sheet').item.json['Last Checked'] }}",
              "operator": {
                "type": "dateTime",
                "operation": "after"
              }
            }
          ],
          "combinator": "and"
        },
        "looseTypeValidation": true,
        "options": {}
      },
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        1100,
        280
      ],
      "id": "f9291dfb-79bc-47f6-8696-1167a379b1ee",
      "name": "If1"
    },
    {
      "parameters": {
        "promptType": "define",
        "text": "={{ $json.Comment }}",
        "hasOutputParser": true,
        "options": {
          "systemMessage": "=<system_prompt>  \nYOU ARE A FRIENDLY AND HELPFUL AI COMMENT ANALYZER DESIGNED TO ENGAGE WITH YOUTUBE COMMENTS IN A POSITIVE MANNER. YOUR TASK IS TO:  \n\n1. **READ AND UNDERSTAND** THE GIVEN YOUTUBE COMMENT.  \n2. **DETERMINE THE COMMENT'S SENTIMENT** AS **POSITIVE, NEUTRAL, OR NEGATIVE** BASED ON ITS TONE AND CONTENT.  \n3. **GENERATE A FRIENDLY AND HELPFUL RESPONSE** THAT ADDRESSES THE COMMENT APPROPRIATELY.  \n4. **RETURN A JSON OBJECT** CONTAINING BOTH THE RESPONSE AND THE SENTIMENT CLASSIFICATION.  \n\n### SENTIMENT CLASSIFICATION RULES:  \n- **POSITIVE:** The comment expresses praise, enthusiasm, agreement, or gratitude.  \n- **NEUTRAL:** The comment is factual, ambiguous, or does not strongly convey an emotion.  \n- **NEGATIVE:** The comment contains complaints, criticism, or frustration.  \n\n### RESPONSE GUIDELINES:  \n- **POSITIVE COMMENTS:** Express gratitude, encouragement, or agreement and invite the commentor to join my free Skool community to learn more or get free n8n workflows.  \n- **NEUTRAL COMMENTS:** Provide a relevant response while maintaining an engaging tone.  \n- **NEGATIVE COMMENTS:** Acknowledge concerns, offer solutions, or respond with understanding while staying constructive.  \n\n### JSON OUTPUT FORMAT:  \n{  \n  \"response\": \"<YOUR GENERATED RESPONSE>\",  \n  \"sentiment\": \"<POSITIVE | NEUTRAL | NEGATIVE>\"  \n}  \nFEW-SHOT EXAMPLES:\nExample 1: Positive Comment\nInput: \"I love this video! The explanation was super clear and helpful!\"\nOutput:\n{  \n  \"response\": \"Thank you so much! I'm really glad you found it helpful! 😊\",  \n  \"sentiment\": \"POSITIVE\"  \n}  \nExample 2: Neutral Comment\nInput: \"This video covers the topic in 10 minutes.\"\nOutput:\n{  \n  \"response\": \"Yep! A quick and to-the-point breakdown of the topic. Hope it helped!\",  \n  \"sentiment\": \"NEUTRAL\"  \n}  \nExample 3: Negative Comment\nInput: \"This explanation is confusing. You should make it simpler.\"\nOutput:\n{  \n  \"response\": \"I appreciate the feedback! I'll try to make it clearer in future videos. Thanks for sharing your thoughts!\",  \n  \"sentiment\": \"NEGATIVE\"  \n}  \nWHAT NOT TO DO:\nDO NOT generate rude, dismissive, or confrontational responses.\nDO NOT misclassify sentiment (e.g., labeling clear praise as neutral).\nDO NOT generate robotic or generic responses—keep them friendly and engaging.\nYOUR GOAL IS TO ENCOURAGE POSITIVE DISCUSSIONS WHILE RESPONDING TO COMMENTS ACCURATELY AND HELPFULLY.\n</system_prompt>"
        }
      },
      "type": "@n8n/n8n-nodes-langchain.agent",
      "typeVersion": 1.8,
      "position": [
        1460,
        180
      ],
      "id": "4ca1316d-3914-44d8-a02f-fda44e145766",
      "name": "AI Agent"
    },
    {
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4o-mini"
        },
        "options": {}
      },
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "typeVersion": 1.2,
      "position": [
        1520,
        340
      ],
      "id": "1605cc65-ddaf-431c-b624-9057ccc08b5b",
      "name": "OpenAI Chat Model",
      "credentials": {
        "openAiApi": {
          "id": "AG2i36rIlQJn1Cj3",
          "name": "OpenAi account"
        }
      }
    },
    {
      "parameters": {
        "operation": "update",
        "documentId": {
          "__rl": true,
          "value": "1zDB8ZyMxEBMuLf0Uz4gNQqlxtV8ImSMsstJdDTWQZV8",
          "mode": "list",
          "cachedResultName": "BC YouTube Video Info",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1zDB8ZyMxEBMuLf0Uz4gNQqlxtV8ImSMsstJdDTWQZV8/edit?usp=drivesdk"
        },
        "sheetName": {
          "__rl": true,
          "value": 159089414,
          "mode": "list",
          "cachedResultName": "Video Info For Processing",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1NFUNgV91beAxhQyiCUXFDtoi57D_bWltgaYwNAgGA3s/edit#gid=159089414"
        },
        "columns": {
          "mappingMode": "defineBelow",
          "value": {
            "Video File": "={{ $('Pull From YouTube Video Info Sheet').item.json['Video File'] }}",
            "YouTube Comments File": "={{ $('Create Google Sheets Doc').item.json.spreadsheetUrl }}",
            "Last Checked": "={{ $now }}"
          },
          "matchingColumns": [
            "Video File"
          ],
          "schema": [
            {
              "id": "Video File",
              "displayName": "Video File",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "removed": false
            },
            {
              "id": "Audio File Link",
              "displayName": "Audio File Link",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "YouTube Video ID",
              "displayName": "YouTube Video ID",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "YouTube Comments File",
              "displayName": "YouTube Comments File",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "Video Transcript File",
              "displayName": "Video Transcript File",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "removed": false
            },
            {
              "id": "Video Category",
              "displayName": "Video Category",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "removed": false
            },
            {
              "id": "Referenced Videos",
              "displayName": "Referenced Videos",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "Google Keywords",
              "displayName": "Google Keywords",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "Video Title",
              "displayName": "Video Title",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "Description",
              "displayName": "Description",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "Video Tags",
              "displayName": "Video Tags",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "Last Checked",
              "displayName": "Last Checked",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "Blog Posted?",
              "displayName": "Blog Posted?",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "removed": false
            },
            {
              "id": "Blog Link",
              "displayName": "Blog Link",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "removed": false
            },
            {
              "id": "LinkedIn Posted?",
              "displayName": "LinkedIn Posted?",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "removed": false
            },
            {
              "id": "LinkedIn Post Link",
              "displayName": "LinkedIn Post Link",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "removed": false
            },
            {
              "id": "Reddit Posted?",
              "displayName": "Reddit Posted?",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "removed": false
            },
            {
              "id": "row_number",
              "displayName": "row_number",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "readOnly": true,
              "removed": true
            }
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {}
      },
      "type": "n8n-nodes-base.googleSheets",
      "typeVersion": 4.5,
      "position": [
        1940,
        -160
      ],
      "id": "15de1f93-c46e-4083-ab59-e667b6fb0f03",
      "name": "Add Comments File URL",
      "credentials": {
        "googleSheetsOAuth2Api": {
          "id": "gbV7ZDvk1w563Bec",
          "name": "Google Sheets account"
        }
      }
    },
    {
      "parameters": {
        "operation": "append",
        "documentId": {
          "__rl": true,
          "value": "={{ $('Pull From YouTube Video Info Sheet').item.json['YouTube Comments File'] }}",
          "mode": "url"
        },
        "sheetName": {
          "__rl": true,
          "value": "Comments and Responses",
          "mode": "name"
        },
        "columns": {
          "mappingMode": "defineBelow",
          "value": {
            "Comment": "={{ $json.snippet.topLevelComment.snippet.textOriginal }}",
            "Commenter Name": "={{ $json.snippet.topLevelComment.snippet.authorDisplayName }}",
            "Comment Time": "={{ $json.snippet.topLevelComment.snippet.publishedAt }}"
          },
          "matchingColumns": [],
          "schema": [
            {
              "id": "Comment",
              "displayName": "Comment",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "removed": false
            },
            {
              "id": "Response",
              "displayName": "Response",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "removed": false
            },
            {
              "id": "Commenter Name",
              "displayName": "Commenter Name",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "removed": false
            },
            {
              "id": "Sentiment",
              "displayName": "Sentiment",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "removed": false
            },
            {
              "id": "Comment Time",
              "displayName": "Comment Time",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "removed": false
            },
            {
              "id": "Response Approved?",
              "displayName": "Response Approved?",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "removed": false
            },
            {
              "id": "Response Submitted?",
              "displayName": "Response Submitted?",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "removed": false
            },
            {
              "id": "Response Time",
              "displayName": "Response Time",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "removed": false
            }
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {}
      },
      "type": "n8n-nodes-base.googleSheets",
      "typeVersion": 4.5,
      "position": [
        1280,
        180
      ],
      "id": "7eafcdaa-07e9-42d9-9118-f2fd6fb8eb4b",
      "name": "Paste Comments",
      "credentials": {
        "googleSheetsOAuth2Api": {
          "id": "gbV7ZDvk1w563Bec",
          "name": "Google Sheets account"
        }
      }
    },
    {
      "parameters": {
        "operation": "update",
        "documentId": {
          "__rl": true,
          "value": "={{ $('Pull From YouTube Video Info Sheet').item.json['YouTube Comments File'] }}",
          "mode": "url"
        },
        "sheetName": {
          "__rl": true,
          "value": "Comments and Responses",
          "mode": "name"
        },
        "columns": {
          "mappingMode": "defineBelow",
          "value": {
            "Comment": "={{ $('Paste Comments').item.json.Comment }}",
            "Response": "={{ $json.output.response }}",
            "Sentiment": "={{ $json.output.sentiment }}"
          },
          "matchingColumns": [
            "Comment"
          ],
          "schema": [
            {
              "id": "Comment",
              "displayName": "Comment",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "removed": false
            },
            {
              "id": "Response",
              "displayName": "Response",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "removed": false
            },
            {
              "id": "Commenter Name",
              "displayName": "Commenter Name",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "removed": false
            },
            {
              "id": "Sentiment",
              "displayName": "Sentiment",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "removed": false
            },
            {
              "id": "Comment Time",
              "displayName": "Comment Time",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "removed": false
            },
            {
              "id": "Response Approved?",
              "displayName": "Response Approved?",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "removed": false
            },
            {
              "id": "Response Submitted?",
              "displayName": "Response Submitted?",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "removed": false
            },
            {
              "id": "Response Time",
              "displayName": "Response Time",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "removed": false
            },
            {
              "id": "row_number",
              "displayName": "row_number",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "readOnly": true,
              "removed": false
            }
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {}
      },
      "type": "n8n-nodes-base.googleSheets",
      "typeVersion": 4.5,
      "position": [
        1820,
        180
      ],
      "id": "802d4253-e38e-4374-adc9-9919d705c3f3",
      "name": "Add Response",
      "credentials": {
        "googleSheetsOAuth2Api": {
          "id": "gbV7ZDvk1w563Bec",
          "name": "Google Sheets account"
        }
      }
    },
    {
      "parameters": {
        "fieldToSplitOut": "items",
        "options": {}
      },
      "type": "n8n-nodes-base.splitOut",
      "typeVersion": 1,
      "position": [
        920,
        280
      ],
      "id": "260d23f1-0596-4131-b875-666c532ccc29",
      "name": "Split Out"
    },
    {
      "parameters": {},
      "type": "n8n-nodes-base.limit",
      "typeVersion": 1,
      "position": [
        1280,
        420
      ],
      "id": "28858679-5932-4afc-adac-f2c36e72b644",
      "name": "Limit"
    },
    {
      "parameters": {
        "jsonSchemaExample": "{  \n  \"response\": \"I understand, but we all need to learn how to live together\",  \n  \"sentiment\": \"NEUTRAL\"  \n}  "
      },
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "typeVersion": 1.2,
      "position": [
        1680,
        340
      ],
      "id": "6ecaad0c-ea86-4c4d-b434-7501aa3099a2",
      "name": "Structured Output Parser"
    },
    {
      "parameters": {},
      "type": "n8n-nodes-base.limit",
      "typeVersion": 1,
      "position": [
        2040,
        420
      ],
      "id": "431f75a7-1dbf-4fb1-b681-44da6b711fca",
      "name": "Limit1"
    },
    {
      "parameters": {
        "operation": "update",
        "documentId": {
          "__rl": true,
          "value": "1zDB8ZyMxEBMuLf0Uz4gNQqlxtV8ImSMsstJdDTWQZV8",
          "mode": "list",
          "cachedResultName": "BC YouTube Video Info",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1zDB8ZyMxEBMuLf0Uz4gNQqlxtV8ImSMsstJdDTWQZV8/edit?usp=drivesdk"
        },
        "sheetName": {
          "__rl": true,
          "value": 159089414,
          "mode": "list",
          "cachedResultName": "Video Info For Processing",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1zDB8ZyMxEBMuLf0Uz4gNQqlxtV8ImSMsstJdDTWQZV8/edit#gid=159089414"
        },
        "columns": {
          "mappingMode": "defineBelow",
          "value": {
            "Video File": "={{ $('Pull From YouTube Video Info Sheet').item.json['Video File'] }}",
            "Last Checked": "={{ $now }}"
          },
          "matchingColumns": [
            "Video File"
          ],
          "schema": [
            {
              "id": "Video File",
              "displayName": "Video File",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "removed": false
            },
            {
              "id": "Audio File Link",
              "displayName": "Audio File Link",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "YouTube Video ID",
              "displayName": "YouTube Video ID",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "YouTube Comments File",
              "displayName": "YouTube Comments File",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "Video Transcript File",
              "displayName": "Video Transcript File",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "removed": false
            },
            {
              "id": "Video Category",
              "displayName": "Video Category",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "removed": false
            },
            {
              "id": "Referenced Videos",
              "displayName": "Referenced Videos",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "Google Keywords",
              "displayName": "Google Keywords",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "Video Title",
              "displayName": "Video Title",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "Description",
              "displayName": "Description",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "Video Tags",
              "displayName": "Video Tags",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "Last Checked",
              "displayName": "Last Checked",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "Blog Posted?",
              "displayName": "Blog Posted?",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "removed": false
            },
            {
              "id": "Blog Link",
              "displayName": "Blog Link",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "removed": false
            },
            {
              "id": "LinkedIn Posted?",
              "displayName": "LinkedIn Posted?",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "removed": false
            },
            {
              "id": "LinkedIn Post Link",
              "displayName": "LinkedIn Post Link",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "removed": false
            },
            {
              "id": "Reddit Posted?",
              "displayName": "Reddit Posted?",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "removed": false
            },
            {
              "id": "row_number",
              "displayName": "row_number",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "readOnly": true,
              "removed": true
            }
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {}
      },
      "type": "n8n-nodes-base.googleSheets",
      "typeVersion": 4.5,
      "position": [
        2040,
        180
      ],
      "id": "9c5c3ea8-0114-44a6-aae2-ea95cfd9b9de",
      "name": "Update Time",
      "credentials": {
        "googleSheetsOAuth2Api": {
          "id": "gbV7ZDvk1w563Bec",
          "name": "Google Sheets account"
        }
      }
    },
    {
      "parameters": {
        "content": "# Instructions\n\n## Initial Setup\n\nConnect and configure the following credentials:\n\n- **Google Services**\n  - **Google Sheets OAuth2**: Required to read from and write to your YouTube tracking sheets.\n  - **Google Drive OAuth2**: Required to move new spreadsheet documents into the designated folder.\n- **YouTube OAuth2**: Required to pull YouTube comment data.\n- **OpenAI API Key**: Required to analyze sentiment and generate responses to YouTube comments via the AI Agent.\n\n> **Note**: This workflow assumes you are storing YouTube video metadata in a central spreadsheet titled **YouTube Video Info Sheet**, and that each video has its own row. The workflow will automatically create a new comment tracking sheet and update the main info sheet with a link to it.\n\n---\n\n## Using This Workflow\n\nThis workflow automatically pulls new YouTube comments for a list of videos, analyzes their sentiment with an AI agent, and generates suggested replies. Results are saved into a structured Google Sheet for each video.\n\n### Here's how it works:\n\n1. **Schedule Trigger**\n   - Runs every hour at 5 minutes past the hour.\n\n2. **Pull From YouTube Video Info**\n   - Loads video metadata from the **Video Info For Processing** tab of the master tracking spreadsheet.\n\n3. **If Existing Comment File?**\n   - Checks whether a comment file already exists for the video.\n   - If no file is listed, it creates a new one.\n   - If a file already exists, it jumps straight to pulling new comments.\n\n4. **Create Google Sheet + Move to Drive Folder**\n   - Creates a new Google Sheet titled after the video and moves it into a folder named `Comment Files`.\n\n5. **Edit Fields + Code1**\n   - Prepares the comment header structure and writes the column headers into the new spreadsheet.\n\n6. **Remove Extra Row**\n   - Deletes the default empty row created in the spreadsheet to avoid formatting issues.\n\n7. **Add Comments File URL**\n   - Updates the master spreadsheet with the new comment sheet's URL and timestamps the last check.\n\n8. **Loop Over Items**\n   - Iterates over each video record in the master sheet.\n\n9. **HTTP Request**\n   - Uses the YouTube Data API to fetch the 10 most recent comments for the video.\n\n10. **Split Out + If1**\n    - Splits individual comments and filters for only those **newer** than the last timestamp recorded in `Last Checked`.\n\n11. **Paste Comments**\n    - Adds the new comments into the comment tracking sheet with commenter name and timestamp.\n\n12. **AI Agent**\n    - Analyzes each comment with an AI agent to classify its sentiment and generate a friendly, tailored reply.\n\n13. **Add Response**\n    - Inserts the AI-generated reply and sentiment classification into the corresponding row in the comment spreadsheet.\n\n14. **Update Time**\n    - Updates the `Last Checked` value in the master tracking sheet to avoid re-processing old comments.\n\n---\n\n## Benefits\n\n- **Fully automated comment monitoring** for YouTube content  \n- Saves hours by **auto-generating sentiment and replies**  \n- Seamless **Google Sheets integration** with centralized data  \n- Easily scales to handle **multiple videos on a schedule**  \n- Ensures **comments are reviewed only once** using timestamp logic\n\n---\n\n## Tips & Customization\n\n- Update the **YouTube Video Info** spreadsheet before this workflow runs with the latest videos.\n- To change where comment files are stored, update the `folderId` in the **Google Drive** node.\n- Modify the **AI prompt** in the `AI Agent` node to align with your channel’s tone or response goals.\n- You can adjust how many comments are fetched by changing the `maxResults` value in the **HTTP Request** node.\n- Monitor **YouTube API quota** and **OpenAI API usage** if running frequently on many videos.\n\n---\n",
        "height": 2060,
        "width": 960
      },
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1220,
        -680
      ],
      "typeVersion": 1,
      "id": "cbf7e051-dec6-41e5-bee9-53b92cca5d03",
      "name": "Sticky Note"
    },
    {
      "parameters": {
        "documentId": {
          "__rl": true,
          "value": "1zDB8ZyMxEBMuLf0Uz4gNQqlxtV8ImSMsstJdDTWQZV8",
          "mode": "list",
          "cachedResultName": "BC YouTube Video Info",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1zDB8ZyMxEBMuLf0Uz4gNQqlxtV8ImSMsstJdDTWQZV8/edit?usp=drivesdk"
        },
        "sheetName": {
          "__rl": true,
          "value": 159089414,
          "mode": "list",
          "cachedResultName": "Video Info For Processing",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1zDB8ZyMxEBMuLf0Uz4gNQqlxtV8ImSMsstJdDTWQZV8/edit#gid=159089414"
        },
        "options": {}
      },
      "type": "n8n-nodes-base.googleSheets",
      "typeVersion": 4.5,
      "position": [
        60,
        0
      ],
      "id": "b2e99387-7686-4933-9034-9969360c5775",
      "name": "Pull From YouTube Video Info Sheet",
      "credentials": {
        "googleSheetsOAuth2Api": {
          "id": "gbV7ZDvk1w563Bec",
          "name": "Google Sheets account"
        }
      }
    },
    {
      "parameters": {
        "content": "# The YouTube Comment Responder\n\n## Automate Business AI\n### By Bradford Carlton",
        "height": 180,
        "width": 600
      },
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        480,
        -420
      ],
      "typeVersion": 1,
      "id": "585f0346-b077-43e1-a0a7-2b89bee9c9a8",
      "name": "Sticky Note4"
    },
    {
      "parameters": {
        "options": {}
      },
      "type": "n8n-nodes-base.splitInBatches",
      "typeVersion": 3,
      "position": [
        560,
        -160
      ],
      "id": "7fe5d22f-f035-4c01-a6e6-fde6e75bcc86",
      "name": "Loop Over Items1"
    }
  ],
  "pinData": {
    "Schedule Trigger": [
      {
        "json": {
          "timestamp": "2025-04-24T11:05:22.005-07:00",
          "Readable date": "April 24th 2025, 11:05:22 am",
          "Readable time": "11:05:22 am",
          "Day of week": "Thursday",
          "Year": "2025",
          "Month": "April",
          "Day of month": "24",
          "Hour": "11",
          "Minute": "05",
          "Second": "22",
          "Timezone": "America/Los_Angeles (UTC-07:00)"
        }
      }
    ]
  },
  "connections": {
    "Schedule Trigger": {
      "main": [
        [
          {
            "node": "Pull From YouTube Video Info Sheet",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "If": {
      "main": [
        [
          {
            "node": "Loop Over Items1",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Google Drive": {
      "main": [
        [
          {
            "node": "Edit Fields",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Edit Fields": {
      "main": [
        [
          {
            "node": "Code1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Code1": {
      "main": [
        [
          {
            "node": "Add Row Headings",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Create Google Sheets Doc": {
      "main": [
        [
          {
            "node": "Google Drive",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Add Row Headings": {
      "main": [
        [
          {
            "node": "Remove Extra Row",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Loop Over Items": {
      "main": [
        [],
        [
          {
            "node": "HTTP Request",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "HTTP Request": {
      "main": [
        [
          {
            "node": "Split Out",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "If1": {
      "main": [
        [
          {
            "node": "Paste Comments",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Limit",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "AI Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Remove Extra Row": {
      "main": [
        [
          {
            "node": "Add Comments File URL",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Paste Comments": {
      "main": [
        [
          {
            "node": "AI Agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "AI Agent": {
      "main": [
        [
          {
            "node": "Add Response",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Split Out": {
      "main": [
        [
          {
            "node": "If1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Limit": {
      "main": [
        [
          {
            "node": "Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Structured Output Parser": {
      "ai_outputParser": [
        [
          {
            "node": "AI Agent",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    },
    "Add Response": {
      "main": [
        [
          {
            "node": "Update Time",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Limit1": {
      "main": [
        [
          {
            "node": "Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Update Time": {
      "main": [
        [
          {
            "node": "Limit1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Pull From YouTube Video Info Sheet": {
      "main": [
        [
          {
            "node": "If",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Loop Over Items1": {
      "main": [
        [],
        [
          {
            "node": "Create Google Sheets Doc",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Add Comments File URL": {
      "main": [
        [
          {
            "node": "Loop Over Items1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "active": true,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "3a2c4ebe-26ad-4227-b1fc-aee5cc8365c6",
  "meta": {
    "templateCredsSetupCompleted": true,
    "instanceId": "755f8e384ae78a7dedbf592ffbd1a01c56d86a07241ef8bcfb307935a604c790"
  },
  "id": "CmLEK7wB274ILd5Y",
  "tags": [
    {
      "createdAt": "2025-03-10T21:36:47.226Z",
      "updatedAt": "2025-03-10T21:36:47.226Z",
      "id": "aFiyGtZ7jL976uPD",
      "name": "Free Giveaways"
    }
  ]
}