未出席 / 错过演示跟进
这是一个Lead Nurturing, AI Chatbot领域的自动化工作流,包含 36 个节点。主要使用 Code, Merge, Slack, Filter, Hubspot 等节点。 通过 Calendly、Zoom 和 AI 生成的跟进恢复错过的演示
- •Slack Bot Token 或 Webhook URL
- •HubSpot API Key
- •HTTP Webhook 端点(n8n 会自动生成)
- •可能需要目标 API 的认证凭证
- •OpenAI API Key
使用的节点 (36)
{
"id": "qC8SFIEjlyWY0hvC",
"meta": {
"instanceId": "42b2652ebb0a87755df4710a5630695eec8e35cb0ce04a63b0e25751b1f044f1",
"templateCredsSetupCompleted": true
},
"name": "未出席 / 错过演示跟进",
"tags": [],
"nodes": [
{
"id": "8531ef8f-43d0-452c-98ea-4645a92e7e42",
"name": "概述",
"type": "n8n-nodes-base.stickyNote",
"position": [
224,
1120
],
"parameters": {
"color": 3,
"width": 396,
"height": 356,
"content": "## 📋 工作流概述"
},
"typeVersion": 1
},
{
"id": "dbd246ba-1a3b-4a1b-b75e-80b8932dff66",
"name": "设置说明",
"type": "n8n-nodes-base.stickyNote",
"position": [
656,
944
],
"parameters": {
"color": 5,
"width": 384,
"height": 296,
"content": "## ⚙️ 一次性设置(运行一次)"
},
"typeVersion": 1
},
{
"id": "b5f882b3-e2b2-4487-a802-f4d1b2836283",
"name": "Zoom 验证指南",
"type": "n8n-nodes-base.stickyNote",
"position": [
1056,
496
],
"parameters": {
"color": 4,
"width": 420,
"height": 360,
"content": "## 🔴 关键:ZOOM 验证"
},
"typeVersion": 1
},
{
"id": "c718c4c9-7f69-4e73-9497-191bfd067fa5",
"name": "路径 1 说明",
"type": "n8n-nodes-base.stickyNote",
"position": [
656,
1248
],
"parameters": {
"color": 3,
"width": 380,
"height": 280,
"content": "## 📥 路径 1:预订跟踪"
},
"typeVersion": 1
},
{
"id": "c38cc125-7571-4a3d-9cd3-542dea207de2",
"name": "路径 2 说明",
"type": "n8n-nodes-base.stickyNote",
"position": [
656,
1536
],
"parameters": {
"color": 3,
"width": 384,
"height": 332,
"content": "## 🔍 路径 2:出席检查"
},
"typeVersion": 1
},
{
"id": "f9bd45e4-c8ad-4fd8-95a1-705a614aa6a0",
"name": "AI 配置",
"type": "n8n-nodes-base.stickyNote",
"position": [
2592,
1184
],
"parameters": {
"color": 5,
"width": 400,
"height": 336,
"content": "## 🤖 AI 个性化"
},
"typeVersion": 1
},
{
"id": "35d77e58-2101-47cc-96f2-9f4c3c605388",
"name": "跟进操作",
"type": "n8n-nodes-base.stickyNote",
"position": [
3536,
1440
],
"parameters": {
"color": 6,
"width": 420,
"height": 340,
"content": "## 📤 跟进操作"
},
"typeVersion": 1
},
{
"id": "73ed0acb-4dba-4826-8400-3d3fd59432d7",
"name": "数据库配置",
"type": "n8n-nodes-base.stickyNote",
"position": [
2176,
1184
],
"parameters": {
"color": 5,
"width": 400,
"height": 340,
"content": "## 💾 数据库设置"
},
"typeVersion": 1
},
{
"id": "a3248c16-6d27-4fd8-854f-a86171b20d90",
"name": "Zoom 认证设置",
"type": "n8n-nodes-base.stickyNote",
"position": [
1728,
1808
],
"parameters": {
"color": 4,
"width": 360,
"height": 300,
"content": "## 🔐 ZOOM OAUTH 设置"
},
"typeVersion": 1
},
{
"id": "894619ce-a0d6-4847-a836-21288a8df5d7",
"name": "设置检查清单",
"type": "n8n-nodes-base.stickyNote",
"position": [
224,
1488
],
"parameters": {
"color": 4,
"width": 400,
"height": 380,
"content": "## ⚠️ 设置检查清单"
},
"typeVersion": 1
},
{
"id": "e108da24-f19b-4417-83fd-9e83088c8b4d",
"name": "Calendly 预订 Webhook",
"type": "n8n-nodes-base.webhook",
"notes": "PATH 1: Receives booking data when a Calendly event is scheduled",
"position": [
1104,
1312
],
"webhookId": "46e46b56-06e4-4cb1-9b96-5dd9c628a2fa",
"parameters": {
"path": "cal-uri-get",
"options": {},
"httpMethod": "POST"
},
"typeVersion": 2.1
},
{
"id": "bffa0474-3d78-41e7-b1c5-93967644c0dc",
"name": "提取预订数据",
"type": "n8n-nodes-base.code",
"notes": "Parses Calendly webhook payload and extracts Zoom meeting details",
"position": [
1328,
1312
],
"parameters": {
"jsCode": "// Extract all booking data from Calendly webhook\nconst payload = $json.body.payload;\nconst scheduledEvent = payload.scheduled_event;\nconst location = scheduledEvent.location;\n\n// Extract Zoom meeting ID\nconst zoomMeetingId = location?.data?.id || null;\nconst zoomJoinUrl = location?.join_url || null;\n\nif (!zoomMeetingId) {\n throw new Error('No Zoom meeting ID found - is this a Zoom meeting?');\n}\n\nreturn [{\n json: {\n // IDs\n booking_id: payload.uri,\n meeting_id: parseInt(zoomMeetingId),\n event_type_uri: scheduledEvent.event_type,\n \n // Meeting details\n zoom_join_url: zoomJoinUrl,\n zoom_password: location?.data?.password || null,\n event_name: scheduledEvent.name,\n start_time: scheduledEvent.start_time,\n end_time: scheduledEvent.end_time,\n \n // Attendee info\n email: payload.email,\n name: payload.name,\n \n // Tracking\n status: 'pending',\n created_at: new Date().toISOString()\n }\n}];"
},
"typeVersion": 2
},
{
"id": "f2ad5409-75a3-4dc2-a439-416b01d3d62c",
"name": "筛选:仅演示事件",
"type": "n8n-nodes-base.filter",
"notes": "⚠️ CONFIGURE: Replace 'YOUR_CALENDLY_EVENT_TYPE_URI' with your specific demo event type URI from Calendly",
"position": [
1552,
1312
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 1,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "f41e5129-f6e0-414a-9e38-1735f3da3b1d",
"operator": {
"type": "string",
"operation": "contains"
},
"leftValue": "={{ $json.event_type_uri }}",
"rightValue": "YOUR_CALENDLY_EVENT_TYPE_URI"
}
]
}
},
"typeVersion": 2
},
{
"id": "3cec4aa0-a335-4dc3-85e9-dd62a336dfcc",
"name": "Zoom 会议结束 Webhook",
"type": "n8n-nodes-base.webhook",
"notes": "PATH 2: Receives webhook when Zoom meeting ends to check attendance",
"position": [
1104,
1568
],
"webhookId": "50fd0f57-cb75-4640-8b39-23c46cff060c",
"parameters": {
"path": "zoom-meeting-ended",
"options": {},
"httpMethod": "POST"
},
"typeVersion": 2.1
},
{
"id": "9934e2fc-53b5-4811-a1c7-97eaf985e6c6",
"name": "筛选:会议结束事件",
"type": "n8n-nodes-base.filter",
"notes": "Ensures we only process meeting.ended events from Zoom",
"position": [
1488,
1568
],
"parameters": {
"options": {},
"conditions": {
"string": [
{
"value1": "={{ $json.body.event }}",
"value2": "meeting.ended",
"operation": "equals"
}
]
}
},
"typeVersion": 2
},
{
"id": "16831094-cc44-490d-8747-bb5d322486fb",
"name": "从 Zoom 提取会议 ID",
"type": "n8n-nodes-base.code",
"notes": "Parses Zoom webhook to get meeting ID for lookup",
"position": [
1664,
1568
],
"parameters": {
"jsCode": "// Extract Zoom meeting ID from webhook and convert to number\nconst meetingId = parseInt($json.body?.payload?.object?.id);\n\nif (!meetingId) {\n throw new Error('No meeting ID in Zoom webhook');\n}\n\nreturn [{\n json: {\n meeting_id: meetingId,\n meeting_uuid: $json.body?.payload?.object?.uuid,\n ended_at: new Date().toISOString()\n }\n}];"
},
"typeVersion": 2
},
{
"id": "1b53510d-2ec2-4528-bf68-00be8314c828",
"name": "获取 Zoom 参与者",
"type": "n8n-nodes-base.httpRequest",
"notes": "Fetches list of participants from Zoom API to check who attended",
"position": [
2208,
1568
],
"parameters": {
"url": "=https://api.zoom.us/v2/past_meetings/{{ $json.meeting_id }}/participants",
"options": {},
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "=Bearer {{ $('Get Zoom Access Token').item.json.access_token }}"
}
]
}
},
"typeVersion": 4.1
},
{
"id": "984a024a-9421-4350-b05b-3f829dc7ebc1",
"name": "检查与会者是否出席",
"type": "n8n-nodes-base.code",
"notes": "Compares expected attendee email with actual Zoom participants",
"position": [
2384,
1568
],
"parameters": {
"jsCode": "// Check if expected attendee actually joined\nconst bookingData = $('Get Booking from Database').first().json;\nconst expectedEmail = bookingData.email.toLowerCase();\nconst participants = $json.participants || [];\n\nconst attended = participants.some(p => \n p.user_email && p.user_email.toLowerCase() === expectedEmail\n);\n\nreturn [{\n json: {\n ...bookingData,\n attended: attended,\n participant_count: participants.length,\n participants_list: participants.map(p => p.name || p.user_email).join(', ')\n }\n}];"
},
"typeVersion": 2
},
{
"id": "151f697a-1f1e-49c2-a691-01b45d1b9ddf",
"name": "AI 生成跟进消息",
"type": "@n8n/n8n-nodes-langchain.openAi",
"notes": "⚠️ CONFIGURE: Connect your OpenAI API credentials. Customize this prompt to match your brand voice and follow-up style.",
"position": [
2832,
1568
],
"parameters": {
"modelId": {
"__rl": true,
"mode": "list",
"value": "gpt-4o"
},
"options": {},
"messages": {
"values": [
{
"content": "=Generate follow-up messages for a demo no-show.\n\nContext:\n- Email: {{ $json.email }}\n- Meeting ID: {{ $json.meeting_id }}\n- Participant count: {{ $json.participant_count }}\n- Who was there: {{ $json.participants_list }}\n- Attendee status: Did not attend\n\nCreate professional, empathetic follow-up messages:\n\n1. EMAIL SUBJECT (short, friendly, non-pushy)\n2. EMAIL BODY (3-4 sentences maximum - acknowledge the miss, express understanding that things happen, offer to reschedule OR send a quick Loom recording)\n3. LINKEDIN MESSAGE (2 sentences, casual and brief)\n\nReturn ONLY valid JSON in this exact format:\n{\n \"email_subject\": \"...\",\n \"email_body\": \"...\",\n \"linkedin_message\": \"...\"\n}"
}
]
}
},
"typeVersion": 1.8
},
{
"id": "4667b279-40bd-4246-80d3-7b5d74cf639f",
"name": "发送恢复邮件",
"type": "n8n-nodes-base.emailSend",
"notes": "⚠️ CONFIGURE: Replace 'YOUR_SALES_EMAIL@company.com' with your sender email. Configure your email provider credentials. Enable this node when ready to send automated emails.",
"disabled": true,
"position": [
3344,
1392
],
"webhookId": "a7eaf7b8-4866-475a-b17a-53cc279665ff",
"parameters": {
"options": {},
"subject": "={{ $json.email_subject }}",
"toEmail": "={{ $json.email }}",
"fromEmail": "YOUR_SALES_EMAIL@company.com"
},
"typeVersion": 2.1
},
{
"id": "ec561207-12f7-4327-8e1b-fa6e191f4cc4",
"name": "在 Slack 中通知团队",
"type": "n8n-nodes-base.slack",
"notes": "⚠️ CONFIGURE: 1) Connect Slack OAuth credentials 2) Select your channel 3) Customize the message template to include info your team needs (attendee name, company, demo type, next steps, etc.)",
"position": [
3344,
1760
],
"webhookId": "f4fd4148-0618-49f0-b3c4-55eba1454b31",
"parameters": {
"text": "=🎯 *NEW DEMO NO-SHOW*\n\n📧 Email: {{ $json.email }}\n🆔 Meeting ID: {{ $json.meeting_id }}\n👥 Participants: {{ $json.participants_list }}\n📊 Total in meeting: {{ $json.participant_count }}\n\n✅ *Actions Taken:*\n- Recovery email queued\n- Database updated\n\n💬 *Suggested Follow-ups:*\n{{ $json.linkedin_message }}\n\n---\nCustomize this message template to fit your team's needs!",
"select": "channel",
"channelId": {
"__rl": true,
"mode": "list",
"value": "YOUR_SLACK_CHANNEL_ID",
"cachedResultName": "your-channel-name"
},
"otherOptions": {
"mrkdwn": true
},
"authentication": "oAuth2"
},
"typeVersion": 2.3
},
{
"id": "454864d6-90ec-4741-9f57-2cf86f0c8b33",
"name": "保存预订到数据库",
"type": "n8n-nodes-base.dataTable",
"notes": "⚠️ CONFIGURE: Create a Data Table in n8n with columns: meeting_id, email, status. Link it here.",
"position": [
1744,
1312
],
"parameters": {
"columns": {
"value": {
"email": "={{ $json.email }}",
"meeting_id": "={{ $json.meeting_id }}"
},
"schema": [
{
"id": "meeting_id",
"type": "string",
"display": true,
"removed": false,
"readOnly": false,
"required": false,
"displayName": "meeting_id",
"defaultMatch": false
},
{
"id": "email",
"type": "string",
"display": true,
"removed": false,
"readOnly": false,
"required": false,
"displayName": "email",
"defaultMatch": false
}
],
"mappingMode": "defineBelow",
"matchingColumns": [],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"dataTableId": {
"__rl": true,
"mode": "list",
"value": "YOUR_DATA_TABLE_ID",
"cachedResultUrl": "/projects/YOUR_PROJECT_ID/datatables/YOUR_DATA_TABLE_ID",
"cachedResultName": "Calendly Events"
}
},
"typeVersion": 1
},
{
"id": "32d50735-236a-4f69-b5a9-39d772d46965",
"name": "从数据库获取预订",
"type": "n8n-nodes-base.dataTable",
"notes": "Retrieves the original booking details using Zoom meeting ID",
"position": [
1856,
1648
],
"parameters": {
"filters": {
"conditions": [
{
"keyName": "meeting_id",
"keyValue": "={{ $json.meeting_id }}"
}
]
},
"matchType": "allConditions",
"operation": "get",
"dataTableId": {
"__rl": true,
"mode": "list",
"value": "YOUR_DATA_TABLE_ID",
"cachedResultUrl": "/projects/YOUR_PROJECT_ID/datatables/YOUR_DATA_TABLE_ID",
"cachedResultName": "Calendly Events"
}
},
"typeVersion": 1
},
{
"id": "9a42b893-b4c0-4eaf-ad40-b3adf4799661",
"name": "获取 Zoom 访问令牌",
"type": "n8n-nodes-base.httpRequest",
"notes": "⚠️ CONFIGURE: Replace with your Zoom Server-to-Server OAuth credentials (Account ID, Client ID, Client Secret). Get these from your Zoom App in the Zoom Marketplace.",
"position": [
1856,
1488
],
"parameters": {
"url": "https://zoom.us/oauth/token",
"method": "POST",
"options": {},
"sendBody": true,
"contentType": "form-urlencoded",
"bodyParameters": {
"parameters": [
{
"name": "grant_type",
"value": "account_credentials"
},
{
"name": "account_id",
"value": "YOUR_ZOOM_ACCOUNT_ID"
},
{
"name": "client_id",
"value": "YOUR_ZOOM_CLIENT_ID"
},
{
"name": "client_secret",
"value": "YOUR_ZOOM_CLIENT_SECRET"
}
]
}
},
"typeVersion": 4.2
},
{
"id": "40feb37d-85bb-4c18-9435-30d108b359e6",
"name": "合并访问令牌与预订数据",
"type": "n8n-nodes-base.merge",
"notes": "Combines Zoom access token with meeting data for API call",
"position": [
2048,
1568
],
"parameters": {
"mode": "combine",
"options": {},
"combineBy": "combineByPosition"
},
"typeVersion": 3.2
},
{
"id": "4d9ecb8a-a6c7-4f54-ae84-f3dd981ae9ff",
"name": "更新出席状态",
"type": "n8n-nodes-base.dataTable",
"notes": "Updates database with attendance status (true/false)",
"position": [
2640,
1728
],
"parameters": {
"columns": {
"value": {
"email": "={{ $json.email}}",
"status": "={{ $json.attended }}",
"meeting_id": "={{ $json.meeting_id }}"
},
"schema": [
{
"id": "meeting_id",
"type": "string",
"display": true,
"removed": false,
"readOnly": false,
"required": false,
"displayName": "meeting_id",
"defaultMatch": false
},
{
"id": "email",
"type": "string",
"display": true,
"removed": false,
"readOnly": false,
"required": false,
"displayName": "email",
"defaultMatch": false
},
{
"id": "status",
"type": "string",
"display": true,
"removed": false,
"readOnly": false,
"required": false,
"displayName": "status",
"defaultMatch": false
}
],
"mappingMode": "defineBelow",
"matchingColumns": [],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"filters": {
"conditions": [
{
"keyName": "meeting_id",
"keyValue": "={{ $json.meeting_id }}"
}
]
},
"options": {},
"operation": "update",
"dataTableId": {
"__rl": true,
"mode": "list",
"value": "YOUR_DATA_TABLE_ID",
"cachedResultUrl": "/projects/YOUR_PROJECT_ID/datatables/YOUR_DATA_TABLE_ID",
"cachedResultName": "Calendly Events"
}
},
"typeVersion": 1
},
{
"id": "49e2fe76-6b3b-4d73-895e-fadcbb515c45",
"name": "更新 CRM 交易(可选)",
"type": "n8n-nodes-base.hubspot",
"notes": "⚠️ OPTIONAL: Enable and configure this to update HubSpot (or your CRM) deals when someone no-shows. Map the deal ID and fields you want to update.",
"disabled": true,
"position": [
3344,
1568
],
"parameters": {
"dealId": {
"__rl": true,
"mode": "list",
"value": ""
},
"resource": "deal",
"operation": "update",
"updateFields": {}
},
"typeVersion": 2.2
},
{
"id": "a993d193-02c7-4c15-bf85-49ac4ce3132a",
"name": "手动设置触发器",
"type": "n8n-nodes-base.manualTrigger",
"notes": "SETUP PATH: Run this once to create Calendly webhook subscription",
"position": [
1104,
1088
],
"parameters": {},
"typeVersion": 1
},
{
"id": "33dbaafd-198b-4533-82f0-54920bac9f08",
"name": "获取 Calendly 组织",
"type": "n8n-nodes-base.httpRequest",
"notes": "⚠️ CONFIGURE: Replace 'YOUR_CALENDLY_API_TOKEN' with your Calendly Personal Access Token from https://calendly.com/integrations/api_webhooks",
"position": [
1328,
1088
],
"parameters": {
"url": "https://api.calendly.com/users/me",
"options": {},
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "Bearer YOUR_TOKEN_HERE"
}
]
}
},
"typeVersion": 4.1
},
{
"id": "1cfed318-50e7-4bed-b894-3ef5a7760360",
"name": "提取组织 URI",
"type": "n8n-nodes-base.code",
"notes": "Parses Calendly response to get your organization URI",
"position": [
1552,
1088
],
"parameters": {
"jsCode": "// Extract organization URI\nconst response = $input.first().json;\nconst orgUri = response.resource.current_organization;\n\nif (!orgUri) {\n throw new Error('No organization found. You might be on a personal account.');\n}\n\nconsole.log('✅ Your Organization URI:', orgUri);\n\nreturn [{\n json: {\n organization_uri: orgUri,\n user_uri: response.resource.uri,\n user_name: response.resource.name,\n user_email: response.resource.email\n }\n}];"
},
"typeVersion": 2
},
{
"id": "7c50f2e3-7f00-4cac-a890-61df07e935ef",
"name": "创建 Calendly Webhook",
"type": "n8n-nodes-base.httpRequest",
"notes": "⚠️ CONFIGURE: Replace 'YOUR_N8N_WEBHOOK_URL' with your n8n instance URL and 'YOUR_CALENDLY_API_TOKEN' with your Calendly token",
"position": [
1776,
1088
],
"parameters": {
"url": "https://api.calendly.com/webhook_subscriptions",
"method": "POST",
"options": {},
"jsonBody": "={\n \"url\": \"YOUR_N8N_WEBHOOK_URL/webhook/cal-uri-get\",\n \"events\": [\"invitee.created\"],\n \"organization\": \"{{ $json.organization_uri }}\",\n \"scope\": \"organization\",\n \"signing_key\": \"your_optional_secret_key\"\n}",
"sendBody": true,
"sendHeaders": true,
"specifyBody": "json",
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "Bearer YOUR_TOKEN_HERE"
},
{
"name": "Content-Type",
"value": "application/json"
}
]
}
},
"typeVersion": 4.1
},
{
"id": "7b694aed-9d5c-4321-90be-84d05cb33c25",
"name": "显示设置成功",
"type": "n8n-nodes-base.code",
"position": [
1984,
1088
],
"parameters": {
"jsCode": "// Parse webhook creation response\nconst response = $input.first().json;\n\nif (response.resource) {\n console.log('✅ WEBHOOK CREATED SUCCESSFULLY!');\n console.log('Webhook URI:', response.resource.uri);\n console.log('Webhook URL:', response.resource.url);\n console.log('Events:', response.resource.events);\n console.log('State:', response.resource.state);\n \n return [{\n json: {\n success: true,\n webhook_uri: response.resource.uri,\n webhook_url: response.resource.url,\n events: response.resource.events,\n state: response.resource.state,\n message: '✅ Webhook subscription created! Calendly will now POST to your n8n webhook when bookings happen.'\n }\n }];\n} else {\n throw new Error('Webhook creation failed: ' + JSON.stringify(response));\n}"
},
"typeVersion": 2
},
{
"id": "171e6449-1352-467b-8392-dbccf290c867",
"name": "Zoom Webhook 验证器",
"type": "n8n-nodes-base.code",
"notes": "⚠️ CONFIGURE: Replace 'YOUR_ZOOM_WEBHOOK_SECRET' with the secret token from your Zoom app's Feature page",
"position": [
1328,
896
],
"parameters": {
"jsCode": "const crypto = require('crypto');\n\n// Your Zoom webhook secret token\nconst ZOOM_WEBHOOK_SECRET = 'YOUR_ZOOM_WEBHOOK_SECRET';\n\nconst body = $json.body;\n\n// Check if this is a validation request\nif (body?.event === 'endpoint.url_validation') {\n const plainToken = body.payload.plainToken;\n \n // Hash the plainToken using HMAC SHA-256\n const encryptedToken = crypto\n .createHmac('sha256', ZOOM_WEBHOOK_SECRET)\n .update(plainToken)\n .digest('hex');\n \n return [{\n plainToken: plainToken,\n encryptedToken: encryptedToken\n }];\n}\n\n// For normal webhook events, pass through\nreturn [$json];"
},
"typeVersion": 2
},
{
"id": "fbb4c54e-4fb6-41cc-98b8-8f5944cb508c",
"name": "向 Zoom 发送验证响应",
"type": "n8n-nodes-base.respondToWebhook",
"notes": "Responds to Zoom's validation challenge with encrypted token",
"position": [
1520,
896
],
"parameters": {
"options": {
"responseCode": 200,
"responseHeaders": {
"entries": [
{
"name": "Content-Type",
"value": "application/json"
}
]
}
}
},
"typeVersion": 1.4
},
{
"id": "33cf8321-30bb-49d6-bdd1-3463cb8ae23c",
"name": "筛选:仅未出席",
"type": "n8n-nodes-base.filter",
"notes": "Only processes meetings where attendee did NOT show up (attended = false)",
"position": [
2624,
1568
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "356a49d4-56b0-43f3-b640-f6e1c2f2b165",
"operator": {
"type": "boolean",
"operation": "false",
"singleValue": true
},
"leftValue": "={{ $json.attended }}",
"rightValue": "0"
}
]
}
},
"typeVersion": 2.2
},
{
"id": "a367fc8c-3e58-4c9e-b5b0-0e12786e9987",
"name": "Zoom 验证 Webhook(重复)",
"type": "n8n-nodes-base.webhook",
"notes": "DISABLED: This is a duplicate for validation testing. Delete after Zoom webhook is validated.",
"disabled": true,
"position": [
1104,
896
],
"webhookId": "50fd0f57-cb75-4640-8b39-23c46cff060c",
"parameters": {
"path": "zoom-meeting-ended",
"options": {},
"httpMethod": "POST",
"responseMode": "responseNode"
},
"typeVersion": 2.1
}
],
"active": false,
"pinData": {},
"settings": {
"executionOrder": "v1"
},
"versionId": "0bff6195-14a8-43cf-9d02-871cf8944ab3",
"connections": {
"Extract Booking Data": {
"main": [
[
{
"node": "Filter: Demo Events Only",
"type": "main",
"index": 0
}
]
]
},
"Manual Setup Trigger": {
"main": [
[
{
"node": "Get Calendly Organization",
"type": "main",
"index": 0
}
]
]
},
"Filter: No-Shows Only": {
"main": [
[
{
"node": "AI Generate Follow-Up Messages",
"type": "main",
"index": 0
}
]
]
},
"Get Zoom Access Token": {
"main": [
[
{
"node": "Merge Access Token with Booking Data",
"type": "main",
"index": 0
}
]
]
},
"Get Zoom Participants": {
"main": [
[
{
"node": "Check if Attendee Showed Up",
"type": "main",
"index": 0
}
]
]
},
"Zoom Webhook Validator": {
"main": [
[
{
"node": "Send Validation Response to Zoom",
"type": "main",
"index": 0
}
]
]
},
"Create Calendly Webhook": {
"main": [
[
{
"node": "Show Setup Success",
"type": "main",
"index": 0
}
]
]
},
"Calendly Booking Webhook": {
"main": [
[
{
"node": "Extract Booking Data",
"type": "main",
"index": 0
}
]
]
},
"Extract Organization URI": {
"main": [
[
{
"node": "Create Calendly Webhook",
"type": "main",
"index": 0
}
]
]
},
"Filter: Demo Events Only": {
"main": [
[
{
"node": "Save Booking to Database",
"type": "main",
"index": 0
}
]
]
},
"Get Booking from Database": {
"main": [
[
{
"node": "Merge Access Token with Booking Data",
"type": "main",
"index": 1
}
]
]
},
"Get Calendly Organization": {
"main": [
[
{
"node": "Extract Organization URI",
"type": "main",
"index": 0
}
]
]
},
"Zoom Meeting Ended Webhook": {
"main": [
[
{
"node": "Filter: Meeting Ended Events",
"type": "main",
"index": 0
}
]
]
},
"Check if Attendee Showed Up": {
"main": [
[
{
"node": "Update Attendance Status",
"type": "main",
"index": 0
},
{
"node": "Filter: No-Shows Only",
"type": "main",
"index": 0
}
]
]
},
"Extract Meeting ID from Zoom": {
"main": [
[
{
"node": "Get Zoom Access Token",
"type": "main",
"index": 0
},
{
"node": "Get Booking from Database",
"type": "main",
"index": 0
}
]
]
},
"Filter: Meeting Ended Events": {
"main": [
[
{
"node": "Extract Meeting ID from Zoom",
"type": "main",
"index": 0
}
]
]
},
"AI Generate Follow-Up Messages": {
"main": [
[
{
"node": "Notify Team in Slack",
"type": "main",
"index": 0
},
{
"node": "Update CRM Deal (Optional)",
"type": "main",
"index": 0
},
{
"node": "Send Recovery Email",
"type": "main",
"index": 0
}
]
]
},
"Zoom Validation Webhook (Duplicate)": {
"main": [
[
{
"node": "Zoom Webhook Validator",
"type": "main",
"index": 0
}
]
]
},
"Merge Access Token with Booking Data": {
"main": [
[
{
"node": "Get Zoom Participants",
"type": "main",
"index": 0
}
]
]
}
}
}如何使用这个工作流?
复制上方的 JSON 配置代码,在您的 n8n 实例中创建新工作流并选择「从 JSON 导入」,粘贴配置后根据需要修改凭证设置即可。
这个工作流适合什么场景?
高级 - 客户培育, AI 聊天机器人
需要付费吗?
本工作流完全免费,您可以直接导入使用。但请注意,工作流中使用的第三方服务(如 OpenAI API)可能需要您自行付费。
相关工作流推荐
Connor Provines
@connorprovinesOver the past 10+ years, I've led marketing initiatives for B2B SaaS companies at every stage, from initial market entry (0→1) through scaled growth (1→10). My approach is grounded in a simple principle: strategic thinking paired with hands-on execution. I focus on building sustainable growth engines, not just campaigns. Whether it's positioning a new product, optimizing conversion funnels, or scaling demand generation, I bring both the framework and the tactical expertise to move fast and win.
分享此工作流