{
  "id": "cA7JWlaKTrTlynWO",
  "meta": {
    "instanceId": "a1ae5c8dc6c65e674f9c3947d083abcc749ef2546dff9f4ff01de4d6a36ebfe6",
    "templateCredsSetupCompleted": true
  },
  "name": "Telegram AI Bot: Extract TikTok and LinkedIn Data with Dumpling AI",
  "tags": [],
  "nodes": [
    {
      "id": "bf2e23ff-22f1-4329-9911-d38e2724f4f8",
      "name": "OpenAI Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        400,
        192
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4.1-mini"
        },
        "options": {}
      },
      "credentials": {
        "openAiApi": {
          "id": "credential-id",
          "name": "openAiApi Credential"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "ba7f8f39-6f52-4b8d-bae0-e63071bd03ec",
      "name": "tiktok_profile_scraper",
      "type": "n8n-nodes-base.httpRequestTool",
      "position": [
        528,
        192
      ],
      "parameters": {
        "url": "https://app.dumplingai.com/api/v1/get-tiktok-profile",
        "method": "POST",
        "options": {},
        "sendBody": true,
        "authentication": "genericCredentialType",
        "bodyParameters": {
          "parameters": [
            {
              "name": "handle",
              "value": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('parameters0_Value', ``, 'string') }}"
            }
          ]
        },
        "genericAuthType": "httpHeaderAuth",
        "toolDescription": "Scrapes a TikTok profile to retrieve public metrics and user details."
      },
      "credentials": {
        "httpHeaderAuth": {
          "id": "credential-id",
          "name": "httpHeaderAuth Credential"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "0063c43e-d4e8-43cc-a0aa-f3f3da119f74",
      "name": "tiktok_database_saver",
      "type": "n8n-nodes-base.googleSheetsTool",
      "position": [
        656,
        192
      ],
      "parameters": {
        "columns": {
          "value": {
            "secUid": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('secUid', ``, 'string') }}",
            "bioLink": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('bioLink', ``, 'string') }}",
            "Username": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Username', ``, 'string') }}",
            "verified": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('verified', ``, 'string') }}",
            "heartCount": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('heartCount', ``, 'string') }}",
            "videoCount": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('videoCount', ``, 'string') }}",
            "friendCount": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('friendCount', ``, 'string') }}",
            "followerCount": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('followerCount', ``, 'string') }}",
            "followingCount": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('followingCount', ``, 'string') }}"
          },
          "schema": [
            {
              "id": "Username",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Username",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "verified",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "verified",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "secUid",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "secUid",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "bioLink",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "bioLink",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "followerCount",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "followerCount",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "followingCount",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "followingCount",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "heartCount",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "heartCount",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "videoCount",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "videoCount",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "friendCount",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "friendCount",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1QCyOUa2GzqfxS2SwJIX3MfgWqOt2776lylgVioemsNs/edit#gid=0",
          "cachedResultName": "TikTok"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1QCyOUa2GzqfxS2SwJIX3MfgWqOt2776lylgVioemsNs/edit?usp=drivesdk",
          "cachedResultName": "Content Library"
        },
        "descriptionType": "manual",
        "toolDescription": "Saves extracted TikTok data into the Google Sheet."
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "id": "credential-id",
          "name": "googleSheetsOAuth2Api Credential"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "c8c2e6f8-4837-47eb-99ab-eca7d7520185",
      "name": "linkedin_profile_scraper",
      "type": "n8n-nodes-base.httpRequestTool",
      "position": [
        784,
        192
      ],
      "parameters": {
        "url": "https://app.dumplingai.com/api/v1/linkedin/profile",
        "method": "POST",
        "options": {},
        "sendBody": true,
        "authentication": "genericCredentialType",
        "bodyParameters": {
          "parameters": [
            {
              "name": "url",
              "value": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('parameters0_Value', ``, 'string') }}"
            }
          ]
        },
        "genericAuthType": "httpHeaderAuth",
        "toolDescription": "Scrapes a LinkedIn profile to retrieve professional details."
      },
      "credentials": {
        "httpHeaderAuth": {
          "id": "credential-id",
          "name": "httpHeaderAuth Credential"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "d9bd7e1f-e9b8-405a-a8bf-8b08605a9e03",
      "name": "linkedin_database_saver",
      "type": "n8n-nodes-base.googleSheetsTool",
      "position": [
        912,
        192
      ],
      "parameters": {
        "columns": {
          "value": {
            "name": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('name', ``, 'string') }}",
            "about": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('about', ``, 'string') }}",
            "image": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('image', ``, 'string') }}",
            "location": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('location', ``, 'string') }}",
            "followers": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('followers', ``, 'string') }}",
            "recentPosts link": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('recentPosts_link', ``, 'string') }}"
          },
          "schema": [
            {
              "id": "name",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "image",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "image",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "location",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "location",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "followers",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "followers",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "about",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "about",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "recentPosts link",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "recentPosts link",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": 1956409676,
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1QCyOUa2GzqfxS2SwJIX3MfgWqOt2776lylgVioemsNs/edit#gid=1956409676",
          "cachedResultName": "Linkedin"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1QCyOUa2GzqfxS2SwJIX3MfgWqOt2776lylgVioemsNs/edit?usp=drivesdk",
          "cachedResultName": "Content Library"
        },
        "descriptionType": "manual",
        "toolDescription": "Saves extracted LinkedIn data into the Google Sheet."
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "id": "credential-id",
          "name": "googleSheetsOAuth2Api Credential"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "3cc2bb52-55ba-4c86-bb00-083a321fa3f8",
      "name": "Receive Telegram Message",
      "type": "n8n-nodes-base.telegramTrigger",
      "position": [
        -720,
        -32
      ],
      "webhookId": "5e72112e-15da-4d37-919b-fbf6900a0d5b",
      "parameters": {
        "updates": [
          "message"
        ],
        "additionalFields": {
          "download": true
        }
      },
      "credentials": {
        "telegramApi": {
          "id": "credential-id",
          "name": "telegramApi Credential"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "3b8636d6-5473-4a31-8963-b9c25ae45131",
      "name": "Check for Voice Message",
      "type": "n8n-nodes-base.if",
      "position": [
        -496,
        -32
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "a32a6a89-05c5-468e-af62-10d6229e84d0",
              "operator": {
                "type": "object",
                "operation": "exists",
                "singleValue": true
              },
              "leftValue": "={{ $json.message.voice }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "8f3e957f-a0fd-4a84-9dbe-97523596f9cc",
      "name": "Fetch Voice File from Telegram",
      "type": "n8n-nodes-base.telegram",
      "position": [
        -272,
        -128
      ],
      "webhookId": "8ad24c26-6620-4990-b6fb-853315f8112b",
      "parameters": {
        "fileId": "={{ $json.message.voice.file_id }}",
        "resource": "file",
        "additionalFields": {}
      },
      "credentials": {
        "telegramApi": {
          "id": "credential-id",
          "name": "telegramApi Credential"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "4c5feeb1-84f3-4a9a-955a-bc91b2304fcf",
      "name": "Transcribe Audio with Whisper",
      "type": "@n8n/n8n-nodes-langchain.openAi",
      "position": [
        -48,
        -128
      ],
      "parameters": {
        "options": {},
        "resource": "audio",
        "operation": "transcribe"
      },
      "credentials": {
        "openAiApi": {
          "id": "credential-id",
          "name": "openAiApi Credential"
        }
      },
      "typeVersion": 1.8
    },
    {
      "id": "7fd25573-e8e0-4202-a52f-690bbe283035",
      "name": "Format Transcription",
      "type": "n8n-nodes-base.set",
      "position": [
        176,
        -128
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "00b6d8f5-3303-4cbc-8ed7-c3f96ff5fbe3",
              "name": "Text",
              "type": "string",
              "value": "={{ $json.text }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "0479485a-d08e-4318-9981-c84749f08aed",
      "name": "Format Text Message",
      "type": "n8n-nodes-base.set",
      "position": [
        176,
        64
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "9432a30e-67a3-4073-81a9-d5f96a1572bd",
              "name": "Text",
              "type": "string",
              "value": "={{ $json.message.text }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "c2061e4b-f957-4ae0-9062-db845f7ededc",
      "name": "Social Media Extraction Agent",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        576,
        -32
      ],
      "parameters": {
        "text": "=User message: {{ $json.Text }}",
        "options": {
          "systemMessage": "You are the \"Social Data Miner,\" a specialized AI agent responsible for extracting profile data from social media platforms and archiving it into a database (Google Sheets).\n\n### YOUR TOOLKIT\nYou have two sets of tools. You must always use them in pairs: one to **GET** the data, and one to **SAVE** the data.\n\n**Set A: TikTok Operations**\n1. `tiktok_profile_scraper`: gets the data.\n2. `tiktok_database_saver`: saves the data.\n\n**Set B: LinkedIn Operations**\n1. `linkedin_profile_scraper`: gets the data.\n2. `linkedin_database_saver`: saves the data.\n\n### OPERATION PROTOCOLS\n\n**PROTOCOL 1: TikTok Extraction**\nIf the user provides a TikTok username or link:\n1.  **Scrape:** Call `tiktok_profile_scraper` with the username.\n2.  **Process:** Wait for the JSON result.\n3.  **Save:** Immediately call `tiktok_database_saver` mapping the scraper's output to these exact fields:\n    - `Username`\n    - `verified`\n    - `secUid`\n    - `bioLink`\n    - `followerCount`\n    - `followingCount`\n    - `heartCount`\n    - `videoCount`\n    - `friendCount`\n4.  **Report:** Confirm to the user: \"TikTok profile for [Username] scraped and saved to database.\"\n\n**PROTOCOL 2: LinkedIn Extraction**\nIf the user provides a LinkedIn profile URL:\n1.  **Scrape:** Call `linkedin_profile_scraper` with the URL.\n2.  **Process:** Wait for the JSON result.\n3.  **Save:** Immediately call `linkedin_database_saver` mapping the scraper's output to these exact fields:\n    - `name`\n    - `image` (Profile picture URL)\n    - `location`\n    - `followers`\n    - `about` (Bio/Summary)\n    - `recentPosts` (Link to recent activity)\n4.  **Report:** Confirm to the user: \"LinkedIn profile for [Name] scraped and saved to database.\"\n\n### ERROR HANDLING\n- If a scraper returns \"Null\" or fails to find the profile, do **not** call the database saver. Instead, inform the user: \"I could not retrieve data for that profile. Please check the link/username.\"\n- Do not make up data. Only save what the scraper returns.\n\nBegin by identifying which platform the user wants to scrape."
        },
        "promptType": "define"
      },
      "typeVersion": 2.2
    },
    {
      "id": "94f08ef8-13fa-4c43-8c60-0c6067980b42",
      "name": "Send Completion Email",
      "type": "n8n-nodes-base.gmail",
      "position": [
        1120,
        -32
      ],
      "webhookId": "d6f5bb11-6891-4500-b1c4-e67984d08ba0",
      "parameters": {
        "sendTo": "user@example.com",
        "message": "Extraction complete. I have scraped the profile and successfully saved all data points to your spreadsheet",
        "options": {
          "appendAttribution": false
        },
        "subject": "Extraction complete",
        "emailType": "text"
      },
      "credentials": {
        "gmailOAuth2": {
          "id": "credential-id",
          "name": "gmailOAuth2 Credential"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "baec690b-5e6d-460e-9cbe-4dfabeee33b8",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1408,
        -464
      ],
      "parameters": {
        "width": 896,
        "height": 928,
        "content": "📊 Social Media Profile Scraper with Dumpling AI\n\nAutomatically extract public profile data from TikTok and LinkedIn via Telegram, powered by AI routing and Dumpling AI scraping.\n\nCAPABILITIES:\n✅ Scrape TikTok profiles (metrics, bio, verification)\n✅ Extract LinkedIn profiles (name, location, followers, bio)\n✅ Support text AND voice input via Telegram\n✅ Auto-save to organized Google Sheets\n✅ Email notifications on completion\n\nHOW TO USE:\n📱 Send to your Telegram bot:\n- \"Scrape @tiktokusername\"\n- \"Get LinkedIn data: [profile URL]\"\n- 🎤 Voice messages also work!\n\nThe AI automatically:\n1. Identifies which platform\n2. Calls the right scraper\n3. Saves data to correct sheet tab\n4. Emails you confirmation\n\nSETUP CHECKLIST:\n□ Create Telegram bot via @BotFather\n□ Add OpenAI API key (Whisper + GPT-4.1)\n□ Add Dumpling AI credentials\n□ Create Google Sheets with 2 tabs: TikTok & LinkedIn\n□ Update sheet ID in both database saver nodes\n□ Connect Gmail for notifications\n□ Update notification email address\n□ Remove personal identifiers (credential names, sheet IDs)\n\nGOOGLE SHEETS REQUIRED COLUMNS:\n\nTikTok Tab:\n- Username, verified, secUid, bioLink\n- followerCount, followingCount, heartCount\n- videoCount, friendCount\n\nLinkedIn Tab:\n- name, image, location, followers\n- about, recentPosts link\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "c3b40d43-23b8-4e8e-98be-93a20d6758ea",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -464,
        -512
      ],
      "parameters": {
        "color": 4,
        "width": 800,
        "height": 768,
        "content": "📥 INPUT HANDLING\n\nReceives messages via Telegram and processes both formats:\n\nVoice Messages:\n1. Fetch Voice File from Telegram\n2. Transcribe Audio with Whisper (OpenAI)\n3. Format Transcription\n\nText Messages:\n1. Format Text Message directly\n\nBoth paths merge into the Social Media Extraction Agent for intelligent processing.\n\nSupports natural language like:\n- \"Get TikTok stats for @username\"\n- \"Extract this LinkedIn profile: [URL]\"\n- \"Scrape charlidamelio on TikTok\""
      },
      "typeVersion": 1
    },
    {
      "id": "f9387d8a-49a2-4aa9-8ef1-97f538afa8c2",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        352,
        -336
      ],
      "parameters": {
        "color": 3,
        "width": 736,
        "height": 656,
        "content": "📱 TIKTOK EXTRACTION PIPELINE\n\n1. Scrape TikTok Profile (Dumpling AI)\n   - Input: TikTok username/handle\n   - API: Dumpling AI's TikTok scraper\n   - Output: Complete profile JSON\n\n2. Save TikTok Data to Sheets\n   - Maps 9 data points to columns\n   - Appends to \"TikTok\" tab\n   - Fields: Username, verified, secUid, bioLink, followerCount, followingCount, heartCount, videoCount, friendCount\n\nExample Input: \"@charlidamelio\" or \"charlidamelio\""
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "pinData": {},
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "2c93dd79-4417-4f24-a674-dd819dedcb87",
  "connections": {
    "OpenAI Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "Social Media Extraction Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Format Text Message": {
      "main": [
        [
          {
            "node": "Social Media Extraction Agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Format Transcription": {
      "main": [
        [
          {
            "node": "Social Media Extraction Agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "tiktok_database_saver": {
      "ai_tool": [
        [
          {
            "node": "Social Media Extraction Agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "tiktok_profile_scraper": {
      "ai_tool": [
        [
          {
            "node": "Social Media Extraction Agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Check for Voice Message": {
      "main": [
        [
          {
            "node": "Fetch Voice File from Telegram",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Format Text Message",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "linkedin_database_saver": {
      "ai_tool": [
        [
          {
            "node": "Social Media Extraction Agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Receive Telegram Message": {
      "main": [
        [
          {
            "node": "Check for Voice Message",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "linkedin_profile_scraper": {
      "ai_tool": [
        [
          {
            "node": "Social Media Extraction Agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Social Media Extraction Agent": {
      "main": [
        [
          {
            "node": "Send Completion Email",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Transcribe Audio with Whisper": {
      "main": [
        [
          {
            "node": "Format Transcription",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Voice File from Telegram": {
      "main": [
        [
          {
            "node": "Transcribe Audio with Whisper",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}