智能供应商合同续签与提醒工作流(使用 GPT 4.1 mini)
高级
这是一个Document Extraction, Multimodal AI领域的自动化工作流,包含 21 个节点。主要使用 If, Code, Slack, EmailSend, GoogleSheets 等节点。 使用 GPT-4.1 mini、Slack 和 Gmail 自动化供应商合同续签与提醒
前置要求
- •Slack Bot Token 或 Webhook URL
- •Google Sheets API 凭证
- •OpenAI API Key
使用的节点 (21)
工作流预览
可视化展示节点连接关系,支持缩放和平移
导出工作流
复制以下 JSON 配置到 n8n 导入,即可使用此工作流
{
"id": "DYAmOE9mHdq9X8eT",
"meta": {
"instanceId": "4a2e6764ba7a6bc9890d9225f4b21d570ce88fc9bd57549c89057fcee58fed0f",
"templateId": "5453",
"templateCredsSetupCompleted": true
},
"name": "智能供应商合同续签与提醒工作流(使用 GPT 4.1 mini)",
"tags": [
{
"id": "5HqPDYxcmr92h5gG",
"name": "Finance Workflow",
"createdAt": "2025-08-02T13:47:30.790Z",
"updatedAt": "2025-08-02T13:47:30.790Z"
}
],
"nodes": [
{
"id": "c14ab271-f79e-4b40-99f4-4a67cef3988a",
"name": "便签1",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1472,
1456
],
"parameters": {
"width": 540,
"height": 528,
"content": "## 1. 工作流每日早上 6 点触发"
},
"typeVersion": 1
},
{
"id": "7608b8d6-1acb-43f6-ad33-0cef8401e633",
"name": "便签 7",
"type": "n8n-nodes-base.stickyNote",
"position": [
-2544,
1120
],
"parameters": {
"width": 1024,
"height": 1696,
"content": "# 📝 智能供应商合同续签与提醒工作流(使用 GPT 4.1 mini)"
},
"typeVersion": 1
},
{
"id": "a7c8a69b-d5bb-4b7d-abef-8be18c0d2f83",
"name": "便签3",
"type": "n8n-nodes-base.stickyNote",
"position": [
-320,
2256
],
"parameters": {
"width": 1020,
"height": 596,
"content": ""
},
"typeVersion": 1
},
{
"id": "e0a78a50-7d76-4ce5-b240-6bb38a04f5ea",
"name": "查找即将到期的供应商",
"type": "n8n-nodes-base.code",
"position": [
-544,
1648
],
"parameters": {
"jsCode": "const results = [];\n\nfor (const item of items) {\n const data = item.json;\n\n const endDate = new Date(data[\"Contract End Date\"]);\n const noticePeriod = parseInt(data[\"Notice Period (days)\"], 10);\n\n // Calculate the date when the reminder should be sent\n const reminderDate = new Date(endDate);\n reminderDate.setDate(reminderDate.getDate() - noticePeriod);\n\n // If today's date >= reminder date, it's time to remind\n if ($today >= reminderDate && $today <= endDate) {\n results.push({\n json: {\n ...data,\n remind: true,\n reminderDate: reminderDate.toISOString().split(\"T\")[0],\n daysUntilExpiry: Math.floor((endDate - $today) / (1000 * 60 * 60 * 24))\n }\n });\n }\n}\n\nreturn results;"
},
"typeVersion": 2
},
{
"id": "8517796c-9c66-4c74-9c0e-b0050e495870",
"name": "OpenAI 聊天模型",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
"position": [
-48,
2080
],
"parameters": {
"model": {
"__rl": true,
"mode": "list",
"value": "gpt-4.1-mini"
},
"options": {}
},
"credentials": {
"openAiApi": {
"id": "PPSwAKeLQYgAPobT",
"name": "OpenAi account"
}
},
"typeVersion": 1.2
},
{
"id": "c7a565b9-97ca-4685-913b-80f01f9f9c09",
"name": "结构化输出解析器",
"type": "@n8n/n8n-nodes-langchain.outputParserStructured",
"position": [
80,
2080
],
"parameters": {
"jsonSchemaExample": "{\n\t\"subject\": \"California\",\n\t\"body\": \"\",\n \"original_json\":\"\"\n}"
},
"typeVersion": 1.3
},
{
"id": "909772f9-a143-4c8d-b7b9-482eb450d428",
"name": "提醒财务联系人并等待审批",
"type": "n8n-nodes-base.slack",
"position": [
320,
1872
],
"webhookId": "bf20ed1a-2179-4efb-bfa2-b1a5fa585d6d",
"parameters": {
"select": "channel",
"message": "={{ $json.output.subject }}\n{{ $json.output.body }}",
"options": {
"limitWaitTime": {
"values": {
"resumeAmount": 8
}
}
},
"channelId": {
"__rl": true,
"mode": "list",
"value": "C0989EJ7Z6K",
"cachedResultName": "automation"
},
"operation": "sendAndWait",
"authentication": "oAuth2"
},
"credentials": {
"slackOAuth2Api": {
"id": "fDHHxMgQm69z0h5T",
"name": "Slack account"
}
},
"typeVersion": 2.3
},
{
"id": "f07fa613-050d-4416-ab36-24050854bf0d",
"name": "编写电子邮件模板",
"type": "n8n-nodes-base.code",
"position": [
752,
1872
],
"parameters": {
"mode": "runOnceForEachItem",
"jsCode": "const record = JSON.parse($('Vendor reminder agent').item.json.output.original_json)\n\nconst vendorName = record[\"Vendor Name\"];\nconst vendorEmail = record[\"Vendor Email\"];\nconst serviceType = record[\"Service Type\"];\nconst contractEndDate = new Date(record[\"Contract End Date\"]).toDateString();\nconst financeContact = record[\"Finance Contact\"];\nconst financeEmail = record[\"Contact Email\"];\nconst renewalType = record[\"Renewal Type\"];\nconst contractValue = record[\"Contract Value (USD)\"];\n\nconst subject = `Contract Extension: ${vendorName} - ${serviceType}`;\n\nconst htmlBody = `\n <div style=\"font-family: Arial, sans-serif; color: #333; line-height: 1.6;\">\n <p>Dear ${vendorName} Team,</p>\n\n <p>We are reaching out to initiate the contract extension process for your <strong>${serviceType}</strong> service. According to our records, the current contract is set to end on <strong>${contractEndDate}</strong>.</p>\n\n <p>Key contract details:</p>\n <ul>\n <li><strong>Vendor:</strong> ${vendorName}</li>\n <li><strong>Service Type:</strong> ${serviceType}</li>\n <li><strong>Renewal Type:</strong> ${renewalType}</li>\n <li><strong>Contract Value:</strong> $${contractValue}</li>\n </ul>\n\n <p>If any changes are required for the upcoming term or if you need us to provide any documentation, kindly let us know by replying to this email.</p>\n\n <p>Best regards,<br/>\n ${financeContact}<br/>\n <a href=\"mailto:${financeEmail}\">${financeEmail}</a><br/>\n Finance Team</p>\n </div>\n`;\n\nreturn {\n to: vendorEmail,\n subject,\n html: htmlBody\n};"
},
"typeVersion": 2
},
{
"id": "92b106a8-712e-4be8-a95d-a71e8032f0f2",
"name": "供应商提醒代理",
"type": "@n8n/n8n-nodes-langchain.chainLlm",
"position": [
-80,
1872
],
"parameters": {
"text": "=Here is the contract info:\n{{ $json.toJsonString()}}",
"batching": {},
"messages": {
"messageValues": [
{
"message": "You are a helpful assistant that drafts professional email reminders to finance contacts about upcoming or overdue vendor contract renewals.\\n\\n## Instructions:\\n- Use a clear, polite, and informative tone.\\n- The email should include:\\n - Vendor name and service type\\n - Contract end date\\n - Renewal type (Manual or Auto-Renew)\\n - Days left until expiration (or if overdue)\\n - Contract value (if available)\\n - Notes field (if provided)\\n- Address the finance contact by name.\\n- Mention next steps if renewal is manual.\\n- Keep the email concise but informative.\\n\\n## Output format:\\n- `subject`: A short subject line for the email\\n- `body`: The full email body (plain text or simple HTML)\\n\\nNow write the subject and body."
}
]
},
"promptType": "define",
"hasOutputParser": true
},
"typeVersion": 1.7
},
{
"id": "43d8ff59-2359-4dbe-bc5b-4fa341f6266d",
"name": "获取供应商合同列表",
"type": "n8n-nodes-base.googleSheets",
"position": [
-768,
1648
],
"parameters": {
"options": {},
"sheetName": {
"__rl": true,
"mode": "list",
"value": "gid=0",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1zdDgKyL0sY54By57Yz4dNokQC_oIbVxcCKeWJ6PADBM/edit#gid=0",
"cachedResultName": "Sheet1"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1zdDgKyL0sY54By57Yz4dNokQC_oIbVxcCKeWJ6PADBM",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1zdDgKyL0sY54By57Yz4dNokQC_oIbVxcCKeWJ6PADBM/edit?usp=drivesdk",
"cachedResultName": "Vendors"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"id": "L670Nly6gZGo71br",
"name": "Google Sheets account 2"
}
},
"typeVersion": 4.6
},
{
"id": "e1ef73e4-980d-4b47-a715-4dc071d6a35c",
"name": "是否为自动续签合同?",
"type": "n8n-nodes-base.if",
"position": [
-320,
1648
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "31b61f50-4cc8-4c0c-a761-a1b16d1a9078",
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json[\"Renewal Type\"] }}",
"rightValue": "=Auto-Renew"
}
]
}
},
"typeVersion": 2.2
},
{
"id": "e6316dbe-ef76-4240-bfdd-6dc1ca0d52db",
"name": "发送手动延期合同电子邮件",
"type": "n8n-nodes-base.emailSend",
"position": [
976,
1872
],
"webhookId": "2cfc6b7b-220e-441b-a89f-0b14f7feb07c",
"parameters": {
"html": "={{ $json.html }}",
"options": {},
"subject": "={{ $json.subject }}",
"toEmail": "={{ $json.to }}"
},
"credentials": {
"smtp": {
"id": "Cqc9p9Z5PHj2MHzn",
"name": "SMTP account"
}
},
"typeVersion": 2.1
},
{
"id": "d6947406-9340-4d1d-b274-1b180019c67e",
"name": "便签",
"type": "n8n-nodes-base.stickyNote",
"position": [
-320,
896
],
"parameters": {
"width": 1036,
"height": 436,
"content": ""
},
"typeVersion": 1
},
{
"id": "b6b47449-df79-495b-9d79-f0003b6144d2",
"name": "编写 Slack 消息",
"type": "n8n-nodes-base.code",
"position": [
-16,
1488
],
"parameters": {
"mode": "runOnceForEachItem",
"jsCode": "const item = $json;\n\nconst vendorName = item[\"Vendor Name\"];\nconst serviceType = item[\"Service Type\"];\nconst contractEndDate = new Date(item[\"Contract End Date\"]).toDateString();\nconst renewalType = item[\"Renewal Type\"];\nconst contractValue = item[\"Contract Value (USD)\"];\nconst financeContact = item[\"Finance Contact\"];\nconst slackId = item[\"Slack ID\"];\nconst vendorEmail = item[\"Vendor Email\"];\nconst notes = item[\"Notes\"];\nconst daysUntil = item[\"daysUntilExpiry\"];\n\nconst message = `\n:bell: *Upcoming Auto-Renewal Notice*\n\nHi ${financeContact},\n\nThe contract with *${vendorName}* for *${serviceType}* is set to *auto-renew* in *${daysUntil} days* — on *${contractEndDate}*.\n\n> 💰 Contract Value: $${contractValue.toLocaleString()}\n> 📝 Renewal Type: ${renewalType}\n> 🗒️ Notes: ${notes}\n\nIf you wish to change this behavior or prevent auto-renewal, please send an email to the vendor at: *${vendorEmail}* before the renewal date.\n\nLet us know if you need help drafting the message or reviewing the terms.\n\nThanks, \nFinance Automation Bot\n`;\n\nreturn {\n slack_message: message,\n slack_target: slackId\n }"
},
"typeVersion": 2
},
{
"id": "a7d66e99-4447-4c79-8b63-660bc77c1c5c",
"name": "向财务通知自动续签合同",
"type": "n8n-nodes-base.slack",
"position": [
304,
1488
],
"webhookId": "bf20ed1a-2179-4efb-bfa2-b1a5fa585d6d",
"parameters": {
"text": "={{ $json.slack_message }}",
"select": "channel",
"channelId": {
"__rl": true,
"mode": "list",
"value": "C0989EJ7Z6K",
"cachedResultName": "automation"
},
"otherOptions": {},
"authentication": "oAuth2"
},
"credentials": {
"slackOAuth2Api": {
"id": "fDHHxMgQm69z0h5T",
"name": "Slack account"
}
},
"typeVersion": 2.3
},
{
"id": "374f879f-6f9b-46fd-a510-ce60e2c29b51",
"name": "便签说明4",
"type": "n8n-nodes-base.stickyNote",
"position": [
1264,
1616
],
"parameters": {
"width": 1484,
"height": 676,
"content": ""
},
"typeVersion": 1
},
{
"id": "9291730f-742b-4fb3-9468-94f81bc8c987",
"name": "每日调度器",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
-1232,
1648
],
"parameters": {
"rule": {
"interval": [
{
"triggerAtHour": 6
}
]
}
},
"typeVersion": 1.2
},
{
"id": "1574e09b-04a5-49b0-b1f6-d82d69ed40a5",
"name": "便签2",
"type": "n8n-nodes-base.stickyNote",
"position": [
-896,
1456
],
"parameters": {
"width": 524,
"height": 528,
"content": "## 2. 获取供应商合同列表并查找即将到期合同"
},
"typeVersion": 1
},
{
"id": "b6a74f00-3bad-484f-8b39-ab95f0601d03",
"name": "便签说明5",
"type": "n8n-nodes-base.stickyNote",
"position": [
-128,
1360
],
"parameters": {
"width": 620,
"height": 320,
"content": "## 3.1 向财务团队通知自动续签合同"
},
"typeVersion": 1
},
{
"id": "e22dffff-56ce-4c92-80a1-4ef987c24e41",
"name": "便签 6",
"type": "n8n-nodes-base.stickyNote",
"position": [
-128,
1712
],
"parameters": {
"width": 620,
"height": 496,
"content": "## 3.2 向财务团队发送手动合同延期通知"
},
"typeVersion": 1
},
{
"id": "a218ee9b-80bc-4a50-bbac-8690026f3fca",
"name": "## 为什么选择 4o 模型?👆",
"type": "n8n-nodes-base.stickyNote",
"position": [
576,
1712
],
"parameters": {
"width": 620,
"height": 496,
"content": "## 4. 向供应商发送电子邮件以启动合同延期流程"
},
"typeVersion": 1
}
],
"active": false,
"pinData": {},
"settings": {
"executionOrder": "v1"
},
"versionId": "8176c31e-1552-4674-bd0a-ec6f4aab7ea5",
"connections": {
"Daily Scheduler": {
"main": [
[
{
"node": "Get vendor contract list",
"type": "main",
"index": 0
}
]
]
},
"OpenAI Chat Model": {
"ai_languageModel": [
[
{
"node": "Vendor reminder agent",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Compose slack message": {
"main": [
[
{
"node": "Notify auto-renew contract to finance",
"type": "main",
"index": 0
}
]
]
},
"Vendor reminder agent": {
"main": [
[
{
"node": "Remind Finance Contact & Waiting For Approval",
"type": "main",
"index": 0
}
]
]
},
"Compose email template": {
"main": [
[
{
"node": "Send manual extend contract email",
"type": "main",
"index": 0
}
]
]
},
"Find expiring vendor(s)": {
"main": [
[
{
"node": "Is auto-renew contract?",
"type": "main",
"index": 0
}
]
]
},
"Is auto-renew contract?": {
"main": [
[
{
"node": "Compose slack message",
"type": "main",
"index": 0
}
],
[
{
"node": "Vendor reminder agent",
"type": "main",
"index": 0
}
]
]
},
"Get vendor contract list": {
"main": [
[
{
"node": "Find expiring vendor(s)",
"type": "main",
"index": 0
}
]
]
},
"Structured Output Parser": {
"ai_outputParser": [
[
{
"node": "Vendor reminder agent",
"type": "ai_outputParser",
"index": 0
}
]
]
},
"Send manual extend contract email": {
"main": [
[]
]
},
"Remind Finance Contact & Waiting For Approval": {
"main": [
[
{
"node": "Compose email template",
"type": "main",
"index": 0
}
]
]
}
}
}常见问题
如何使用这个工作流?
复制上方的 JSON 配置代码,在您的 n8n 实例中创建新工作流并选择「从 JSON 导入」,粘贴配置后根据需要修改凭证设置即可。
这个工作流适合什么场景?
高级 - 文档提取, 多模态 AI
需要付费吗?
本工作流完全免费,您可以直接导入使用。但请注意,工作流中使用的第三方服务(如 OpenAI API)可能需要您自行付费。
相关工作流推荐
构建用于Slack候选人评估的AI驱动聊天机器人
AI简历分析与候选人评估:Slack和Google表格集成
If
Code
Slack
+12
29 节点Trung Tran
AI 聊天机器人
智能面试助手:基于简历、职位描述和轮次的定制问题
基于简历、职位描述和轮次使用GPT-4生成定制面试问题
Set
Code
Merge
+10
26 节点Trung Tran
人力资源
HireMind – AI驱动的简历智能处理流程
HR AI简历筛选与评估:GPT-4和Google Workspace
If
Code
Slack
+10
26 节点Trung Tran
人力资源
TalentFlow AI - 批量简历筛选与职位描述匹配
使用GPT-4为HR团队进行批量简历筛选与职位描述匹配
If
Code
Merge
+12
30 节点Trung Tran
人力资源
Apollo 数据抓取与触达流程 1 ✅
使用 Apollo、AI 解析和定时邮件跟进自动生成潜在客户
If
Code
Wait
+13
39 节点Deniz
内容创作
WordPress博客自动化专业版(深度研究)v2.1市场
使用GPT-4o、Perplexity AI和多语言支持自动化SEO优化的博客创建
If
Set
Xml
+27
125 节点Daniel Ng
内容创作
工作流信息
难度等级
高级
节点数量21
分类2
节点类型10
作者
Trung Tran
@trungtranEmpowering small and medium businesses with smart automation and practical AI, no big tech team required. Reach out: lets@automatewith.me
外部链接
在 n8n.io 查看 →
分享此工作流