{
  "id": "nqmmC4Z0cU9UFtVk",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "AI-Powered Instagram Comment Auto-Reply",
  "tags": [],
  "nodes": [
    {
      "id": "5683fa49-d9bf-48ea-b449-32b6b7ea8c9a",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2064,
        -1024
      ],
      "parameters": {
        "color": 4,
        "width": 386.9707535069169,
        "height": 343.8950932756325,
        "content": "## \ud83d\ude80 WORKFLOW START\n\nThis workflow automatically monitors Instagram comments and replies with AI-generated responses.\n\n**Features:**\n- Real-time comment monitoring\n- AI-powered contextual replies\n- Duplicate prevention\n- Spam filtering\n- Engagement tracking"
      },
      "typeVersion": 1
    },
    {
      "id": "c4e05953-bd04-4c02-a615-634ba52ecd8f",
      "name": "Schedule Trigger",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        -2784,
        -304
      ],
      "parameters": {
        "rule": {
          "interval": [
            {}
          ]
        }
      },
      "typeVersion": 1
    },
    {
      "id": "7ceb7a5c-90bd-4cd3-8648-c85f590f611a",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2864,
        -640
      ],
      "parameters": {
        "color": 5,
        "width": 252,
        "height": 490,
        "content": "## \u23f0 TRIGGER\n\nRuns every 5 minutes to check for new comments.\n\nAdjust frequency based on your needs:\n- High traffic: 2-3 min\n- Medium: 5 min\n- Low: 10-15 min"
      },
      "typeVersion": 1
    },
    {
      "id": "e354447a-b2ba-47cf-a0d9-7184d9364440",
      "name": "Get Recent Posts",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -2560,
        -304
      ],
      "parameters": {
        "url": "https://graph.instagram.com/me/media",
        "method": "POST",
        "options": {},
        "sendQuery": true,
        "authentication": "predefinedCredentialType",
        "queryParameters": {
          "parameters": [
            {
              "name": "fields",
              "value": "id,caption,media_type,media_url,timestamp"
            },
            {
              "name": "limit",
              "value": "10"
            }
          ]
        },
        "nodeCredentialType": "instagramGraphApi"
      },
      "typeVersion": 4.1
    },
    {
      "id": "8775e252-f86d-407d-ac28-4dc5bd1f7a6f",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2592,
        -640
      ],
      "parameters": {
        "color": 6,
        "width": 369,
        "height": 485,
        "content": "## \ud83d\udcf8 GET POSTS\n\nFetches your 10 most recent Instagram posts.\n\n**API Endpoint:**\n`/me/media`\n\nReturns post IDs needed to fetch comments."
      },
      "typeVersion": 1
    },
    {
      "id": "482867b5-c987-4189-ac71-a23fb13990b1",
      "name": "Split Posts",
      "type": "n8n-nodes-base.splitOut",
      "position": [
        -2336,
        -304
      ],
      "parameters": {
        "options": {},
        "fieldToSplitOut": "data"
      },
      "typeVersion": 1
    },
    {
      "id": "c7f4585f-5ca3-47d1-8488-9a6f42c14c33",
      "name": "Get Comments",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -2112,
        -232
      ],
      "parameters": {
        "url": "=https://graph.instagram.com/{{ $json.id }}/comments",
        "options": {},
        "sendQuery": true,
        "authentication": "predefinedCredentialType",
        "queryParameters": {
          "parameters": [
            {
              "name": "fields",
              "value": "id,text,username,timestamp,like_count"
            }
          ]
        },
        "nodeCredentialType": "instagramGraphApi"
      },
      "typeVersion": 4.1
    },
    {
      "id": "04491271-b169-4d02-bec3-923b2d3a5b0d",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2160,
        -640
      ],
      "parameters": {
        "color": 6,
        "width": 225,
        "height": 533,
        "content": "## \ud83d\udcac GET COMMENTS\n\nFetches all comments for each post.\n\n**Returns:**\n- Comment ID\n- Text content\n- Username\n- Timestamp\n- Like count"
      },
      "typeVersion": 1
    },
    {
      "id": "70bdb008-0d55-4b4f-9c35-4927fe944575",
      "name": "Split Comments",
      "type": "n8n-nodes-base.splitOut",
      "position": [
        -1888,
        -232
      ],
      "parameters": {
        "options": {},
        "fieldToSplitOut": "data"
      },
      "typeVersion": 1
    },
    {
      "id": "60f13b8f-2627-4cfe-a0ab-2d1f73abb34f",
      "name": "Add Post Context",
      "type": "n8n-nodes-base.merge",
      "position": [
        -1664,
        -304
      ],
      "parameters": {
        "mode": "combine",
        "options": {},
        "combinationMode": "multiplex"
      },
      "typeVersion": 2.1
    },
    {
      "id": "bb387325-4f62-4663-8ab3-b76827c9fe50",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1904,
        -624
      ],
      "parameters": {
        "color": 7,
        "width": 385,
        "height": 508,
        "content": "## \ud83d\udd17 MERGE DATA\n\nCombines comment data with original post context.\n\nThis gives AI the post caption/content to generate relevant replies."
      },
      "typeVersion": 1
    },
    {
      "id": "d7a6591d-f4f2-40b0-8d4e-fb7bdfd12e35",
      "name": "Check If Replied",
      "type": "n8n-nodes-base.redis",
      "position": [
        -1440,
        -304
      ],
      "parameters": {
        "key": "=replied_{{ $json.id }}",
        "options": {},
        "operation": "get"
      },
      "credentials": {
        "redis": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "cf422c6c-ee36-4df6-be1b-307d788ed305",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1504,
        -640
      ],
      "parameters": {
        "color": 3,
        "width": 209,
        "height": 506,
        "content": "## \u2705 DUPLICATE CHECK\n\nChecks Redis to see if we already replied to this comment.\n\n**Key format:**\n`replied_{comment_id}`\n\nPrevents sending multiple replies to same comment."
      },
      "typeVersion": 1
    },
    {
      "id": "b1c8ba7e-85f2-4a91-8aaa-2457e520fd5f",
      "name": "Not Replied Yet?",
      "type": "n8n-nodes-base.if",
      "position": [
        -1216,
        -304
      ],
      "parameters": {
        "conditions": {
          "string": [
            {
              "value1": "={{ $json.reply }}",
              "operation": "isEmpty"
            }
          ]
        }
      },
      "typeVersion": 1
    },
    {
      "id": "b81c50e5-50b2-413c-8cf3-b2090d5785ed",
      "name": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1264,
        -640
      ],
      "parameters": {
        "color": 3,
        "width": 209,
        "height": 502,
        "content": "## \ud83d\udea6 FILTER\n\nOnly processes comments that haven't been replied to yet.\n\n**Logic:**\nIf reply key is empty \u2192 Continue\nIf reply key exists \u2192 Skip"
      },
      "typeVersion": 1
    },
    {
      "id": "131dae48-de89-4580-8008-d0f922e7242a",
      "name": "Spam Filter",
      "type": "n8n-nodes-base.code",
      "position": [
        -992,
        -304
      ],
      "parameters": {
        "jsCode": "// Spam detection keywords\nconst spamKeywords = ['buy now', 'click here', 'dm me', 'check bio', 'follow for follow', 'f4f', 'l4l', 'spam', 'bot'];\n\nconst commentText = $input.item.json.text.toLowerCase();\n\n// Check for spam\nconst isSpam = spamKeywords.some(keyword => commentText.includes(keyword));\n\n// Check if comment is too short (likely not genuine)\nconst isTooShort = commentText.length < 3;\n\n// Check if comment is just emojis\nconst isOnlyEmojis = /^[\\p{Emoji}\\s]+$/u.test(commentText);\n\nreturn {\n  json: {\n    ...($input.item.json),\n    isSpam: isSpam,\n    isTooShort: isTooShort,\n    isOnlyEmojis: isOnlyEmojis,\n    shouldReply: !isSpam && !isTooShort && !isOnlyEmojis\n  }\n};"
      },
      "typeVersion": 2
    },
    {
      "id": "fc683c62-62ae-4e5e-9239-1e4e41ef5e97",
      "name": "Sticky Note7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1024,
        -640
      ],
      "parameters": {
        "color": 3,
        "width": 209,
        "height": 500,
        "content": "## \ud83d\udee1\ufe0f SPAM DETECTION\n\nFilters out:\n- Spam keywords\n- Very short comments (<3 chars)\n- Emoji-only comments\n- Promotional content\n\nPrevents wasting API calls on spam."
      },
      "typeVersion": 1
    },
    {
      "id": "26e242b0-222f-40de-99a3-fa93cd708fca",
      "name": "Should Reply?",
      "type": "n8n-nodes-base.if",
      "position": [
        -768,
        -304
      ],
      "parameters": {
        "conditions": {
          "boolean": [
            {
              "value1": "={{ $json.shouldReply }}",
              "value2": true
            }
          ]
        }
      },
      "typeVersion": 1
    },
    {
      "id": "8030a81c-c057-40fb-a8cc-885a3d18dd31",
      "name": "Generate AI Reply",
      "type": "@n8n/n8n-nodes-langchain.openAi",
      "position": [
        -544,
        -304
      ],
      "parameters": {
        "resource": "chat"
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "45b050d2-f682-443d-a2ff-38cf0dca8b2a",
      "name": "Sticky Note8",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -800,
        -640
      ],
      "parameters": {
        "color": 2,
        "width": 369,
        "height": 486,
        "content": "## \ud83e\udd16 AI GENERATION\n\nUses GPT-4o-mini to generate contextual replies.\n\n**Prompt includes:**\n- Post caption\n- Comment text\n- Username\n\n**Settings:**\n- Temperature: 0.8 (creative)\n- Max tokens: 150\n- Tone: Friendly & engaging"
      },
      "typeVersion": 1
    },
    {
      "id": "c1873eb7-005f-4557-94ad-3a1d9f0c536c",
      "name": "Post Reply",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -320,
        -304
      ],
      "parameters": {
        "url": "=https://graph.instagram.com/{{ $json.id }}/replies",
        "method": "POST",
        "options": {},
        "sendBody": true,
        "authentication": "predefinedCredentialType",
        "bodyParameters": {
          "parameters": [
            {
              "name": "message",
              "value": "={{ $json.message.content }}"
            }
          ]
        },
        "nodeCredentialType": "instagramGraphApi"
      },
      "typeVersion": 4.1
    },
    {
      "id": "d325002a-7fe8-4af6-8792-7c57982d0a9f",
      "name": "Sticky Note9",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -384,
        -656
      ],
      "parameters": {
        "color": 6,
        "width": 209,
        "height": 516,
        "content": "## \ud83d\udce4 POST REPLY\n\nSends the AI-generated reply to Instagram.\n\n**API Endpoint:**\n`/{comment-id}/replies`\n\n**Method:** POST\n**Body:** message parameter"
      },
      "typeVersion": 1
    },
    {
      "id": "dea7eafb-d657-42bf-b80c-53e52bc5892b",
      "name": "Mark As Replied",
      "type": "n8n-nodes-base.redis",
      "position": [
        -96,
        -304
      ],
      "parameters": {
        "key": "=replied_{{ $json.id }}",
        "ttl": 2592000,
        "value": "=true",
        "expire": true,
        "operation": "set"
      },
      "credentials": {
        "redis": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "522eba11-6ac2-4d8f-b768-0f19fdee2319",
      "name": "Sticky Note10",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -144,
        -656
      ],
      "parameters": {
        "color": 3,
        "width": 225,
        "height": 532,
        "content": "## \ud83d\udcbe SAVE STATE\n\nStores comment ID in Redis with 30-day TTL.\n\n**Key:** `replied_{comment_id}`\n**Value:** true\n**TTL:** 30 days\n\nPrevents duplicate replies."
      },
      "typeVersion": 1
    },
    {
      "id": "04242788-8791-4460-ad1a-c68de0cbecd8",
      "name": "Log Reply",
      "type": "n8n-nodes-base.redis",
      "position": [
        128,
        -304
      ],
      "parameters": {
        "list": "instagram_replies_log",
        "operation": "push",
        "messageData": "={{ JSON.stringify({\n  commentId: $json.id,\n  username: $json.username,\n  comment: $json.text,\n  reply: $json.message.content,\n  postId: $json.postId,\n  timestamp: new Date().toISOString()\n}) }}"
      },
      "credentials": {
        "redis": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "8726c188-7840-4f50-8d48-5fc21f0a39b9",
      "name": "Sticky Note11",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        96,
        -656
      ],
      "parameters": {
        "color": 4,
        "width": 225,
        "height": 526,
        "content": "## \ud83d\udcca ANALYTICS\n\nLogs all replies to Redis list for tracking.\n\n**Stored data:**\n- Comment & reply text\n- Username\n- Timestamps\n- Post ID\n\nUse for analytics & reporting."
      },
      "typeVersion": 1
    },
    {
      "id": "aa73aa12-3b91-4812-83d9-d7e70139af17",
      "name": "Sticky Note13",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2592,
        -1216
      ],
      "parameters": {
        "width": 440,
        "height": 500,
        "content": "## \u2699\ufe0f SETUP REQUIRED\n\n1. **Instagram Credentials:**\n   - Add Instagram Graph API credentials\n   - Get access token from Meta Developer Portal\n\n2. **OpenAI API:**\n   - Add OpenAI credentials\n   - API key from platform.openai.com\n\n3. **Redis:**\n   - Set up Redis connection\n   - Used for duplicate prevention & logging\n\n4. **Customize:**\n   - Adjust trigger frequency\n   - Modify AI prompt tone\n   - Add custom spam keywords\n   - Set reply filters"
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "9c992c9f-45d1-4e53-bdb9-af3ebab17fff",
  "connections": {
    "Post Reply": {
      "main": [
        [
          {
            "node": "Mark As Replied",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Spam Filter": {
      "main": [
        [
          {
            "node": "Should Reply?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Split Posts": {
      "main": [
        [
          {
            "node": "Get Comments",
            "type": "main",
            "index": 0
          },
          {
            "node": "Add Post Context",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Comments": {
      "main": [
        [
          {
            "node": "Split Comments",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Should Reply?": {
      "main": [
        [
          {
            "node": "Generate AI Reply",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Split Comments": {
      "main": [
        [
          {
            "node": "Add Post Context",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Mark As Replied": {
      "main": [
        [
          {
            "node": "Log Reply",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Add Post Context": {
      "main": [
        [
          {
            "node": "Check If Replied",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check If Replied": {
      "main": [
        [
          {
            "node": "Not Replied Yet?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Recent Posts": {
      "main": [
        [
          {
            "node": "Split Posts",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Not Replied Yet?": {
      "main": [
        [
          {
            "node": "Spam Filter",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Schedule Trigger": {
      "main": [
        [
          {
            "node": "Get Recent Posts",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Generate AI Reply": {
      "main": [
        [
          {
            "node": "Post Reply",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}