8
n8n 中文网amn8n.com

使用 HTTP Last-Modified 检查从 Google Sheets 获取职位发布过期和刷新提醒

高级

这是一个HR, Miscellaneous, Multimodal AI领域的自动化工作流,包含 19 个节点。主要使用 If, Set, Code, Wait, Gmail 等节点。 通过 Google Sheets、HTTP 检查和 Gmail 实现职位发布过期提醒的自动化

前置要求
  • Google 账号和 Gmail API 凭证
  • 可能需要目标 API 的认证凭证
  • Google Sheets API 凭证
工作流预览
可视化展示节点连接关系,支持缩放和平移
导出工作流
复制以下 JSON 配置到 n8n 导入,即可使用此工作流
{
  "id": "Et2vjObBEUPt72Ff",
  "meta": {
    "instanceId": "14e4c77104722ab186539dfea5182e419aecc83d85963fe13f6de862c875ebfa",
    "templateCredsSetupCompleted": true
  },
  "name": "使用 HTTP Last-Modified 检查从 Google Sheets 获取职位发布过期和刷新提醒",
  "tags": [],
  "nodes": [
    {
      "id": "86114cf9-db36-4ed0-bd20-cead6465ca95",
      "name": "计划触发器",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        -60,
        -40
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "cronExpression",
              "expression": "10 32 10 * * *"
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "70241c9f-d0df-4907-9a77-045436521635",
      "name": "获取职位 URL",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        320,
        -40
      ],
      "parameters": {
        "options": {},
        "sheetName": {
          "__rl": true,
          "mode": "name",
          "value": "Job Posts"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "1n_AIqOd10Q0ErQZSO4q4LBMekwgsR4cP7EW2q9nEzdk"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "id": "K51JQLS2WHFWzap5",
          "name": "Google Sheets account 7"
        }
      },
      "executeOnce": false,
      "notesInFlow": false,
      "retryOnFail": false,
      "typeVersion": 4.6,
      "alwaysOutputData": true
    },
    {
      "id": "d21a1bde-5c2f-45cc-b729-7cbf9d378d1d",
      "name": "筛选无效行",
      "type": "n8n-nodes-base.if",
      "position": [
        480,
        -40
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "67a2d579-8bab-4da0-b6a2-d38acb936935",
              "operator": {
                "type": "string",
                "operation": "notEmpty",
                "singleValue": true
              },
              "leftValue": "{{ $json.job_url }}",
              "rightValue": ""
            },
            {
              "id": "10c7e27f-331d-4df6-99cf-442c346074af",
              "operator": {
                "type": "string",
                "operation": "regex"
              },
              "leftValue": "={{ $json.recruiter_email }}",
              "rightValue": "^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$"
            },
            {
              "id": "43158fe0-b3f9-4b5b-8d86-9a2d16ac5c21",
              "operator": {
                "type": "string",
                "operation": "notEmpty",
                "singleValue": true
              },
              "leftValue": "={{ $json.recruiter_email }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "e6bb385d-a4b3-48b7-995e-8ad55a06357b",
      "name": "HTTP 请求",
      "type": "n8n-nodes-base.httpRequest",
      "onError": "continueRegularOutput",
      "position": [
        1320,
        40
      ],
      "parameters": {
        "url": "={{$json.job_url}}",
        "method": "HEAD",
        "options": {
          "timeout": 5000
        },
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "User-Agent",
              "value": "={{ ($json[\"USER_AGENT\"] || \"n8n-job-checker/1.0\").replace(/\\n/g, \"\").trim() }}"
            }
          ]
        }
      },
      "retryOnFail": false,
      "typeVersion": 4.2
    },
    {
      "id": "48022cb5-72dd-45f8-aabf-b90c55310dd3",
      "name": "HTTP 请求前等待",
      "type": "n8n-nodes-base.wait",
      "position": [
        1120,
        40
      ],
      "webhookId": "7b536af6-1208-4fb7-9072-4b58c7840905",
      "parameters": {},
      "typeVersion": 1.1
    },
    {
      "id": "85d9b757-910b-4fef-874f-abea9ebbae81",
      "name": "年龄 ≥ 阈值天数?",
      "type": "n8n-nodes-base.if",
      "position": [
        1940,
        40
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "f38b35c0-457f-478c-94bb-78dfb95f34fd",
              "operator": {
                "type": "number",
                "operation": "gte"
              },
              "leftValue": "={{ $json.age_days }}",
              "rightValue": "={{ 30 }}"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "d26e7e33-fc11-4674-81a7-8e8335998570",
      "name": "Gmail",
      "type": "n8n-nodes-base.gmail",
      "onError": "continueRegularOutput",
      "position": [
        2220,
        20
      ],
      "webhookId": "69c3daba-371f-4a5b-93e2-6332e40ea0dd",
      "parameters": {
        "sendTo": "={{ $json.recruiter_email }}",
        "message": "=<p>Hi {{ $json.recruiter_name }},</p>\n<p>This is a kind reminder that the following job post appears to be <strong>{{ $json.age_days }} days old</strong>:</p>\n<p><a href=\"{{ $json.job_url }}\">{{ $json.job_url }}</a></p>\n<p>Last Modified: <strong>{{ $json.last_modified }}</strong></p>\n<p>If the position is still open, we recommend refreshing or updating the post to ensure visibility and relevance.</p>\n<p>Thank you!</p>\n<p><em>— Hiring Ops Bot</em></p>",
        "options": {},
        "subject": "={{'Gentle Reminder: Update Your Job Post (${json.age_days} days old)' }}"
      },
      "credentials": {
        "gmailOAuth2": {
          "id": "GsAjl8kiLaQnkjoK",
          "name": "Gmail account 10"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "1d6141d4-a6b8-425f-8543-c3ae6207a12d",
      "name": "计算年龄",
      "type": "n8n-nodes-base.code",
      "position": [
        1760,
        40
      ],
      "parameters": {
        "jsCode": "const lastModifiedStr = $input.item.json.last_modified;\n\nlet ageDays = 0;\n\nif (lastModifiedStr && lastModifiedStr !== 'Unknown') {\n  try {\n    const lastModified = new Date(lastModifiedStr);\n    const now = new Date();\n    const diffMs = now.getTime() - lastModified.getTime();\n    ageDays = Math.floor(diffMs / (1000 * 60 * 60 * 24));\n  } catch (error) {\n    console.log('Error parsing date:', error);\n    ageDays = 0;\n  }\n}\n\nreturn [{\n  ...$input.item.json,\n  age_days: ageDays\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "8056958e-6330-4938-b2b2-939e3a08779e",
      "name": "记录无效行",
      "type": "n8n-nodes-base.set",
      "position": [
        700,
        60
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "cbd19052-996c-432a-bdd4-40c6ba089dce",
              "name": "reason",
              "type": "string",
              "value": "={{ $json.job_url ? ($json.recruiter_email ? ($json.recruiter_name ? 'Unknown validation error' : 'Missing recruiter name') : 'Invalid email format') : 'Missing job URL' }}"
            },
            {
              "id": "2dc2f6ba-926a-4283-b2ec-d8d8d41201f4",
              "name": "row_data",
              "type": "string",
              "value": "={{ JSON.stringify($json) }}"
            },
            {
              "id": "4e3c204a-7096-4b8f-9b34-bb1af2158718",
              "name": "status",
              "type": "string",
              "value": "SKIPPED"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "566fd940-f6bd-4f8c-8d7e-1e86b375ff63",
      "name": "检查周末",
      "type": "n8n-nodes-base.code",
      "position": [
        880,
        -220
      ],
      "parameters": {
        "jsCode": "// Check if we should skip weekends\nconst includeWeekends = $('configuration sheet').item.json.INCLUDE_WEEKENDS;\nconst today = new Date();\nconst dayOfWeek = today.getDay(); // 0 = Sunday, 6 = Saturday\n\nif (!includeWeekends && (dayOfWeek === 0 || dayOfWeek === 6)) {\n  return {\n    json: {\n      ...$input.item.json,\n      status: 'SKIPPED_WEEKEND',\n      skip_reason: 'Weekend execution disabled'\n    }\n  };\n}\n\nreturn {\n  json: {\n    ...$input.item.json,\n    status: 'PROCESSING'\n  }\n};"
      },
      "typeVersion": 2
    },
    {
      "id": "055be0ef-82ba-42fa-a8e8-88dc89227746",
      "name": "周末筛选器",
      "type": "n8n-nodes-base.if",
      "position": [
        1120,
        -200
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "e9e590cf-531f-46d8-ae6a-0307b83e73c3",
              "operator": {
                "name": "filter.operator.equals",
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json.status }}",
              "rightValue": "PROCESSING"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "cb2ed435-62d6-47c6-80fe-b9073738fa85",
      "name": "记录周末跳过",
      "type": "n8n-nodes-base.code",
      "position": [
        1220,
        -500
      ],
      "parameters": {
        "jsCode": "return {\n  json: {\n    ...$input.item.json,\n    logged_reason: 'Execution skipped - weekend and INCLUDE_WEEKENDS is false'\n  }\n};"
      },
      "typeVersion": 2
    },
    {
      "id": "084d89b8-3ea1-4b73-95cc-990c47d418c3",
      "name": "便签",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -160,
        -240
      ],
      "parameters": {
        "width": 300,
        "content": "## 配置中心"
      },
      "typeVersion": 1
    },
    {
      "id": "b54e6d67-d203-4970-850b-aee5e262b1c0",
      "name": "便签1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        400,
        -220
      ],
      "parameters": {
        "width": 280,
        "content": "## 🚨 数据验证检查点"
      },
      "typeVersion": 1
    },
    {
      "id": "49dd1f84-ad4c-460c-8848-915bf955f965",
      "name": "便签2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        820,
        -400
      ],
      "parameters": {
        "content": "## 周末逻辑"
      },
      "typeVersion": 1
    },
    {
      "id": "7cb61d6a-8db3-499e-ae0b-4375e3f66eb1",
      "name": "便签3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1220,
        200
      ],
      "parameters": {
        "width": 280,
        "height": 180,
        "content": "## 🌐 HEAD 请求获取头部信息"
      },
      "typeVersion": 1
    },
    {
      "id": "245d21f0-55f0-4a2e-8345-fce982d24044",
      "name": "便签4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1700,
        200
      ],
      "parameters": {
        "width": 260,
        "height": 180,
        "content": "## 年龄计算引擎"
      },
      "typeVersion": 1
    },
    {
      "id": "6d313a45-5953-434d-aae0-02db2d324502",
      "name": "配置表格",
      "type": "n8n-nodes-base.set",
      "position": [
        140,
        -40
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "1e96273a-d891-44c4-b433-2a11840b8c63",
              "name": "SPREADSHEET_ID",
              "type": "string",
              "value": "1n_AIqOd10Q0ErQZSO4q4LBMekwgsR4cP7EW2q9nEzdk"
            },
            {
              "id": "0aae4a91-f153-4493-a9a8-9a2023e4f158",
              "name": "SOURCE_SHEET",
              "type": "string",
              "value": "Job Posts"
            },
            {
              "id": "802cb08e-cfec-4a40-9236-afea62476136",
              "name": "TIMEZONE",
              "type": "string",
              "value": "Asia/Kolkata"
            },
            {
              "id": "708470ef-5283-4440-9db7-4bd9336ed468",
              "name": "THRESHOLD_DAYS",
              "type": "number",
              "value": 30
            },
            {
              "id": "2cfbcdc6-7b00-4f6c-baf4-a9b37016ac8c",
              "name": "USER_AGENT",
              "type": "string",
              "value": "n8n-job-checker/1.0"
            },
            {
              "id": "639af2e4-08f4-4153-9dc0-dc5abac95346",
              "name": "HTTP_TIMEOUT_SECONDS",
              "type": "number",
              "value": 10
            },
            {
              "id": "4fcad7fb-adeb-4c7a-a165-20a2c5ae3788",
              "name": "HTTP_RETRIES",
              "type": "number",
              "value": 2
            },
            {
              "id": "1ea69c95-e131-45ca-8e4a-ee005608a66e",
              "name": "RATE_LIMIT_HTTP_SECONDS",
              "type": "number",
              "value": 5
            },
            {
              "id": "b8ca4dcd-cf18-4732-8b33-c9341d38811c",
              "name": "RATE_LIMIT_EMAIL_SECONDS",
              "type": "number",
              "value": 2
            },
            {
              "id": "fbaed34b-a618-45ec-883c-7ee89dc2932f",
              "name": "SMTP_FROM",
              "type": "string",
              "value": "hiring-ops@company.com"
            },
            {
              "id": "b3f745cb-b5d2-43e9-a7a1-803fc0646274",
              "name": "SUBJECT_TEMPLATE",
              "type": "string",
              "value": "Please review your stale job post"
            },
            {
              "id": "03bb79a9-6115-402d-a88a-de24bdaf6016",
              "name": "HTML_TEMPLATE",
              "type": "string",
              "value": "<p>Hello {{recruiter_name}},</p><p>Your job post at {{job_url}} is {{age_days}} days old (last updated on {{last_modified}}). Consider updating it.</p>"
            },
            {
              "id": "7fa7d589-8e71-4de4-80bc-fe8bd2c91f1f",
              "name": "TEXT_TEMPLATE",
              "type": "string",
              "value": "Hi {{recruiter_name}}, your job {{job_url}} is {{age_days}} days old. Last updated on {{last_modified}}."
            },
            {
              "id": "4355e287-bbe4-4e82-a2bd-1cd086dc79db",
              "name": "INCLUDE_WEEKENDS",
              "type": "boolean",
              "value": true
            },
            {
              "id": "74a3dd62-e07d-4878-8ca6-ea6c5fc603d8",
              "name": "DRY_RUN",
              "type": "boolean",
              "value": false
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "b39b18bf-b1d6-4ddb-bed9-02907d288347",
      "name": "配置映射",
      "type": "n8n-nodes-base.set",
      "position": [
        1560,
        40
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "f576e9b1-c210-4f5f-bfcc-0e82d08e776a",
              "name": "last_modified",
              "type": "string",
              "value": "={{ $json.headers && $json.headers['last-modified'] ? $json.headers['last-modified'] : 'Unknown' }}"
            },
            {
              "id": "0ca59df2-775d-4a56-bd38-2b40d7ee3400",
              "name": "recruiter_email",
              "type": "string",
              "value": "=={{ $json.recruiter_email }}"
            },
            {
              "id": "7bfbd56a-df82-4c80-aff1-b0916c09c8ef",
              "name": "recruiter_name",
              "type": "string",
              "value": "={{ $json.recruiter_name }}"
            },
            {
              "id": "f0246fc4-54a2-442d-9d27-17e3e9f23edf",
              "name": "job_url",
              "type": "string",
              "value": "={{ $json.job_url }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    }
  ],
  "active": false,
  "pinData": {},
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "db387692-2684-4f88-9ec4-793201e5eeec",
  "connections": {
    "Gmail": {
      "main": [
        []
      ]
    },
    "HTTP Request": {
      "main": [
        [
          {
            "node": "configure mapping",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check Weekend": {
      "main": [
        [
          {
            "node": "Weekend Filter",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "calculate Age": {
      "main": [
        [
          {
            "node": "Is Age ≥ THRESHOLD_DAYS?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Job URLs": {
      "main": [
        [
          {
            "node": "Filter Invalid Rows",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Weekend Filter": {
      "main": [
        [
          {
            "node": "Wait Before HTTP",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Log weekend skip",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Log Invalid Rows": {
      "main": [
        []
      ]
    },
    "Schedule Trigger": {
      "main": [
        [
          {
            "node": "configuration sheet",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Wait Before HTTP": {
      "main": [
        [
          {
            "node": "HTTP Request",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "configure mapping": {
      "main": [
        [
          {
            "node": "calculate Age",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Filter Invalid Rows": {
      "main": [
        [
          {
            "node": "Check Weekend",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Log Invalid Rows",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "configuration sheet": {
      "main": [
        [
          {
            "node": "Fetch Job URLs",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Is Age ≥ THRESHOLD_DAYS?": {
      "main": [
        [
          {
            "node": "Gmail",
            "type": "main",
            "index": 0
          }
        ],
        []
      ]
    }
  }
}
常见问题

如何使用这个工作流?

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

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

高级 - 人力资源, 杂项, 多模态 AI

需要付费吗?

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

工作流信息
难度等级
高级
节点数量19
分类3
节点类型9
难度说明

适合高级用户,包含 16+ 个节点的复杂工作流

作者
WeblineIndia

WeblineIndia

@weblineindia

A Leading Software Engineering, Consulting & Outsourcing Services Company in USA & India serving Clients Globally since 1999.

外部链接
在 n8n.io 查看

分享此工作流