{
  "nodes": [
    {
      "id": "2490f7b5-3a4b-413a-9b94-3e6d2131ee3f",
      "name": "\ud83d\udccb Workflow Overview",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1424,
        192
      ],
      "parameters": {
        "width": 600,
        "height": 772,
        "content": "@[youtube](GZ4OrOt3HSY)\n\n# \ud83d\udd17 LinkedIn Group Members to Google Sheets\n## Premium & Verified Members Only\n\n**Purpose:** Automatically extract LinkedIn group members and filter for Premium/Verified profiles, then save to Google Sheets.\n\n**Features:**\n- \u2705 Pagination support for large groups\n- \u2705 Filters for Premium & Verified members only\n- \u2705 Auto-appends to Google Sheets\n- \u2705 Tracks follower count, headline, profile URL\n\n**Author:** ConnectSafely.ai\n**API Endpoint:** `api.connectsafely.ai/linkedin/groups/members`"
      },
      "typeVersion": 1
    },
    {
      "id": "69e3a09c-ac22-4d33-af77-a55a49f5d3fc",
      "name": "\u2699\ufe0f Configuration",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -672,
        816
      ],
      "parameters": {
        "color": 4,
        "width": 600,
        "height": 280,
        "content": "## \u2699\ufe0f Configuration Required\n\n### 1. API Credentials\n- Set up **HTTP Bearer YOUR_TOKEN_HERE** credential for ConnectSafely.ai API\n- Name: `ConnectSafelyAI Token`\n\n### 2. Google Sheets\n- Connect your **Google Sheets OAuth2** account\n- Create/select your target spreadsheet\n- Ensure columns match: Profile ID, First Name, Last Name, etc.\n\n### 3. Group ID\n- Update `groupId` in **Initialize Pagination** node\n- Default: `9357376` (Product Hunt Promotion Group)"
      },
      "typeVersion": 1
    },
    {
      "id": "da23d6c6-d824-4100-9765-aa0b90d9662e",
      "name": "\ud83c\udf10 API Details",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -512,
        192
      ],
      "parameters": {
        "color": 5,
        "width": 400,
        "height": 260,
        "content": "## \ud83c\udf10 ConnectSafely.ai API\n\n**Endpoint:** POST `/linkedin/groups/members`\n\n**Request Body:**\n```json\n{\n  \"groupId\": \"9357376\",\n  \"count\": 50,\n  \"start\": 0\n}\n```\n\n**Response includes:**\n- `members[]` - Array of member objects\n- `hasMore` - Boolean for pagination"
      },
      "typeVersion": 1
    },
    {
      "id": "59781647-de59-4257-b65e-985758ae5bf6",
      "name": "\ud83d\udd0d Filter Logic",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        0,
        0
      ],
      "parameters": {
        "color": 6,
        "width": 400,
        "height": 324,
        "content": "## \ud83d\udd0d Member Filtering\n\n**Premium/Verified Detection:**\n- `isPremium === true`\n- `isVerified === true`\n- `badges` includes 'premium'\n- `badges` includes 'verified'\n\n**Extracted Fields:**\n- Profile ID, Name, Headline\n- Public Identifier, Profile URL\n- Follower Count, Badges\n- Relationship Status, Creator flag"
      },
      "typeVersion": 1
    },
    {
      "id": "355516e4-e434-4b63-88b0-7b5f05a582b4",
      "name": "\ud83d\udcc4 Pagination Flow",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        288,
        800
      ],
      "parameters": {
        "color": 6,
        "width": 304,
        "height": 248,
        "content": "## \ud83d\udcc4 Pagination Logic\n\n1. Start with `start: 0`\n2. Fetch 50 members per request\n3. If `hasMore === true`:\n   - Loop back to HTTP Request\n   - Increment `start` by 50\n4. If `hasMore === false`:\n   - Proceed to Google Sheets"
      },
      "typeVersion": 1
    },
    {
      "id": "0e9e28ce-6a7d-4fb6-9e5f-1f2fb6c1d356",
      "name": "\ud83d\udcca Google Sheets",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        464,
        48
      ],
      "parameters": {
        "width": 380,
        "height": 280,
        "content": "## \ud83d\udcca Google Sheets Output\n\n**Columns:**\n| Column | Description |\n|--------|-------------|\n| Profile ID | Unique LinkedIn ID |\n| First Name | Member first name |\n| Last Name | Member last name |\n| Headline | Professional headline |\n| Profile URL | Direct profile link |\n| Follower Count | Number of followers |\n| Is Premium | Premium status |\n| Is Verified | Verification status |"
      },
      "typeVersion": 1
    },
    {
      "id": "9507a1f1-9e36-4801-b65d-1ee22a37dc39",
      "name": "Start Workflow",
      "type": "n8n-nodes-base.manualTrigger",
      "position": [
        -752,
        496
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "71060dc7-36c4-43c8-bbf3-b5aacebd5bb5",
      "name": "Initialize Pagination",
      "type": "n8n-nodes-base.code",
      "position": [
        -528,
        496
      ],
      "parameters": {
        "jsCode": "// Initialize pagination variables\n// Change groupId to target different LinkedIn groups\nreturn [\n  {\n    json: {\n      groupId: \"9357376\",  // Product Hunt Promotion Group\n      count: 50,           // Members per request (max 50)\n      start: 0,            // Starting offset\n      hasMore: true,       // Continue flag\n      allMembers: []       // Accumulated results\n    }\n  }\n];"
      },
      "typeVersion": 2
    },
    {
      "id": "9b64821f-85a7-4c4e-a81a-66e06324c515",
      "name": "Fetch Group Members",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -304,
        496
      ],
      "parameters": {},
      "credentials": {},
      "typeVersion": 4.3
    },
    {
      "id": "d67e262a-7ab6-4741-b733-697d6d12ea74",
      "name": "Process & Filter Members",
      "type": "n8n-nodes-base.code",
      "position": [
        -80,
        416
      ],
      "parameters": {
        "jsCode": "// Get current pagination state from the previous Code node's output\nconst items = $input.all();\nconst firstItem = items[0].json;\n\n// Access the API response data (merged with pagination state)\nconst response = firstItem;\nconst members = response.members || [];\nconst hasMore = response.hasMore || false;\n\n// Get pagination info from workflow context\nconst currentStart = $('Initialize Pagination').first().json.start || 0;\nconst currentCount = $('Initialize Pagination').first().json.count || 50;\nconst groupId = $('Initialize Pagination').first().json.groupId;\nconst previousMembers = $('Initialize Pagination').first().json.allMembers || [];\n\n// Filter for premium or verified members\nconst filteredMembers = members.filter(member => {\n  const isPremium = member.isPremium === true;\n  const isVerified = member.isVerified === true;\n  const hasPremiumBadge = member.badges && member.badges.includes('premium');\n  const hasVerifiedBadge = member.badges && member.badges.includes('verified');\n  \n  return isPremium || isVerified || hasPremiumBadge || hasVerifiedBadge;\n});\n\n// Extract relevant fields from filtered members\nconst processedMembers = filteredMembers.map(member => ({\n  profileId: member.profileId,\n  firstName: member.firstName,\n  lastName: member.lastName,\n  fullName: member.fullName,\n  headline: member.headline,\n  publicIdentifier: member.publicIdentifier,\n  profileUrl: member.profileUrl,\n  followerCount: member.followerCount,\n  isPremium: member.isPremium,\n  isVerified: member.isVerified,\n  badges: member.badges ? member.badges.join(', ') : '',\n  relationshipStatus: member.relationshipStatus,\n  creator: member.creator,\n  fetchedAt: new Date().toISOString()\n}));\n\n// Combine with previous members\nconst allMembers = [...previousMembers, ...processedMembers];\n\n// Prepare next iteration or final output\nif (hasMore) {\n  return [{\n    json: {\n      groupId: groupId,\n      count: currentCount,\n      start: currentStart + currentCount,\n      hasMore: true,\n      allMembers: allMembers,\n      continueLoop: true,\n      currentBatch: processedMembers\n    }\n  }];\n} else {\n  return [{\n    json: {\n      groupId: groupId,\n      hasMore: false,\n      allMembers: allMembers,\n      continueLoop: false,\n      totalFiltered: allMembers.length,\n      totalFetched: currentStart + members.length\n    }\n  }];\n}"
      },
      "typeVersion": 2
    },
    {
      "id": "1cae57d9-650f-4a30-9b46-e813b9056661",
      "name": "Continue Pagination",
      "type": "n8n-nodes-base.code",
      "position": [
        368,
        592
      ],
      "parameters": {
        "jsCode": "// Loop back with updated pagination state\nconst item = $input.first().json;\n\nreturn [{\n  json: {\n    groupId: item.groupId,\n    count: item.count,\n    start: item.start,\n    hasMore: item.hasMore,\n    allMembers: item.allMembers\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "138b1558-373c-4e92-a0e9-515faa956417",
      "name": "Prepare for Sheets",
      "type": "n8n-nodes-base.code",
      "position": [
        368,
        368
      ],
      "parameters": {
        "jsCode": "// Split all members into individual items for Google Sheets\nconst allMembers = $input.first().json.allMembers || [];\n\nif (allMembers.length === 0) {\n  return [];\n}\n\n// Return each member as a separate item\nreturn allMembers.map(member => ({ json: member }));"
      },
      "typeVersion": 2
    },
    {
      "id": "40039a53-0a69-421d-ac5f-cfa54527ccee",
      "name": "Append to Google Sheets",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        592,
        368
      ],
      "parameters": {
        "columns": {
          "value": {
            "Headline": "={{ $json.headline }}",
            "Full Name": "={{ $json.fullName }}",
            "Last Name": "={{ $json.lastName }}",
            "First Name": "={{ $json.firstName }}",
            "Is Premium": "={{ $json.isPremium }}",
            "Profile ID": "={{ $json.profileId }}",
            "Is Verified": "={{ $json.isVerified }}",
            "Profile URL": "={{ $json.profileUrl }}",
            "Follower Count": "={{ $json.followerCount }}",
            "Public Identifier": "={{ $json.publicIdentifier }}",
            "Relationship Status": "={{ $json.relationshipStatus }}"
          },
          "schema": [
            {
              "id": "Profile ID",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Profile ID",
              "defaultMatch": true,
              "canBeUsedToMatch": true
            },
            {
              "id": "First Name",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "First Name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Last Name",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Last Name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Full Name",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Full Name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Headline",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Headline",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Public Identifier",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Public Identifier",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Profile URL",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Profile URL",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Follower Count",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Follower Count",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Is Premium",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Is Premium",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Is Verified",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Is Verified",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Relationship Status",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Relationship Status",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "Profile ID"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": true
        },
        "options": {},
        "operation": "appendOrUpdate",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=1409852359",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/11Cs4xOauRZa2usYQ6KNoKCpGtRIIMM_Paywm8Uk8Zes/edit#gid=1409852359",
          "cachedResultName": "Product Hunt Promotion Group - 9357376"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "11Cs4xOauRZa2usYQ6KNoKCpGtRIIMM_Paywm8Uk8Zes",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/11Cs4xOauRZa2usYQ6KNoKCpGtRIIMM_Paywm8Uk8Zes/edit?usp=drivesdk",
          "cachedResultName": "Top AI Influencers"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "64fd109a-bf44-476b-9d74-d63fc01e1851",
      "name": "\u2705 Workflow Complete",
      "type": "n8n-nodes-base.noOp",
      "position": [
        816,
        368
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "cdead25e-f181-46ba-87de-6e6855be9f4b",
      "name": "If",
      "type": "n8n-nodes-base.if",
      "position": [
        112,
        432
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "34346e59-7490-4177-b29f-7c1fe4f5d7be",
              "operator": {
                "type": "boolean",
                "operation": "false",
                "singleValue": true
              },
              "leftValue": "={{ $json.continueLoop }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.2
    }
  ],
  "connections": {
    "If": {
      "main": [
        [
          {
            "node": "Prepare for Sheets",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Continue Pagination",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Start Workflow": {
      "main": [
        [
          {
            "node": "Initialize Pagination",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prepare for Sheets": {
      "main": [
        [
          {
            "node": "Append to Google Sheets",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Append to Google Sheets": {
      "main": [
        [
          {
            "node": "\u2705 Workflow Complete",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Process & Filter Members": {
      "main": [
        [
          {
            "node": "If",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}