8
n8n 中文网amn8n.com

X/Twitter招聘帖监控与Apify、AI筛选及Telegram警报

中级

这是一个Content Creation, Multimodal AI领域的自动化工作流,包含 13 个节点。主要使用 If, Set, Code, Telegram, HttpRequest 等节点。 使用Apify、AI筛选和Telegram警报监控X/Twitter上的招聘帖子

前置要求
  • Telegram Bot Token
  • 可能需要目标 API 的认证凭证
  • Google Sheets API 凭证
  • OpenAI API Key
工作流预览
可视化展示节点连接关系,支持缩放和平移
导出工作流
复制以下 JSON 配置到 n8n 导入,即可使用此工作流
{
  "meta": {
    "instanceId": "e08988aa0061610a374f1467cc80142fc7298a1ab25f75e8f07895c66f95c50a",
    "templateCredsSetupCompleted": true
  },
  "nodes": [
    {
      "id": "b522f688-3201-468f-878c-96575adeef55",
      "name": "在 sheet1 中追加或更新行",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        -832,
        1584
      ],
      "parameters": {
        "columns": {
          "value": {
            "url": "={{ $json.url }}",
            "text": "={{ $json.text }}",
            "author": "={{ $json.author.userName }}",
            "location": "={{ $json.author.location }}",
            "url author": "={{ $json.author.url }}"
          },
          "schema": [
            {
              "id": "url",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "url",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "text",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "text",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "author",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "author",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "url author",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "url author",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "location",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "location",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "url"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "appendOrUpdate",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1b87NBYctXlv5e-cfjF8XrGgtfLElgnELyDBcumoM2bE/edit#gid=0",
          "cachedResultName": "X"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1b87NBYctXlv5e-cfjF8XrGgtfLElgnELyDBcumoM2bE",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1b87NBYctXlv5e-cfjF8XrGgtfLElgnELyDBcumoM2bE/edit?usp=drivesdk",
          "cachedResultName": "X and threads"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "id": "BX6f5DraM0AGzqRA",
          "name": "Google Sheets account"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "92929cdf-2771-4e86-bd78-9d1cd7c8c4ba",
      "name": "编辑字段",
      "type": "n8n-nodes-base.set",
      "position": [
        -1888,
        1680
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "946aeca1-2f8e-418d-9970-45a0c3c768c0",
              "name": "url",
              "type": "string",
              "value": "={{ $json.url }}"
            },
            {
              "id": "9c6a1f7e-5975-47bf-bebd-42eab220ccf1",
              "name": "text",
              "type": "string",
              "value": "={{ $json.text }}"
            },
            {
              "id": "1796f734-f0d9-430b-bce9-2c7fe9fa50c6",
              "name": "author.userName",
              "type": "string",
              "value": "={{ $json.author.userName }}"
            },
            {
              "id": "dcbda70c-ce37-4c6e-971b-d25a0cc1ef59",
              "name": "author.url",
              "type": "string",
              "value": "={{ $json.author.url }}"
            },
            {
              "id": "edaa24fe-eb31-4caa-a67f-2bfd6649752f",
              "name": "author.location",
              "type": "string",
              "value": "={{ $json.author.location }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "d8ed862b-a231-46ea-ba29-eeddb19a6b1e",
      "name": "6 小时",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        -2336,
        1680
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "hours",
              "hoursInterval": 12
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "ad8fa0da-5452-4de7-849c-56920740d38d",
      "name": "HTTP 请求",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -2112,
        1680
      ],
      "parameters": {
        "url": "https://api.apify.com/v2/acts/apidojo~tweet-scraper/run-sync-get-dataset-items?",
        "method": "POST",
        "options": {
          "redirect": {
            "redirect": {}
          }
        },
        "jsonBody": "{\n    \"maxItems\": 50,\n    \"searchTerms\": [\n      \"n8n developer\", \n      \"looking for n8n\",\n      \"n8n expert\",\n      \"hire AI automation\", \n      \"looking for AI automation\"\n    ],\n    \"sort\": \"Latest\"\n}",
        "sendBody": true,
        "sendHeaders": true,
        "specifyBody": "json",
        "headerParameters": {
          "parameters": [
            {
              "name": "Accept",
              "value": "application/json"
            },
            {
              "name": "Authorization",
              "value": "Bearer "
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "c7442722-6a28-4e0e-b8bd-09fc95cd6a2f",
      "name": "发送短信1",
      "type": "n8n-nodes-base.telegram",
      "position": [
        -832,
        1744
      ],
      "webhookId": "e7b7167d-a137-44ee-a7d1-f8bf6c99158e",
      "parameters": {
        "text": "=Tweet URL: {{ $json.url }} \nAuthor:{{ $json.author.userName }}\nAuthor URL: {{ $json.author.url }}\nLocation:{{ $json.author.location }}\nText: {{ $json.text }}",
        "additionalFields": {}
      },
      "credentials": {
        "telegramApi": {
          "id": "x5VuxQ3yh5aU8gPB",
          "name": "Lead replied bot"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "0745d915-2372-4ae4-af55-10f659327f68",
      "name": "AI Agent1",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        -1664,
        1680
      ],
      "parameters": {
        "text": "=This is the text that you have to check  {{ $json.text }}{{ $json.url }}{{ $json.author }}\n",
        "options": {
          "systemMessage": "=<goal> You are **Hiring Post Classifier & Extractor**. Read short social posts (Twitter/Threads), plus author bio and any link-preview text, and return **only** posts where the **author is hiring an n8n/AI automation engineer** in allowed geographies. Deduplicate against Google Sheets by `url`. If non-passing or duplicate → **output nothing**. </goal>\n\n<format_rules>\n\nInput (exact shape):\n\n{\n  \"url\": \"https://twitter.com/... or https://www.threads.net/...\",\n  \"text\": \"raw post text\",\n  \"author\": {\n    \"userName\": \"handle or display name\",\n    \"url\": \"author profile url\",\n    \"location\": \"free-text location from bio (optional)\"\n  }\n}\n\n\nOutput: strict JSON (see <output>) for passing, non-duplicate posts; otherwise no output (empty response).\n\nNo extra fields, arrays, prose, or explanations.\n</format_rules>\n\n\n<decision_rules>\n\nReduce tokens where ever possible\n\nHire-only by the author (no replies/retweets unless the author restates as the hirer).\nAccept only if text clearly signals an open n8n/AI automation engineer role.\nStrong hire cues (any): hiring, we’re hiring, opening, role, position, join our team, bring on an automation engineer, seeking n8n engineer, need an AI automation engineer, apply, send your portfolio/resume, email to, link to job.\nHelpful (not required): full-time, part-time, contract, paid, salary, compensation.\nRole scope (accept): n8n engineer, AI automation engineer, workflow automation engineer, automation developer (explicit n8n/AI automation duties), no-code/low-code automation engineer (with n8n/AI explicitly mentioned).\nExclude: generic software roles without automation focus; RPA-only if n8n/AI automation isn’t explicit; “consultant available” language (see self-promo).\n\nExclude self-promotion / service ads / bait.\nReject if the author markets themselves/services (e.g., “hire me,” “available for projects,” “my rates,” “portfolio/reel,” “DMs open to hire me,” “book me,” “client work,” “commissions,” “services”).\nIf the bio indicates the author is a freelancer for hire and the post is ambiguous → treat as self-promo → exclude.\n\nDeduplication (Google Sheets).\nAfter passing 1–3, query the sheet for the url. If found → no output. If not found → output JSON.\n</decision_rules>\n\n<tools_and_usage>\n<google_sheets access=\"read-only\">\n\nmethod: find(url) → returns a match if the post url already exists\n</google_sheets>\n</tools_and_usage>\n\n<planning_guidance>\n\nConfirm author hiring signal for an n8n/AI automation engineer (not self-promo; not a reply/retweet unless restated).\n\nApply geo rules using post text, bio location, and link-preview text.\n\nIf pass, dedupe via Google Sheets on url.\n\nIf unique, emit strict JSON with minimal pass-through fields.\n</planning_guidance>\n\n<output> For passing, non-duplicate posts, return **only**: ```json { \"url\": \"{{ $json.url }}\", \"text\": \"{{ $json.text }}\", \"username\": \"{{ $json.author.userName }}\", \"profile_url\": \"{{ $json.author.url }}\", \"location\": \"{{ $json.author.location }}\" } ``` Otherwise, **return nothing**. </output>\n\n"
        },
        "promptType": "define",
        "hasOutputParser": true
      },
      "typeVersion": 2.2
    },
    {
      "id": "beae3b6b-780b-4fa8-836b-c17e9d1bfa73",
      "name": "OpenAI 聊天模型1",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        -1664,
        1904
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4.1-mini"
        },
        "options": {}
      },
      "credentials": {
        "openAiApi": {
          "id": "LWvK49oyV3NIemKb",
          "name": "OpenAi account"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "ff6f42d3-893c-453f-bf85-db69c094ad46",
      "name": "在 Google Sheets1 中获取行",
      "type": "n8n-nodes-base.googleSheetsTool",
      "position": [
        -1536,
        1904
      ],
      "parameters": {
        "options": {},
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1b87NBYctXlv5e-cfjF8XrGgtfLElgnELyDBcumoM2bE/edit#gid=0",
          "cachedResultName": "X"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1b87NBYctXlv5e-cfjF8XrGgtfLElgnELyDBcumoM2bE",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1b87NBYctXlv5e-cfjF8XrGgtfLElgnELyDBcumoM2bE/edit?usp=drivesdk",
          "cachedResultName": "X and threads"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "id": "BX6f5DraM0AGzqRA",
          "name": "Google Sheets account"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "e4a986d2-4146-46bc-9ca8-d4acc07c9e52",
      "name": "代码1",
      "type": "n8n-nodes-base.code",
      "position": [
        -1088,
        1680
      ],
      "parameters": {
        "jsCode": "const results = [];\n\nfor (const item of $input.all()) {\n  try {\n    const rawData = item.json.output; // The raw string from the LLM\n\n    // --- FIX IS HERE ---\n    // Find the first opening curly brace '{'\n    const firstBrace = rawData.indexOf('{');\n    // Find the last closing curly brace '}'\n    const lastBrace = rawData.lastIndexOf('}');\n\n    // If both braces are found, extract the content between them\n    if (firstBrace !== -1 && lastBrace !== -1) {\n      const jsonString = rawData.substring(firstBrace, lastBrace + 1);\n\n      // Now, parse the cleaned string\n      const obj = JSON.parse(jsonString);\n\n      results.push({ json: obj });\n    }\n    // --- END OF FIX ---\n\n  } catch (error) {\n    // This will catch any items that still fail to parse,\n    // so the whole workflow doesn't stop for one bad item.\n    console.error(\"Failed to parse an item:\", error);\n  }\n}\n\nreturn results;\n"
      },
      "typeVersion": 2
    },
    {
      "id": "4f0c0edc-ac12-41ff-9733-71df7f1ed66f",
      "name": "条件判断",
      "type": "n8n-nodes-base.if",
      "position": [
        -1312,
        1680
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "d6b35f7a-4b86-4aa0-a826-c6992ad15da2",
              "operator": {
                "type": "string",
                "operation": "notEmpty",
                "singleValue": true
              },
              "leftValue": "={{ $json.output }}",
              "rightValue": "={}"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "63532971-8154-4fd7-8805-c9a86d685588",
      "name": "便签",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -3088,
        1264
      ],
      "parameters": {
        "color": 5,
        "width": 672,
        "height": 1184,
        "content": "自动抓取 X(Twitter)上招聘特定职位(例如,自动化工程师、视频编辑、平面设计师)的帖子,使用 AI 筛选真实招聘意图,在 Google Sheets 中去重,并通过 Telegram 发出警报。"
      },
      "typeVersion": 1
    },
    {
      "id": "c143fed2-4d73-4532-8492-5fb66fd1ed2e",
      "name": "便签1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -3088,
        2496
      ],
      "parameters": {
        "width": 672,
        "height": 256,
        "content": "# 寻找定制工作流?通过我的 Reddit 或网站预订——并关注未来的模板。"
      },
      "typeVersion": 1
    },
    {
      "id": "76c04377-96f0-45ec-84be-6d55e9206f29",
      "name": "便签2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2224,
        1264
      ],
      "parameters": {
        "color": 5,
        "width": 336,
        "height": 256,
        "content": "## 1. 在每个 Https 节点中替换 API 密钥"
      },
      "typeVersion": 1
    }
  ],
  "pinData": {
    "6 hours": [
      {
        "Hour": "15",
        "Year": "2025",
        "Month": "September",
        "Minute": "01",
        "Second": "38",
        "Timezone": "Europe/Berlin (UTC+02:00)",
        "timestamp": "2025-09-24T15:01:38.805+02:00",
        "Day of week": "Wednesday",
        "Day of month": "24",
        "Readable date": "September 24th 2025, 3:01:38 pm",
        "Readable time": "3:01:38 pm"
      }
    ]
  },
  "connections": {
    "If": {
      "main": [
        [
          {
            "node": "Code1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Code1": {
      "main": [
        [
          {
            "node": "Send a text message1",
            "type": "main",
            "index": 0
          },
          {
            "node": "Append or update row in sheet1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "6 hours": {
      "main": [
        [
          {
            "node": "HTTP Request",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "AI Agent1": {
      "main": [
        [
          {
            "node": "If",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Edit Fields": {
      "main": [
        [
          {
            "node": "AI Agent1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "HTTP Request": {
      "main": [
        [
          {
            "node": "Edit Fields",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI Chat Model1": {
      "ai_languageModel": [
        [
          {
            "node": "AI Agent1",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Get row(s) in sheet in Google Sheets1": {
      "ai_tool": [
        [
          {
            "node": "AI Agent1",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    }
  }
}
常见问题

如何使用这个工作流?

复制上方的 JSON 配置代码,在您的 n8n 实例中创建新工作流并选择「从 JSON 导入」,粘贴配置后根据需要修改凭证设置即可。

这个工作流适合什么场景?

中级 - 内容创作, 多模态 AI

需要付费吗?

本工作流完全免费,您可以直接导入使用。但请注意,工作流中使用的第三方服务(如 OpenAI API)可能需要您自行付费。

工作流信息
难度等级
中级
节点数量13
分类2
节点类型11
难度说明

适合有一定经验的用户,包含 6-15 个节点的中等复杂度工作流

外部链接
在 n8n.io 查看

分享此工作流