AutomationFlowsAI & RAG › Log and Analyze Job Postings with Telegram, Claude, and Google Sheets

Log and Analyze Job Postings with Telegram, Claude, and Google Sheets

ByArminas B @abeka on n8n.io

This workflow logs job postings sent via Telegram into Google Sheets using Anthropic Claude to extract structured fields, and generates an on-demand Telegram report (/report) that analyzes trends across all saved postings. Triggers when a new Telegram message is received by the…

Event trigger★★★★☆ complexityAI-powered16 nodesTelegram TriggerAnthropicGoogle SheetsTelegram
AI & RAG Trigger: Event Nodes: 16 Complexity: ★★★★☆ AI nodes: yes Added:

This workflow corresponds to n8n.io template #15931 — we link there as the canonical source.

This workflow follows the Google Sheets → Telegram recipe pattern — see all workflows that pair these two integrations.

The workflow JSON

Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →

Download .json
{
  "id": "r1WHh7zhA2TDwDlb",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "Personal Job Market Intelligence System",
  "tags": [],
  "nodes": [
    {
      "id": "a16b959a-7eec-470f-a433-bcc5bb690595",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -144,
        -96
      ],
      "parameters": {
        "width": 624,
        "height": 736,
        "content": "## Personal Job Market Intelligence System\n\n  ### How it works\n\n  1. The workflow starts by receiving a message via Telegram.\n  2. It sets configuration variables for further processing.\n  3. It checks if the Telegram user ID is authorized.\n  4. Depending on the message content, it routes to either extract job data or generate a report.\n  5. It updates a Google Sheet with job data and confirms via Telegram or analyzes job patterns and sends a report.\n\n  ### Setup steps\n\n  - [ ] Create a Telegram bot via @BotFather and copy the API token. Add it as a Telegram credential in n8n.\n  - [ ] Set Google Sheets API credentials and permissions (Service Account recommended).\n  - [ ] Set variables in 'Set Config Variables' node: paste your Google Sheet ID and sheet name.\n  - [ ] In your Google Sheet, add these headers in row 1: Date, Company, Role, Seniority, Hard Requirements, Tech\n  Stack, Salary, Location, Domain, Key Signal\n  - [ ] In 'Check Telegram User ID' node, replace the hardcoded ID with your own Telegram user ID.\n\n  ### How to use\n\n  - **Log a job:** While browsing LinkedIn or any job board, copy the full job description and paste it into your\n  Telegram chat with the bot. Claude will extract structured data and log it to your Google Sheet automatically. You\n  will receive a confirmation message.\n  - **Get a report:** Send `/report` to the bot. Claude will analyze all logged jobs and send back a summary of top\n  skills, tech stack trends, salary ranges, seniority distribution, and a key market insight.\n\n  ### Customization\n\nYou can customize which jobs or patterns to focus on by adjusting the AI prompt in the 'Claude Extract Job Info' node or the report format in 'Claude Analyze Job Patterns'"
      },
      "typeVersion": 1
    },
    {
      "id": "a3f94cd2-d4d6-480c-9256-5011a60a4bdf",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        560,
        256
      ],
      "parameters": {
        "color": 7,
        "width": 416,
        "height": 304,
        "content": "## Receive message and configure\n\nReceives Telegram messages and initializes workflow variables."
      },
      "typeVersion": 1
    },
    {
      "id": "a59e6232-7e94-424a-aa84-d6ba2e77e125",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1008,
        256
      ],
      "parameters": {
        "color": 7,
        "width": 416,
        "height": 304,
        "content": "## User authentication and routing\n\nAuthenticates user and routes to appropriate job or report process."
      },
      "typeVersion": 1
    },
    {
      "id": "70298028-9f96-469c-a1b1-92ed91ab0d9c",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1456,
        272
      ],
      "parameters": {
        "color": 7,
        "width": 976,
        "height": 272,
        "content": "## Job data extraction\n\nExtracts job data using AI and logs it in Google Sheets, then confirms."
      },
      "typeVersion": 1
    },
    {
      "id": "c5422e78-3c0c-4a0c-ac28-3929194ac238",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1472,
        -96
      ],
      "parameters": {
        "color": 7,
        "width": 752,
        "height": 272,
        "content": "## Report generation and sending\n\nReads all jobs, generates patterns via AI, and sends report through Telegram."
      },
      "typeVersion": 1
    },
    {
      "id": "54fc3b7b-9ee1-4ec0-bf40-0dc282ef5d87",
      "name": "When Telegram Message Received",
      "type": "n8n-nodes-base.telegramTrigger",
      "position": [
        608,
        384
      ],
      "parameters": {
        "updates": [
          "message"
        ],
        "additionalFields": {}
      },
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "d9738cd5-9db2-4060-9702-18e8530a8f24",
      "name": "Set Config Variables",
      "type": "n8n-nodes-base.set",
      "position": [
        832,
        384
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "3156a863-beb0-4bc8-a88f-f3b1e2840eb3",
              "name": "SHEET_PERSONAL_JOB_MARKET_INTEL_ID",
              "type": "string",
              "value": "<YOUR-VALUE-HERE>"
            },
            {
              "id": "3b1498b8-0714-472d-a7e2-c0ef49f49da0",
              "name": "SHEET_PERSONAL_JOB_MARKET_INTEL_SHEET",
              "type": "string",
              "value": "Sheet1"
            },
            {
              "id": "305e9368-5977-4837-9533-bcd1a84c867f",
              "name": "TELEGRAM_USER_ID",
              "type": "number",
              "value": 1234567890
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "a47af54f-eecf-4d65-b35e-1590d706b8a1",
      "name": "Check Telegram User ID",
      "type": "n8n-nodes-base.if",
      "position": [
        1056,
        384
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "8882b696-1efe-4369-bb45-b93223a6dcda",
              "operator": {
                "type": "number",
                "operation": "equals"
              },
              "leftValue": "={{ $('When Telegram Message Received').item.json.message.chat.id }}",
              "rightValue": "={{ $json.TELEGRAM_USER_ID }}"
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "62c640b2-6daf-4123-8411-07f90b97e711",
      "name": "Route by Message Type",
      "type": "n8n-nodes-base.if",
      "position": [
        1280,
        384
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "a68a6869-2db2-46d9-b48c-90fa78646216",
              "operator": {
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $('When Telegram Message Received').item.json.message.text }}",
              "rightValue": "/report"
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "490a2ecc-3498-4be4-b622-17168157c7f7",
      "name": "Claude Extract Job Info",
      "type": "@n8n/n8n-nodes-langchain.anthropic",
      "position": [
        1504,
        384
      ],
      "parameters": {
        "modelId": {
          "__rl": true,
          "mode": "list",
          "value": "claude-haiku-4-5-20251001",
          "cachedResultName": "claude-haiku-4-5-20251001"
        },
        "options": {},
        "messages": {
          "values": [
            {
              "content": "=  Extract structured data from this job posting and return ONLY valid JSON, no markdown, no code blocks,\n   no explanation.\n\n  Job Posting:\n  {{ $('When Telegram Message Received').item.json.message.text }}\n\n  Return this exact JSON structure:\n  {\n    \"company\": \"string\",\n    \"role\": \"string\",\n    \"seniority\": \"Junior|Mid|Senior|Lead|Principal\",\n    \"hard_requirements\": \"comma-separated list\",\n    \"tech_stack\": \"comma-separated list\",\n    \"salary\": \"range or empty string if not mentioned\",\n    \"location\": \"Remote|Hybrid|On-site, city if mentioned\",\n    \"domain\": \"Fintech|SaaS|Retail|Healthcare|Other\",\n    \"key_signal\": \"one sentence \u2014 what makes this role unique or what they really care about\"\n  }"
            }
          ]
        }
      },
      "credentials": {
        "anthropicApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "b9adade9-90d0-409a-8ae6-64c0d7ab7538",
      "name": "Parse JSON for Sheets",
      "type": "n8n-nodes-base.code",
      "position": [
        1856,
        384
      ],
      "parameters": {
        "jsCode": "const text = $input.item.json.content[0].text;\n  const cleaned = text.replace(/```json\\n?/g, '').replace(/```\\n?/g, '').trim();\n  return { json: JSON.parse(cleaned) };"
      },
      "typeVersion": 2
    },
    {
      "id": "d3c0082c-fc42-4dfc-b3ea-7fbd4a89e984",
      "name": "Append Job Data to Sheet",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        2080,
        384
      ],
      "parameters": {
        "columns": {
          "value": {
            "Date": "={{ $now.toFormat('yyyy-MM-dd') }}",
            "Role": "={{ $json.role }}",
            "Domain": "={{ $json.domain }}",
            "Salary": "={{ $json.salary }}",
            "Company": "={{ $json.company }}",
            "Location": "={{ $json.location }}",
            "Seniority": "={{ $json.seniority }}",
            "Key Signal": "={{ $json.key_signal }}",
            "Tech Stack": "={{ $json.tech_stack }}",
            "Hard Requirements": "={{ $json.hard_requirements }}"
          },
          "schema": [
            {
              "id": "Date",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Date",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Company",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Company",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Role",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Role",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Seniority",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Seniority",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Hard Requirements",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Hard Requirements",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Tech Stack",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Tech Stack",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Salary",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Salary",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Location",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Location",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Domain",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Domain",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Key Signal",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Key Signal",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "name",
          "value": "={{ $('Set Config Variables').item.json.SHEET_PERSONAL_JOB_MARKET_INTEL_SHEET }}"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $('Set Config Variables').item.json.SHEET_PERSONAL_JOB_MARKET_INTEL_ID }}"
        },
        "authentication": "serviceAccount"
      },
      "credentials": {
        "googleApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "8e9accb2-609a-4559-b592-228689cf45ea",
      "name": "Send Telegram Log Confirmation",
      "type": "n8n-nodes-base.telegram",
      "position": [
        2288,
        384
      ],
      "parameters": {
        "text": "=\u2705 *Logged*    *{{ $json.Role }}* at *{{ $json.Company }}*   Seniority: {{ $json.Seniority }}   Domain: {{ $json.Domain }}",
        "chatId": "={{ $('When Telegram Message Received').item.json.message.chat.id }}",
        "additionalFields": {}
      },
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "719b00b6-cc0b-4d7a-a95d-daf39368cfd1",
      "name": "Read All Jobs from Sheets",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        1520,
        16
      ],
      "parameters": {
        "options": {},
        "sheetName": {
          "__rl": true,
          "mode": "name",
          "value": "={{ $('Set Config Variables').item.json.SHEET_PERSONAL_JOB_MARKET_INTEL_SHEET }}"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $('Set Config Variables').item.json.SHEET_PERSONAL_JOB_MARKET_INTEL_ID }}"
        },
        "authentication": "serviceAccount"
      },
      "credentials": {
        "googleApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "8cd6100d-1ff6-477f-ae17-dd773034189f",
      "name": "Claude Analyze Job Patterns",
      "type": "@n8n/n8n-nodes-langchain.anthropic",
      "position": [
        1728,
        16
      ],
      "parameters": {
        "modelId": {
          "__rl": true,
          "mode": "list",
          "value": "claude-haiku-4-5-20251001",
          "cachedResultName": "claude-haiku-4-5-20251001"
        },
        "options": {},
        "messages": {
          "values": [
            {
              "content": "=You are analyzing a personal job market database. Below is structured data from {{ $input.all().length\n   }} job postings. Analyze the patterns and return a formatted report.\n\n  Data:\n  {{ JSON.stringify($input.all().map(item => item.json)) }}\n\n  Return a clear report with these sections:\n  1. **Top Skills** \u2014 most frequently required across all postings\n  2. **Tech Stack Trends** \u2014 what technologies appear most\n  3. **Salary Range** \u2014 distribution and average if available\n  4. **Seniority Distribution** \u2014 Junior/Mid/Senior breakdown\n  5. **Domains** \u2014 which industries are hiring most\n  6. **Key Signal** \u2014 one insight about what the market is actually looking for right now\n\nReturn a SHORT Telegram-friendly report using only: *bold*, bullet points, and emojis. No tables, no\n  markdown headers, no long explanations. Max 300 words.\n\n  Format exactly like this:\n  \ud83d\udcca *Job Market Report \u2014 [X] postings*\n\n  \ud83d\udd27 *Top Skills*\n  \u2022 Skill 1 (X/X roles)\n  \u2022 Skill 2 (X/X roles)\n\n  \ud83d\udcb0 *Salary Range*\n  \u2022 Mid: \u20acX\u2013\u20acX\n  \u2022 Senior: \u20acX\u2013\u20acX\n\n  \ud83d\udcc8 *Seniority*\n  \u2022 Mid: X% | Senior: X% | Junior: 0%\n\n  \ud83c\udfed *Domains*\n  \u2022 Domain 1, Domain 2\n\n  \ud83d\udca1 *Key Signal*\n  One sentence. What the market actually wants right now."
            }
          ]
        }
      },
      "credentials": {
        "anthropicApi": {
          "name": "<your credential>"
        }
      },
      "executeOnce": true,
      "typeVersion": 1
    },
    {
      "id": "fb8ac2b1-e375-4cdf-8f2d-91742984b730",
      "name": "Send Job Report via Telegram",
      "type": "n8n-nodes-base.telegram",
      "position": [
        2080,
        16
      ],
      "parameters": {
        "text": "={{ $json.content[0].text }}",
        "chatId": "={{ $('When Telegram Message Received').item.json.message.chat.id }}",
        "additionalFields": {}
      },
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    }
  ],
  "active": true,
  "settings": {
    "binaryMode": "separate",
    "executionOrder": "v1"
  },
  "versionId": "55c2829e-957b-489e-bca5-854ea9d59088",
  "connections": {
    "Set Config Variables": {
      "main": [
        [
          {
            "node": "Check Telegram User ID",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse JSON for Sheets": {
      "main": [
        [
          {
            "node": "Append Job Data to Sheet",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Route by Message Type": {
      "main": [
        [
          {
            "node": "Read All Jobs from Sheets",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Claude Extract Job Info",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check Telegram User ID": {
      "main": [
        [
          {
            "node": "Route by Message Type",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Claude Extract Job Info": {
      "main": [
        [
          {
            "node": "Parse JSON for Sheets",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Append Job Data to Sheet": {
      "main": [
        [
          {
            "node": "Send Telegram Log Confirmation",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Read All Jobs from Sheets": {
      "main": [
        [
          {
            "node": "Claude Analyze Job Patterns",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Claude Analyze Job Patterns": {
      "main": [
        [
          {
            "node": "Send Job Report via Telegram",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "When Telegram Message Received": {
      "main": [
        [
          {
            "node": "Set Config Variables",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}

Credentials you'll need

Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.

Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

This workflow logs job postings sent via Telegram into Google Sheets using Anthropic Claude to extract structured fields, and generates an on-demand Telegram report (/report) that analyzes trends across all saved postings. Triggers when a new Telegram message is received by the…

Source: https://n8n.io/workflows/15931/ — original creator credit. Request a take-down →

More AI & RAG workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

AI & RAG

Ask questions like “How much did I spend on food last month?” and get instant answers from your financial data — directly in Telegram.

Telegram Trigger, OpenAI, Google Sheets +2
AI & RAG

Most expense tracker apps (like Money Lover, Spendee, or Wallet) have a common friction point: Data Entry. You have to unlock your phone, find the app, wait for it to load, navigate menus, and manuall

Google Sheets, Google Gemini, Telegram +2
AI & RAG

&gt; ⚠️ Disclaimer: This workflow uses Community Nodes and must be run on a self-hosted instance of n8n.

HTTP Request, Telegram Trigger, Telegram +2
AI & RAG

Viral Tik Tok Clone Finder. Uses httpRequest, telegramTrigger, openAi, googleSheets. Event-driven trigger; 41 nodes.

HTTP Request, Telegram Trigger, OpenAI +2
AI & RAG

Sales Lead Qualifier. Uses telegramTrigger, googleSheets, telegram, googleGemini. Event-driven trigger; 41 nodes.

Telegram Trigger, Google Sheets, Telegram +3