{
  "name": "n8n workflow",
  "nodes": [
    {
      "id": "ad57cc04-508b-494a-9cf9-fbd7bb8f2b7b",
      "name": "Listen to submission from Instagram DM",
      "type": "n8n-nodes-base.jotFormTrigger",
      "notes": "This node listens to the submissions of the form that was sent to the instagram user via DM after commenting our post.",
      "position": [
        -160,
        -32
      ],
      "parameters": {
        "form": "252682338805059"
      },
      "notesInFlow": true,
      "typeVersion": 1
    },
    {
      "id": "4abccb8b-e942-4b40-8139-063c95537ad1",
      "name": "Structured Output Parser",
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "position": [
        944,
        112
      ],
      "parameters": {
        "jsonSchemaExample": "{\n  \"Insights\": \"This Instagram profile belongs to a niche film-photography enthusiast with a clear focus on analog shooting (Praktica MTL 50) and a strong visual aesthetic. With 293 followers, 49 posts and a high follow-to-follower ratio (781 follows vs 293 followers), the user is likely a hobbyist who actively seeks inspiration and community rather than a mass-market influencer. Key actionable insights for email marketing:\\n\\n1. **Interest & Content Focus** – Film photography, vintage gear, film stock, darkroom techniques, creative storytelling. Emails should feature gear reviews, film stock news, tutorials, and behind-the-lens stories.\\n\\n2. **Demographic & Psychographic** – Likely 20-35 years old, creative professionals or students, values authenticity, craftsmanship, and artistic expression. Motivated by community, learning opportunities, and exclusive deals.\\n\\n3. **Tone & Messaging Style** – Warm, slightly nostalgic, supportive, and aspirational. Use imagery-rich copy, analog metaphors, and a conversational voice that mirrors the user’s bio and captions.\\n\\n4. **Segmentation Opportunities** – Create a “Film-Photography Enthusiast” segment: those who follow similar accounts, engage with film-related content, or have shown interest in analog gear. Offer early access to film stock bundles, workshop invites, and discount codes for film-related accessories.\\n\\n5. **Email Topics & CTAs** – “New Film Stock Arrivals for Analog Lovers”, “Step-by-Step Darkroom Guide”, “Join Our Monthly Film-Photography Challenge”, “Exclusive Discount on Praktica-Compatible Lenses”. Each email should end with a clear CTA to join a community forum, download a free guide, or purchase gear.\\n\\n6. **Frequency & Timing** – Moderate cadence (2-3 emails/month) to avoid overwhelming a niche audience. Send during evenings or weekends when hobbyists are most likely to engage.\\n\\n7. **Cross-Channel Strategy** – Use Instagram stories and posts to tease email content, encouraging followers to sign up for the newsletter for deeper dives and special offers.\\n\\nBy aligning email content with the user’s passion for film photography and fostering a sense of community, you can increase engagement, conversion, and loyalty within this niche segment.\"\n}"
      },
      "typeVersion": 1.3
    },
    {
      "id": "5718f77d-b929-46b2-85ba-12ac7690eef2",
      "name": "OpenAI Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        832,
        80
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4.1-mini"
        },
        "options": {}
      },
      "typeVersion": 1.2
    },
    {
      "id": "a1aa8068-9705-4bd3-b499-0d0748e42561",
      "name": "Generate Insights",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "notes": "This AI Agent generates marketing insights from the instagram profile information.",
      "position": [
        768,
        -48
      ],
      "parameters": {
        "text": "=Analyze this instagram user and provide actionable insights about the user that would be useful for targeting in email marketing campaigns. Focus on interests, demographics, tone, and potential motivators that could inform segmentation and personalized messaging.\n\nBio:\n{{ $json.business_discovery.biography }}\n\nFollowers count:\n{{ $json.business_discovery.followers_count }}\n\nFollows count:\n{{ $json.business_discovery.follows_count }}\n\nMedia count:\n{{ $json.business_discovery.media_count }}\n\nProfile image:\n{{ $json.business_discovery.profile_picture_url }}",
        "options": {},
        "promptType": "define",
        "hasOutputParser": true
      },
      "notesInFlow": true,
      "typeVersion": 2.2
    },
    {
      "id": "bc985b69-18c1-4f54-a3f4-576372b24a26",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -256,
        -144
      ],
      "parameters": {
        "color": 7,
        "width": 496,
        "height": 656,
        "content": "## 1. Data reception"
      },
      "typeVersion": 1
    },
    {
      "id": "1354f78c-1f3a-4210-a077-f38af721c993",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        256,
        -144
      ],
      "parameters": {
        "color": 7,
        "width": 816,
        "height": 656,
        "content": "## 2. Data enrichment"
      },
      "typeVersion": 1
    },
    {
      "id": "b807e058-b7f3-47f1-b681-8c02532462e3",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1088,
        -144
      ],
      "parameters": {
        "color": 7,
        "width": 352,
        "height": 656,
        "content": "## 3. Saving data"
      },
      "typeVersion": 1
    },
    {
      "id": "e46e14a8-ac09-40d4-ac4a-fcac68a0c1b0",
      "name": "Profile type check",
      "type": "n8n-nodes-base.switch",
      "position": [
        480,
        -32
      ],
      "parameters": {
        "rules": {
          "values": [
            {
              "outputKey": "Professional profile",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "9a3e40e3-f14d-44fd-9e08-02e41368f081",
                    "operator": {
                      "type": "string",
                      "operation": "exists",
                      "singleValue": true
                    },
                    "leftValue": "={{ $json.business_discovery.id }}",
                    "rightValue": ""
                  }
                ]
              },
              "renameOutput": true
            },
            {
              "outputKey": "Personal profile",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "f54ffba0-9c50-4f1b-af7d-8a8bd4163c82",
                    "operator": {
                      "type": "number",
                      "operation": "exists",
                      "singleValue": true
                    },
                    "leftValue": "={{ $json.statusCode }}",
                    "rightValue": ""
                  }
                ]
              },
              "renameOutput": true
            }
          ]
        },
        "options": {}
      },
      "typeVersion": 3.3
    },
    {
      "id": "811b41e1-705e-44fa-afb9-202cd04ffdca",
      "name": "Subscribe contact with user insights",
      "type": "n8n-nodes-klicktipp.klicktipp",
      "notes": "This node subscribes the instagram user to KlickTipp with the enriched data.",
      "position": [
        1168,
        -48
      ],
      "parameters": {
        "email": "={{ $('Listen to submission from Instagram DM').item.json.Email }}",
        "tagId": "13614965",
        "fields": {
          "dataFields": [
            {
              "fieldId": "fieldFirstName",
              "fieldValue": "={{ $('Listen to submission from Instagram DM').item.json.Name.first }}"
            },
            {
              "fieldId": "fieldLastName",
              "fieldValue": "={{ $('Listen to submission from Instagram DM').item.json.Name.last }}"
            },
            {
              "fieldId": "field224100",
              "fieldValue": "={{ $('Listen to submission from Instagram DM').item.json.instagram_username }}"
            },
            {
              "fieldId": "field224125",
              "fieldValue": "={{ $('Get user profile').item.json.business_discovery.biography }}"
            },
            {
              "fieldId": "field224101",
              "fieldValue": "={{ $json.output.Insights }}"
            },
            {
              "fieldId": "field224126",
              "fieldValue": "={{ $('Get user profile').item.json.business_discovery.followers_count }}"
            },
            {
              "fieldId": "field224127",
              "fieldValue": "={{ $('Get user profile').item.json.business_discovery.follows_count }}"
            },
            {
              "fieldId": "field224128",
              "fieldValue": "={{ $('Get user profile').item.json.business_discovery.media_count }}"
            },
            {
              "fieldId": "field224129",
              "fieldValue": "={{ $('Look for entry in matching table').item.json['Instagram ID comment payload'] }}"
            }
          ]
        },
        "listId": "358895",
        "resource": "subscriber",
        "operation": "subscribe"
      },
      "notesInFlow": true,
      "typeVersion": 3
    },
    {
      "id": "55aff71d-7014-40c9-a61a-ab47a295af95",
      "name": "Subscribe contact with username",
      "type": "n8n-nodes-klicktipp.klicktipp",
      "notes": "This node subscribes the instagram user to KlickTipp with the enriched data.",
      "position": [
        1168,
        288
      ],
      "parameters": {
        "email": "={{ $('Listen to submission from Instagram DM').item.json.Email }}",
        "tagId": "13659866",
        "fields": {
          "dataFields": [
            {
              "fieldId": "fieldFirstName",
              "fieldValue": "={{ $('Listen to submission from Instagram DM').item.json.Name.first }}"
            },
            {
              "fieldId": "fieldLastName",
              "fieldValue": "={{ $('Listen to submission from Instagram DM').item.json.Name.last }}"
            },
            {
              "fieldId": "field224100",
              "fieldValue": "={{ $('Listen to submission from Instagram DM').item.json.instagram_username }}"
            },
            {
              "fieldId": "field224129",
              "fieldValue": "={{ $('Look for entry in matching table').item.json['Instagram ID comment payload'] }}"
            }
          ]
        },
        "listId": "358895",
        "resource": "subscriber",
        "operation": "subscribe"
      },
      "notesInFlow": true,
      "typeVersion": 3
    },
    {
      "id": "8f84e109-b2a9-4433-97a1-0e1b31f3a24c",
      "name": "Get user profile",
      "type": "n8n-nodes-base.facebookGraphApi",
      "notes": "This node gets the instagram profile using the username from the form submission.",
      "onError": "continueRegularOutput",
      "position": [
        304,
        -32
      ],
      "parameters": {
        "node": "17841465090245583",
        "options": {
          "fields": {
            "field": [
              {
                "name": "=business_discovery.username({{ $json.instagram_username }}){id,username,name,biography,followers_count,follows_count,media_count,profile_picture_url}"
              }
            ]
          }
        },
        "graphApiVersion": "v23.0"
      },
      "notesInFlow": true,
      "typeVersion": 1
    },
    {
      "id": "d2c7ce02-2bd6-4dc9-8a4a-949ad75d26fe",
      "name": "Look for entry in matching table",
      "type": "n8n-nodes-base.googleSheets",
      "notes": "This node checks if there is an entry in the matching table for this username.",
      "position": [
        80,
        -32
      ],
      "parameters": {
        "options": {},
        "filtersUI": {
          "values": [
            {
              "lookupValue": "={{ $json.instagram_username }}",
              "lookupColumn": "Instagram username"
            }
          ]
        },
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1Ou94mTx0gHHdHKr6UQ3Kf01VyIKCNXdlUMhKykTD1Cs/edit#gid=0",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "url",
          "value": "https://docs.google.com/spreadsheets/d/1Ou94mTx0gHHdHKr6UQ3Kf01VyIKCNXdlUMhKykTD1Cs/edit?gid=0#gid=0"
        }
      },
      "notesInFlow": true,
      "typeVersion": 4.7
    },
    {
      "id": "8afaf202-2345-4c31-a3dc-d729831fd17b",
      "name": "KlickTipp Trigger",
      "type": "n8n-nodes-klicktipp.klicktippTrigger",
      "position": [
        384,
        1120
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "3eece678-ae5f-4bd2-badb-44e5b6d3e367",
      "name": "Send personalized DM to user",
      "type": "n8n-nodes-base.httpRequest",
      "notes": "This node sends out a DM to a user in Instagram in order to prompt a form submission.",
      "position": [
        864,
        1120
      ],
      "parameters": {
        "url": "https://graph.instagram.com/v21.0/me/messages",
        "method": "POST",
        "options": {},
        "sendBody": true,
        "authentication": "genericCredentialType",
        "bodyParameters": {
          "parameters": [
            {
              "name": "message",
              "value": "={\"text\":\"Hallo {{ $json.CustomFieldFirstName }} 👋*. Das ist eine persönliche Nachricht.\"}"
            },
            {
              "name": "recipient",
              "value": "={\"id\":\"2213136375820874\"}"
            }
          ]
        },
        "genericAuthType": "httpHeaderAuth"
      },
      "notesInFlow": true,
      "typeVersion": 4.2
    },
    {
      "id": "32b77aa6-8537-4846-8fa1-09d2aedcff66",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        224,
        944
      ],
      "parameters": {
        "color": 7,
        "width": 464,
        "height": 384,
        "content": "## 1. Data reception\n"
      },
      "typeVersion": 1
    },
    {
      "id": "ec847335-fe6b-4188-a41c-c03ef7c10b74",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        704,
        944
      ],
      "parameters": {
        "color": 7,
        "width": 448,
        "height": 384,
        "content": "## 2. Sending message"
      },
      "typeVersion": 1
    },
    {
      "id": "9d1c5086-53c7-4435-8c2c-e3618181bb26",
      "name": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -384,
        -608
      ],
      "parameters": {
        "width": 624,
        "height": 448,
        "content": "## 1. Data Reception\n[Read more about the JotForm Trigger Node](https://docs.n8n.io/integrations/builtin/trigger-nodes/n8n-nodes-base.jotformtrigger/)\n\nThis step listens for **new JotForm submissions** that were sent to users via **Instagram DMs**.  \nEvery time a user completes the form, their information (name, email, and Instagram username) enters the workflow.\n\n### What happens here\n- The **JotForm Trigger** node captures submission data in real time.  \n- The **Google Sheets lookup** then checks if this username exists in your matching table to find the related **Instagram Comment ID**.\n\n### Why this matters\nThis connection ensures that every Instagram user who interacted with your post is properly matched to their JotForm response, so you can later enrich and tag their profile automatically.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "0e9a6018-8ec2-49bf-ad9f-f5e7faa8c653",
      "name": "Sticky Note7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        256,
        -608
      ],
      "parameters": {
        "width": 816,
        "height": 448,
        "content": "## 2. Data Enrichment\n[Read about the Facebook Graph API Node](https://docs.n8n.io/integrations/builtin/app-nodes/n8n-nodes-base.facebookgraphapi)\n[Read about the OpenAI Chat Node](https://docs.n8n.io/integrations/builtin/cluster-nodes/sub-nodes/n8n-nodes-langchain.lmchatopenai/)\n\nThis is where the **magic happens** — the workflow enriches the Instagram user’s profile with insights for smarter segmentation.\n\n### What happens here\n1. The **Facebook Graph API** fetches the user’s public profile data (bio, followers, follows, media count).  \n2. The **AI Agent** analyzes this data and generates **actionable marketing insights** (interests, tone, motivators, segment ideas).  \n3. The **Structured Output Parser** ensures the AI’s text is formatted cleanly into JSON for later mapping.\n\n### Why this matters\nInstead of just saving usernames, this step transforms raw Instagram data into **ready-to-use persona intelligence**.  \nThese insights can directly inform personalized email campaigns, tagging, or custom lead scoring.\n\n💡 *Pro Tip:* Adjust the AI prompt to focus on the attributes most valuable to your audience — such as purchase intent, content style, or collaboration potential.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "6a0e566f-477b-4ca8-bb1c-61fad66be52b",
      "name": "Sticky Note8",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1088,
        -608
      ],
      "parameters": {
        "width": 624,
        "height": 448,
        "content": "## 3. Saving Data\n[Learn more about the KlickTipp Node](https://n8n.io/integrations/klicktipp/)\n\nThis stage syncs the enriched lead profile back into your **KlickTipp CRM**.\n\n### What happens here\n- If a valid **business_discovery** object exists → the lead is subscribed with **AI-enriched insights**, profile metrics, and relevant tags.  \n- Otherwise → the lead is still subscribed with basic information (name, email, username) for future enrichment.\n\n### Why this matters\nThis ensures every captured lead is stored in KlickTipp, automatically tagged and enriched for segmentation — without any manual data entry.\n\n💡 *Pro Tip:*  \nAdd KlickTipp fields like “Instagram Followers” and “AI Persona Insights” to power dynamic segments and personalized automation.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "39b134d9-2043-4c6d-889f-a92556c02b95",
      "name": "Sticky Note9",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        304,
        576
      ],
      "parameters": {
        "width": 752,
        "height": 352,
        "content": "## 1. DM Message Flow\nThis section starts the **Instagram → JotForm** connection.  \nIt listens for specific KlickTipp tags or campaigns, then sends a **personalized DM** prompting users to fill out a form.\n\n### What happens\n- The **KlickTipp Trigger** detects when a tag or campaign action occurs.  \n- The **HTTP Request** node sends a custom message via the **Instagram Graph API**.  \n- The message invites the user to fill in a linked JotForm, initiating the enrichment loop.\n\n💬 Example:\n> “Hey {{FirstName}} 👋 We’ve got something special for analog photographers like you! Click the link to claim your guide.”\n\nThis flow keeps the funnel automated from the very first DM touchpoint.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "317a58da-2510-4816-8302-bb0462a0a17b",
      "name": "Sticky Note10",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        272,
        320
      ],
      "parameters": {
        "color": 3,
        "content": "⚠️ **API Permissions Reminder**\nEnsure your Meta app has these permissions:\n- `instagram_basic`\n- `pages_show_list`\n- `business_management`\n\nWithout them, the Instagram Graph API will not return `business_discovery` fields.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "839e89b9-a1da-4c57-887d-72ac59474d16",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1552,
        -240
      ],
      "parameters": {
        "color": 7,
        "width": 1072,
        "height": 1296,
        "content": "## **Community Node Disclaimer**\nThis workflow uses **KlickTipp community nodes**, available for **self-hosted n8n instances only**.\n\n---\n\n## **Who’s it for**\nDigital marketers, social media managers, and coaches who engage leads through **Instagram DMs** and want to **automate personalized outreach, lead enrichment, and segmentation** in KlickTipp — without manual follow-ups or data entry.\n\n---\n\n## **How it works**\nThis workflow creates a **complete Instagram-to-email enrichment loop** — starting with personalized **DM outreach**, capturing responses via **JotForm**, enriching profile data, and syncing everything with **KlickTipp**.\n\nWhen a workflow trigger or campaign action occurs, it:\n1. Sends a **personalized Instagram DM** inviting the user to fill out a JotForm.  \n2. Listens for **form submissions** in real time.  \n3. Retrieves the lead’s **Instagram profile data** via the **Facebook Graph API**.  \n4. Matches the username to the **Instagram DM ID** in a **Google Sheet**.  \n5. Generates **AI-powered marketing insights** using **OpenAI**.  \n6. Subscribes or updates the lead in **KlickTipp**, mapping enriched fields and tags.  \n\nThe result: every DM-initiated lead is captured, analyzed, and segmented — ready for intelligent follow-ups and personalized campaigns.\n\n---\n\n## **How to set up**\n1. Connect accounts for KlickTipp, JotForm, Google Sheets, Facebook Graph API, and OpenAI.  \n2. Set up a KlickTipp tag or campaign trigger to initiate the **DM sending**.  \n3. Create KlickTipp fields for Instagram data (e.g., Bio, Follower count, Insights).  \n4. Add tags: `Instagram | Outreach`, `Instagram | Enrichment`, `Instagram | Username found`.  \n5. Test a sample flow: send a DM → fill the JotForm → verify data enrichment in KlickTipp.  \n\n💡 *Pro Tip:* Personalize the DM message template and test both personal and business accounts to ensure optimal engagement and AI insight quality.\n\n---\n\n## **Requirements**\n- Meta (Instagram) Business Account  \n- Facebook Graph API with `instagram_basic` and `pages_show_list` permissions  \n- KlickTipp account with API access  \n- OpenAI connection (`gpt-4.1-mini` model)  \n- (Optional) Active Instagram Page connected to your Facebook App for DM messaging  \n\n---\n\n## **How to customize**\n- Adjust DM content and message timing for different campaigns or audiences.  \n- Edit tags and field mappings in KlickTipp to match your segmentation logic.  \n- Modify the AI prompt to emphasize tone, purchase intent, or niche interests.  \n- Add conditional logic (e.g., `followers > 1,000 → influencer tag`).  \n- Extend the flow to LinkedIn, website tracking, or CRM syncing for multi-channel enrichment."
      },
      "typeVersion": 1
    }
  ],
  "connections": {
    "Get user profile": {
      "main": [
        [
          {
            "node": "Profile type check",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Generate Insights": {
      "main": [
        [
          {
            "node": "Subscribe contact with user insights",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "KlickTipp Trigger": {
      "main": [
        [
          {
            "node": "Send personalized DM to user",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "Generate Insights",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Profile type check": {
      "main": [
        [
          {
            "node": "Generate Insights",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Subscribe contact with username",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Structured Output Parser": {
      "ai_outputParser": [
        [
          {
            "node": "Generate Insights",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    },
    "Look for entry in matching table": {
      "main": [
        [
          {
            "node": "Get user profile",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Listen to submission from Instagram DM": {
      "main": [
        [
          {
            "node": "Look for entry in matching table",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {},
  "active": false
}
