{
  "nodes": [
    {
      "id": "62f5598c-aed5-4800-b7b3-99d2cf55fcc5",
      "name": "\ud83d\udccb Workflow Overview",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        128,
        464
      ],
      "parameters": {
        "width": 564,
        "height": 704,
        "content": "## LinkedIn Keyword Auto-DM Responder\n**Auto-send DMs to commenters using trigger keywords**\n\n@[youtube](8Pe0DB_pItY)\n\n### How It Works\n1. Submit form with post URL + keyword\n2. Scans all comments for your keyword\n3. Checks if commenter is a 1st connection\n4. Sends personalized DM with your link\n5. Waits 15-30 min between messages\n\n### Setup Required\n1. Install `n8n-nodes-connectsafely-ai` community node\n2. Add ConnectSafely.AI API credentials\n3. Customize DM template in node 9\ufe0f\u20e3"
      },
      "typeVersion": 1
    },
    {
      "id": "350787fc-5a89-4e84-9584-c37e0c38c25f",
      "name": "\ud83d\udce5 Input",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        720,
        704
      ],
      "parameters": {
        "width": 260,
        "height": 288,
        "content": "## \ud83d\udce5 Input\nForm captures post URL, trigger keyword, and your content link."
      },
      "typeVersion": 1
    },
    {
      "id": "8fee1bbf-6927-4967-9388-022695f28ebd",
      "name": "\ud83d\udd0d Fetch Comments",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1008,
        704
      ],
      "parameters": {
        "width": 520,
        "height": 288,
        "content": "## \ud83d\udd0d Fetch & Split\nRetrieves all comments from the LinkedIn post and splits them for individual processing."
      },
      "typeVersion": 1
    },
    {
      "id": "1c5cbdbd-bb31-496e-ba3e-2fe58de1271f",
      "name": "\ud83d\udd04 Loop",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1600,
        704
      ],
      "parameters": {
        "width": 308,
        "height": 288,
        "content": "## \ud83d\udd04 Process Loop\nHandles each comment one by one, returning here after each cycle."
      },
      "typeVersion": 1
    },
    {
      "id": "6f2936d8-a31e-4a83-b477-e7636312a63c",
      "name": "\ud83c\udfaf Keyword Check",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1952,
        688
      ],
      "parameters": {
        "width": 584,
        "height": 344,
        "content": "## \ud83c\udfaf Keyword Detection\nScans comment for trigger keyword (case-insensitive). Routes matches to connection check."
      },
      "typeVersion": 1
    },
    {
      "id": "3d5f37cd-b989-45c0-84f5-740768112c23",
      "name": "\ud83d\udd17 Connection Check",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2672,
        688
      ],
      "parameters": {
        "width": 660,
        "height": 320,
        "content": "## \ud83d\udd17 Connection Check\nVerifies if commenter is a 1st connection. Only connected users can receive DMs."
      },
      "typeVersion": 1
    },
    {
      "id": "4455d1f8-331e-42b9-b734-8b5b9d4ef8c3",
      "name": "\ud83d\udce8 Send & Wait",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3440,
        688
      ],
      "parameters": {
        "width": 484,
        "height": 272,
        "content": "## \ud83d\udce8 Send & Rate Limit\nSends personalized DM with your link. Waits 15-30 min before next message for account safety."
      },
      "typeVersion": 1
    },
    {
      "id": "cfa450d5-d9b1-42b5-b3cc-62d142097c63",
      "name": "\u23ed\ufe0f Skip Path",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3408,
        976
      ],
      "parameters": {
        "width": 260,
        "height": 200,
        "content": "## \u23ed\ufe0f Skip\nHandles non-matches and non-connections. Returns to loop for next comment."
      },
      "typeVersion": 1
    },
    {
      "id": "436197d9-46fd-4f02-928f-9d368fd5ccd1",
      "name": "1\ufe0f\u20e3 Form: Enter Post Details",
      "type": "n8n-nodes-base.formTrigger",
      "position": [
        784,
        816
      ],
      "parameters": {
        "options": {},
        "formTitle": "\ud83e\udd16 LinkedIn Keyword Auto-Responder",
        "formFields": {
          "values": [
            {
              "fieldLabel": "LinkedIn Post URL",
              "placeholder": "https://www.linkedin.com/posts/username_topic-activity-1234567890...",
              "requiredField": true
            },
            {
              "fieldLabel": "Trigger Keyword",
              "placeholder": "code",
              "requiredField": true
            },
            {
              "fieldLabel": "Content Link to Send",
              "placeholder": "https://your-link.com/resource",
              "requiredField": true
            },
            {
              "fieldLabel": "Your Name (for signature)",
              "placeholder": "Your Name",
              "requiredField": true
            }
          ]
        },
        "formDescription": "## Send Automatic DMs to Comment Keywords\n\nThis workflow monitors your LinkedIn post for specific keywords and automatically sends a personalized DM with your content link.\n\n---\n\n### \ud83d\udcdd How to Use:\n1. **Post URL** - Paste the full LinkedIn post URL\n2. **Keyword** - The word to trigger a DM (e.g., \"code\", \"example\")\n3. **Link** - The URL/content to send\n\n---\n\n### \ud83d\udca1 Tips:\n- Use unique keywords to avoid false positives\n- Make sure the post has comments\n- Only 1st connections will receive DMs\n\n---\n\n**Powered by ConnectSafely.ai**"
      },
      "typeVersion": 2.3
    },
    {
      "id": "e98555f5-99c0-4c14-b78a-904bad35a77f",
      "name": "2\ufe0f\u20e3 Fetch All Comments",
      "type": "n8n-nodes-connectsafely-ai.connectSafelyLinkedIn",
      "position": [
        1056,
        816
      ],
      "parameters": {
        "postUrl": "={{ $json['LinkedIn Post URL'] }}",
        "accountId": "68ecc8f6ae3fb53989597a55",
        "operation": "getPostComments"
      },
      "typeVersion": 1
    },
    {
      "id": "c4d93ff8-85c3-4373-9c8b-45b8ecbcf612",
      "name": "3\ufe0f\u20e3 Split Comments Array",
      "type": "n8n-nodes-base.splitOut",
      "position": [
        1344,
        816
      ],
      "parameters": {
        "options": {},
        "fieldToSplitOut": "comments"
      },
      "typeVersion": 1
    },
    {
      "id": "b29e215f-bcf5-4ab8-a48e-b58e09e7e350",
      "name": "4\ufe0f\u20e3 Loop: Process Each Comment",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        1680,
        816
      ],
      "parameters": {
        "options": {
          "reset": false
        }
      },
      "typeVersion": 3
    },
    {
      "id": "2719d6ee-32c0-43b9-a94e-ee48eac76d26",
      "name": "5\ufe0f\u20e3 Detect Keyword Match",
      "type": "n8n-nodes-base.code",
      "position": [
        2016,
        832
      ],
      "parameters": {
        "jsCode": "// YOUR_AWS_SECRET_KEY_HERE=============\n// \ud83d\udd0d KEYWORD DETECTION ENGINE\n// YOUR_AWS_SECRET_KEY_HERE=============\n// This code checks if the comment contains the trigger keyword\n//\n// \ud83d\udcdd CUSTOMIZATION:\n// - Modify this to check multiple keywords\n// - Add regex patterns for advanced matching\n// - Exclude certain phrases\n// YOUR_AWS_SECRET_KEY_HERE=============\n\n// Get the comment text from current item\nconst commentText = $input.first().json.commentText || \"\";\n\n// Get the keyword from the form submission\nconst keyword = $('1\ufe0f\u20e3 Form: Enter Post Details').first().json['Trigger Keyword'] || \"\";\n\n// YOUR_AWS_SECRET_KEY_HERE=============\n// \ud83c\udfaf MATCHING LOGIC\n// YOUR_AWS_SECRET_KEY_HERE=============\n// Case-insensitive matching\n// You can modify this for:\n// - Exact match: commentText.toLowerCase() === keyword.toLowerCase()\n// - Multiple keywords: keywords.some(k => commentText.includes(k))\n// - Regex: /pattern/.test(commentText)\n\nconst isMatch = commentText.toLowerCase().includes(keyword.toLowerCase());\n\n// YOUR_AWS_SECRET_KEY_HERE=============\n// \ud83d\udce4 OUTPUT\n// YOUR_AWS_SECRET_KEY_HERE=============\nreturn [\n  {\n    json: {\n      isKeywordMatch: isMatch,\n      commentText: commentText,\n      searchedKeyword: keyword,\n      matchDetails: isMatch ? `Found \"${keyword}\" in comment` : `No match for \"${keyword}\"`\n    }\n  }\n];\n"
      },
      "typeVersion": 2
    },
    {
      "id": "8e16ff0e-f822-432f-843e-f46b38f1fa48",
      "name": "6\ufe0f\u20e3 If: Keyword Found?",
      "type": "n8n-nodes-base.if",
      "position": [
        2288,
        832
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "condition-keyword-match",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              },
              "leftValue": "={{ $json.isKeywordMatch }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "cfe261a2-91fa-4a22-bea9-8a232718f8f8",
      "name": "7\ufe0f\u20e3 Check Connection Status",
      "type": "n8n-nodes-connectsafely-ai.connectSafelyLinkedIn",
      "position": [
        2816,
        816
      ],
      "parameters": {
        "accountId": "68ecc8f6ae3fb53989597a55",
        "operation": "checkRelationship",
        "profileId": "={{ $('4\ufe0f\u20e3 Loop: Process Each Comment').item.json.publicIdentifier }}"
      },
      "typeVersion": 1
    },
    {
      "id": "5fa73034-5aa6-4428-a75e-964708f06a53",
      "name": "8\ufe0f\u20e3 If: Connected?",
      "type": "n8n-nodes-base.if",
      "position": [
        3136,
        816
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "condition-connected",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              },
              "leftValue": "={{ $json.connected }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "fb02577e-2ec3-4c37-911f-f980a8728fac",
      "name": "9\ufe0f\u20e3 Send DM with Link",
      "type": "n8n-nodes-connectsafely-ai.connectSafelyLinkedIn",
      "position": [
        3488,
        800
      ],
      "parameters": {
        "message": "=Hey {{ $('4\ufe0f\u20e3 Loop: Process Each Comment').item.json.authorName }}! \ud83d\udc4b\n\nThanks for your comment on my post!\n\nAs promised, here's the link you requested:\n\ud83d\udc49 {{ $('1\ufe0f\u20e3 Form: Enter Post Details').item.json['Content Link to Send'] }}\n\nIf you have any questions or want more resources like this, just let me know!\n\nBest,\n{{ $('1\ufe0f\u20e3 Form: Enter Post Details').item.json['Your Name (for signature)'] }}",
        "accountId": "68ecc8f6ae3fb53989597a55",
        "operation": "sendMessage",
        "recipientProfileId": "={{ $('4\ufe0f\u20e3 Loop: Process Each Comment').item.json.publicIdentifier }}"
      },
      "typeVersion": 1
    },
    {
      "id": "9d8921e1-4d56-4a9c-9737-4159964e0eeb",
      "name": "\ud83d\udd1f Wait: Rate Limiting",
      "type": "n8n-nodes-base.wait",
      "position": [
        3744,
        800
      ],
      "parameters": {
        "amount": "={{ Math.floor(Math.random() * (1800 - 900 + 1)) + 900 }}"
      },
      "typeVersion": 1.1
    },
    {
      "id": "bb91b56a-f651-49ae-8a09-84b9538a7090",
      "name": "\u23ed\ufe0f Skip: No Match / Not Connected",
      "type": "n8n-nodes-base.noOp",
      "position": [
        3440,
        1088
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "54616d6d-9253-41d0-ae6d-e68405f4e8b6",
      "name": "\u2705 All Comments Processed",
      "type": "n8n-nodes-base.noOp",
      "position": [
        2112,
        528
      ],
      "parameters": {},
      "typeVersion": 1
    }
  ],
  "connections": {
    "8\ufe0f\u20e3 If: Connected?": {
      "main": [
        [
          {
            "node": "9\ufe0f\u20e3 Send DM with Link",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "\u23ed\ufe0f Skip: No Match / Not Connected",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\ud83d\udd1f Wait: Rate Limiting": {
      "main": [
        [
          {
            "node": "4\ufe0f\u20e3 Loop: Process Each Comment",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "9\ufe0f\u20e3 Send DM with Link": {
      "main": [
        [
          {
            "node": "\ud83d\udd1f Wait: Rate Limiting",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "2\ufe0f\u20e3 Fetch All Comments": {
      "main": [
        [
          {
            "node": "3\ufe0f\u20e3 Split Comments Array",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "6\ufe0f\u20e3 If: Keyword Found?": {
      "main": [
        [
          {
            "node": "7\ufe0f\u20e3 Check Connection Status",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "\u23ed\ufe0f Skip: No Match / Not Connected",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "3\ufe0f\u20e3 Split Comments Array": {
      "main": [
        [
          {
            "node": "4\ufe0f\u20e3 Loop: Process Each Comment",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "5\ufe0f\u20e3 Detect Keyword Match": {
      "main": [
        [
          {
            "node": "6\ufe0f\u20e3 If: Keyword Found?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "7\ufe0f\u20e3 Check Connection Status": {
      "main": [
        [
          {
            "node": "8\ufe0f\u20e3 If: Connected?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "1\ufe0f\u20e3 Form: Enter Post Details": {
      "main": [
        [
          {
            "node": "2\ufe0f\u20e3 Fetch All Comments",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "4\ufe0f\u20e3 Loop: Process Each Comment": {
      "main": [
        [
          {
            "node": "\u2705 All Comments Processed",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "5\ufe0f\u20e3 Detect Keyword Match",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\u23ed\ufe0f Skip: No Match / Not Connected": {
      "main": [
        [
          {
            "node": "4\ufe0f\u20e3 Loop: Process Each Comment",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}