GPT-4o:Twilio集成与自动跟进功能
高级
这是一个Content Creation、Multimodal AI领域的自动化工作流,包含 21 个节点。主要使用 If、Code、Wait、Merge、Slack 等节点。 GPT-4o:Twilio集成与自动跟进功能
前置要求
- •Slack Bot Token 或 Webhook URL
- •Airtable API Key
- •可能需要目标 API 的认证凭证
- •OpenAI API Key
使用的节点 (21 个)
工作流预览
可视化展示节点连接关系,支持缩放和平移
导出工作流
复制以下 JSON 配置到 n8n 导入,即可使用此工作流
{
"meta": {
"instanceId": "d23ca638a83fba54c06ee57ee6430730afe25e4177b234d2a702bd83cbe8f349"
},
"nodes": [
{
"id": "5f0e216a-ea69-4674-af22-3fe170cbd766",
"name": "合并结果",
"type": "n8n-nodes-base.merge",
"position": [
22416,
16208
],
"parameters": {},
"typeVersion": 3
},
{
"id": "b7116aa4-8d06-4ff4-8d74-da1b030a62f2",
"name": "跟踪结果",
"type": "n8n-nodes-base.code",
"position": [
22640,
16208
],
"parameters": {
"jsCode": "// Track which channels were used\nconst items = $input.all();\n\n// Check if SMS was sent (will have twilio response)\nconst smsSent = items.some(item => item.json.sid || item.json.messageSid);\n\n// Check if Email was sent (will have email response)\nconst emailSent = items.some(item => item.json.accepted || item.json.messageId);\n\n// Get customer data from Prepare Messages node\nconst customerData = $('Prepare Messages2').first().json;\n\nreturn {\n json: {\n ...customerData,\n sms_sent: smsSent,\n email_sent: emailSent,\n messages_sent_at: new Date().toISOString()\n }\n};"
},
"typeVersion": 2
},
{
"id": "58a9ef5a-8fb0-4781-8eb0-b4dd3eeb6ad0",
"name": "便签9",
"type": "n8n-nodes-base.stickyNote",
"position": [
19280,
15872
],
"parameters": {
"width": 928,
"height": 1392,
"content": "## 📞 未接来电收入挽回机器人"
},
"typeVersion": 1
},
{
"id": "f62d032e-17c4-498c-988a-434e2288a21c",
"name": "检测到未接来电2",
"type": "n8n-nodes-base.twilioTrigger",
"position": [
20352,
16208
],
"webhookId": "twilio-missed-call",
"parameters": {
"updates": [
"com.twilio.voice.insights.call-summary.complete"
]
},
"credentials": {
"twilioApi": {
"id": "vDXzBZzToDaIu6Nn",
"name": "Twilio account"
}
},
"typeVersion": 1
},
{
"id": "fe521a57-2f91-45f5-a09d-efd7fd3cae9f",
"name": "分析通话上下文2",
"type": "n8n-nodes-base.code",
"position": [
20576,
16208
],
"parameters": {
"jsCode": "// Extract and analyze call data\nconst callData = $input.first().json;\n\n// Twilio Call Status values:\n// 'completed' = answered and ended normally\n// 'no-answer' = no answer or rejected\n// 'busy' = busy signal\n// 'canceled' = hung up while queued/ringing\n// 'failed' = invalid number or error\n\n// Check if call was answered (CallDuration > 0 means conversation happened)\nconst callDuration = parseInt(callData.CallDuration) || 0;\nconst callStatus = callData.CallStatus || '';\n\n// Skip answered calls (completed with duration > 0)\nconst wasAnswered = callStatus === 'completed' && callDuration > 0;\n\nif (wasAnswered) {\n return []; // Don't process answered calls\n}\n\n// Extract caller information (handle both camelCase and PascalCase)\nconst callerNumber = callData.From || callData.from || '';\nconst receiverNumber = callData.To || callData.to || '';\nconst timestamp = callData.Timestamp || callData.timestamp || new Date().toISOString();\nconst callTime = new Date(timestamp);\nconst currentHour = callTime.getHours();\n\n// Determine business context\nconst isBusinessHours = currentHour >= 9 && currentHour < 17;\nconst dayOfWeek = callTime.getDay();\nconst isWeekend = dayOfWeek === 0 || dayOfWeek === 6;\n\nreturn {\n json: {\n caller_number: callerNumber,\n receiver_number: receiverNumber,\n call_time: callTime.toISOString(),\n call_time_local: callTime.toLocaleString(),\n call_status: callStatus,\n call_duration: callDuration,\n is_business_hours: isBusinessHours,\n is_weekend: isWeekend,\n call_sid: callData.CallSid || callData.callSid || '',\n urgency_score: !isBusinessHours ? 8 : 5, // Higher urgency for after-hours calls\n context: {\n time_of_day: currentHour < 12 ? 'morning' : currentHour < 17 ? 'afternoon' : 'evening',\n day_type: isWeekend ? 'weekend' : 'weekday'\n }\n }\n};"
},
"typeVersion": 2
},
{
"id": "e7a1c806-c63b-45f8-8bf5-51ffc12486d0",
"name": "检查现有联系人2",
"type": "n8n-nodes-base.httpRequest",
"position": [
20800,
16208
],
"parameters": {
"url": "=https://your-crm-api.com/contacts/search?phone={{ $json.caller_number }}",
"options": {
"response": {
"response": {
"neverError": true
}
}
},
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth"
},
"typeVersion": 4.1
},
{
"id": "10faf764-b0e6-486b-92c7-8b08663af3ed",
"name": "合并客户数据2",
"type": "n8n-nodes-base.code",
"position": [
21024,
16208
],
"parameters": {
"jsCode": "// Merge call data with CRM history\nconst callData = $('Analyze Call Context2').first().json;\nconst crmData = $input.first().json;\n\nconst hasHistory = crmData && crmData.contact;\nconst contact = crmData?.contact || {};\n\nreturn {\n json: {\n ...callData,\n \n // CRM Information\n is_existing_customer: hasHistory,\n customer_name: contact.name || 'Unknown',\n customer_email: contact.email || null,\n last_contact_date: contact.last_contact || null,\n customer_status: contact.status || 'new',\n previous_purchases: contact.purchase_count || 0,\n lifetime_value: contact.lifetime_value || 0,\n notes: contact.notes || '',\n \n // Prioritization\n priority_level: hasHistory && contact.lifetime_value > 1000 ? 'high' : hasHistory ? 'medium' : 'new',\n follow_up_urgency: hasHistory ? 'immediate' : 'standard'\n }\n};"
},
"typeVersion": 2
},
{
"id": "be1b553a-725b-4a80-b901-1d469794bdaa",
"name": "生成AI响应2",
"type": "@n8n/n8n-nodes-langchain.chainLlm",
"position": [
21280,
16208
],
"parameters": {
"text": "=Generate a personalized missed call response for the following situation:\n\nCustomer Information:\n- Name: {{ $json.customer_name }}\n- Status: {{ $json.is_existing_customer ? 'Existing Customer' : 'New Prospect' }}\n- Priority: {{ $json.priority_level }}\n- Previous Purchases: {{ $json.previous_purchases }}\n\nCall Context:\n- Time: {{ $json.context.time_of_day }} on a {{ $json.context.day_type }}\n- Business Hours: {{ $json.is_business_hours ? 'Yes' : 'No (After Hours)' }}\n- Phone: {{ $json.caller_number }}\n\nCreate TWO versions:\n\n1. SMS_MESSAGE (160 chars max): Friendly, apologetic, includes booking link placeholder\n2. EMAIL_MESSAGE (200 words): Professional, personalized, multiple contact options\n\nReturn JSON with:\n- sms: Brief apologetic message\n- email_subject: Personalized subject line\n- email_body: Professional email with [BOOKING_LINK] placeholder\n- tone: warm/professional/urgent\n- recommended_channel: sms/email/both\n\nTone should be:\n- Warm and apologetic\n- Acknowledge their attempt to reach us\n- Offer immediate booking option\n- Personalize based on customer status",
"promptType": "define",
"hasOutputParser": true
},
"typeVersion": 1.4
},
{
"id": "27649586-1171-4e61-8cf7-d1239ab8ce89",
"name": "OpenAI聊天模型8",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
"position": [
21248,
16432
],
"parameters": {
"model": "gpt-4o",
"options": {
"maxTokens": 500,
"temperature": 0.7
}
},
"typeVersion": 1
},
{
"id": "d4e13bed-0f1b-41ea-a450-81b4e9ac5550",
"name": "结构化输出解析器8",
"type": "@n8n/n8n-nodes-langchain.outputParserStructured",
"position": [
21376,
16432
],
"parameters": {
"autoFix": true,
"schemaType": "manual",
"inputSchema": "{\n \"type\": \"object\",\n \"properties\": {\n \"sms\": {\n \"type\": \"string\",\n \"description\": \"SMS message (160 chars max)\"\n },\n \"email_subject\": {\n \"type\": \"string\",\n \"description\": \"Email subject line\"\n },\n \"email_body\": {\n \"type\": \"string\",\n \"description\": \"Email body with [BOOKING_LINK] placeholder\"\n },\n \"tone\": {\n \"type\": \"string\",\n \"enum\": [\"warm\", \"professional\", \"urgent\"],\n \"description\": \"Message tone\"\n },\n \"recommended_channel\": {\n \"type\": \"string\",\n \"enum\": [\"sms\", \"email\", \"both\"],\n \"description\": \"Recommended communication channel\"\n }\n },\n \"required\": [\"sms\", \"email_subject\", \"email_body\", \"tone\", \"recommended_channel\"]\n}"
},
"typeVersion": 1.3
},
{
"id": "e16ca74e-3796-4f9f-8279-5aab98395133",
"name": "准备消息2",
"type": "n8n-nodes-base.code",
"position": [
21744,
16208
],
"parameters": {
"jsCode": "// Parse AI response and prepare messages\nconst aiResponse = $input.first().json;\nconst customerData = $('Merge Customer Data2').first().json;\n\n// Generate booking link (Cal.com or Calendly)\nconst bookingUrl = 'https://cal.com/your-business'; // Replace with your booking link\nconst bookingLink = `${bookingUrl}?name=${encodeURIComponent(customerData.customer_name)}&phone=${encodeURIComponent(customerData.caller_number)}`;\n\n// Add booking link to messages\nconst smsWithLink = `${aiResponse.sms}\\n\\nBook instantly: ${bookingLink}`;\nconst emailWithLink = aiResponse.email_body.replace('[BOOKING_LINK]', bookingLink);\n\nreturn {\n json: {\n ...customerData,\n \n // AI-generated messages\n sms_message: smsWithLink,\n email_subject: aiResponse.email_subject,\n email_body: emailWithLink,\n message_tone: aiResponse.tone,\n recommended_channel: aiResponse.recommended_channel,\n \n // Booking information\n booking_link: bookingLink,\n \n // Metadata\n response_generated_at: new Date().toISOString()\n }\n};"
},
"typeVersion": 2
},
{
"id": "10884b30-701c-4c5f-8d92-abc00f9228a8",
"name": "发送短信?2",
"type": "n8n-nodes-base.if",
"position": [
21968,
16112
],
"parameters": {
"options": {},
"conditions": {
"options": {
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "or",
"conditions": [
{
"id": "sms-channel",
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.recommended_channel }}",
"rightValue": "sms"
},
{
"id": "both-channels",
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.recommended_channel }}",
"rightValue": "both"
}
]
}
},
"typeVersion": 2
},
{
"id": "52dce42a-1e0b-4389-bd9a-422b3dc04cba",
"name": "发送短信2",
"type": "n8n-nodes-base.twilio",
"position": [
22192,
16112
],
"parameters": {
"to": "={{ $json.caller_number }}",
"from": "+15551234567",
"message": "={{ $json.sms_message }}",
"options": {}
},
"typeVersion": 1
},
{
"id": "5c68f5ef-2058-4d58-a257-b6779488f3cb",
"name": "发送邮件?2",
"type": "n8n-nodes-base.if",
"position": [
21968,
16304
],
"parameters": {
"options": {},
"conditions": {
"options": {
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "has-email",
"operator": {
"type": "string",
"operation": "notEmpty"
},
"leftValue": "={{ $json.customer_email }}",
"rightValue": ""
},
{
"id": "email-channel",
"operator": {
"type": "string",
"operation": "contains"
},
"leftValue": "={{ $json.recommended_channel }}",
"rightValue": "email"
}
]
}
},
"typeVersion": 2
},
{
"id": "a76db0f7-5e55-4be4-947f-dc9921779442",
"name": "发送邮件2",
"type": "n8n-nodes-base.emailSend",
"position": [
22192,
16304
],
"webhookId": "b3c6d8bc-0f42-4cbe-a05c-1d026f0d1c63",
"parameters": {
"options": {},
"subject": "={{ $json.email_subject }}",
"toEmail": "={{ $json.customer_email }}",
"fromEmail": "your-business@example.com"
},
"credentials": {
"smtp": {
"id": "qmhzTud0RSbKigGt",
"name": "SMTP account"
}
},
"typeVersion": 2.1
},
{
"id": "1ca48805-f52b-4e18-93f1-c79290d328a3",
"name": "记录到CRM2",
"type": "n8n-nodes-base.airtable",
"position": [
22864,
16208
],
"parameters": {
"base": {
"__rl": true,
"mode": "id",
"value": "REPLACE_WITH_AIRTABLE_BASE_ID"
},
"table": {
"__rl": true,
"mode": "id",
"value": "REPLACE_WITH_AIRTABLE_TABLE_ID"
},
"columns": {
"value": {
"Status": "Pending Response",
"Priority": "={{ $json.priority_level }}",
"SMS_Sent": "={{ $json.sms_sent ? 'Yes' : 'No' }}",
"Call_Time": "={{ $json.call_time }}",
"Email_Sent": "={{ $json.email_sent ? 'Yes' : 'No' }}",
"Booking_Link": "={{ $json.booking_link }}",
"Caller_Number": "={{ $json.caller_number }}",
"Customer_Name": "={{ $json.customer_name }}",
"Urgency_Score": "={{ $json.urgency_score }}",
"Follow_Up_Date": "={{ new Date(Date.now() + 86400000).toISOString() }}"
},
"mappingMode": "defineBelow"
},
"options": {},
"operation": "upsert"
},
"typeVersion": 2
},
{
"id": "da785def-5222-4e81-a0ed-8b9ef698732d",
"name": "通知销售团队3",
"type": "n8n-nodes-base.slack",
"position": [
23088,
16208
],
"webhookId": "3ad339ab-392a-44ad-b967-aa02e04de2af",
"parameters": {
"text": "=📞 *Missed Call Alert*\n\n*Customer:* {{ $json.customer_name }}{{ $json.is_existing_customer ? ' (Existing Customer 🌟)' : ' (New Prospect)' }}\n*Phone:* {{ $json.caller_number }}\n*Time:* {{ $json.call_time_local }}\n*Priority:* {{ $json.priority_level.toUpperCase() }}\n\n*Context:*\n• Call during: {{ $json.is_business_hours ? 'Business Hours' : 'After Hours ⚠️' }}\n• Customer Status: {{ $json.customer_status }}\n{{ $json.previous_purchases > 0 ? '• Previous Purchases: ' + $json.previous_purchases : '' }}\n{{ $json.lifetime_value > 0 ? '• Lifetime Value: $' + $json.lifetime_value : '' }}\n\n*Auto-Response Sent:*\n{{ $json.sms_sent ? '✅ SMS' : '❌ SMS' }} | {{ $json.email_sent ? '✅ Email' : '❌ Email' }}\n\n*Booking Link:* {{ $json.booking_link }}\n\n🎯 *Action Required:* {{ $json.follow_up_urgency === 'immediate' ? 'Call back ASAP!' : 'Follow up within 24 hours' }}",
"select": "channel",
"channelId": {
"__rl": true,
"mode": "id",
"value": "REPLACE_WITH_SLACK_SALES_CHANNEL_ID"
},
"otherOptions": {
"includeLinkToWorkflow": false
}
},
"typeVersion": 2.1
},
{
"id": "a162a326-8ad2-499a-b6a1-5d004683570f",
"name": "等待24小时2",
"type": "n8n-nodes-base.wait",
"position": [
23312,
16208
],
"webhookId": "8c3d23ad-f82f-4e2f-b4af-fb1b19e5b790",
"parameters": {
"unit": "hours",
"amount": 24
},
"typeVersion": 1.1
},
{
"id": "ed555f98-119d-4d52-822f-88730c1324e8",
"name": "检查是否已预订2",
"type": "n8n-nodes-base.httpRequest",
"position": [
23536,
16208
],
"parameters": {
"url": "=https://your-crm-api.com/contacts/{{ $json.caller_number }}/bookings",
"options": {
"response": {
"response": {
"neverError": true
}
}
},
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth"
},
"credentials": {
"httpHeaderAuth": {
"id": "exVxOWDpxBu7XVql",
"name": "nithichote.com header auth key"
}
},
"typeVersion": 4.1
},
{
"id": "0433e538-eef4-48d8-9511-668bfe41fc27",
"name": "无响应?2",
"type": "n8n-nodes-base.if",
"position": [
23760,
16208
],
"parameters": {
"options": {},
"conditions": {
"options": {
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "no-booking",
"operator": {
"type": "number",
"operation": "equals"
},
"leftValue": "={{ $json.booking_count || 0 }}",
"rightValue": 0
}
]
}
},
"typeVersion": 2
},
{
"id": "5a1e4e37-abf8-4979-b90b-7ba2da1f05e7",
"name": "发送跟进短信2",
"type": "n8n-nodes-base.twilio",
"position": [
23984,
16208
],
"parameters": {
"to": "={{ $json.caller_number }}",
"from": "+15551234567",
"message": "=Hi {{ $json.customer_name }},\n\nWe tried reaching you yesterday. Still interested in scheduling?\n\nBook now: {{ $json.booking_link }}\n\nOr call us: +1-555-0100\n\nThanks!\nYour Business Name",
"options": {}
},
"typeVersion": 1
}
],
"pinData": {},
"connections": {
"Send SMS2": {
"main": [
[
{
"node": "Merge Results",
"type": "main",
"index": 0
}
]
]
},
"Send SMS?2": {
"main": [
[
{
"node": "Send SMS2",
"type": "main",
"index": 0
}
]
]
},
"Log to CRM2": {
"main": [
[
{
"node": "Notify Sales Team3",
"type": "main",
"index": 0
}
]
]
},
"Send Email2": {
"main": [
[
{
"node": "Merge Results",
"type": "main",
"index": 1
}
]
]
},
"Send Email?2": {
"main": [
[
{
"node": "Send Email2",
"type": "main",
"index": 0
}
]
]
},
"Merge Results": {
"main": [
[
{
"node": "Track Results",
"type": "main",
"index": 0
}
]
]
},
"No Response?2": {
"main": [
[
{
"node": "Send Follow-up SMS2",
"type": "main",
"index": 0
}
]
]
},
"Track Results": {
"main": [
[
{
"node": "Log to CRM2",
"type": "main",
"index": 0
}
]
]
},
"Wait 24 Hours2": {
"main": [
[
{
"node": "Check if Booked2",
"type": "main",
"index": 0
}
]
]
},
"Check if Booked2": {
"main": [
[
{
"node": "No Response?2",
"type": "main",
"index": 0
}
]
]
},
"Prepare Messages2": {
"main": [
[
{
"node": "Send SMS?2",
"type": "main",
"index": 0
},
{
"node": "Send Email?2",
"type": "main",
"index": 0
}
]
]
},
"Notify Sales Team3": {
"main": [
[
{
"node": "Wait 24 Hours2",
"type": "main",
"index": 0
}
]
]
},
"OpenAI Chat Model8": {
"ai_languageModel": [
[
{
"node": "Generate AI Response2",
"type": "ai_languageModel",
"index": 0
},
{
"node": "Structured Output Parser8",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Merge Customer Data2": {
"main": [
[
{
"node": "Generate AI Response2",
"type": "main",
"index": 0
}
]
]
},
"Analyze Call Context2": {
"main": [
[
{
"node": "Check Existing Contact2",
"type": "main",
"index": 0
}
]
]
},
"Generate AI Response2": {
"main": [
[
{
"node": "Prepare Messages2",
"type": "main",
"index": 0
}
]
]
},
"Missed Call Detected2": {
"main": [
[
{
"node": "Analyze Call Context2",
"type": "main",
"index": 0
}
]
]
},
"Check Existing Contact2": {
"main": [
[
{
"node": "Merge Customer Data2",
"type": "main",
"index": 0
}
]
]
},
"Structured Output Parser8": {
"ai_outputParser": [
[
{
"node": "Generate AI Response2",
"type": "ai_outputParser",
"index": 0
}
]
]
}
}
}常见问题
如何使用这个工作流?
复制上方的 JSON 配置代码,在您的 n8n 实例中创建新工作流并选择「从 JSON 导入」,粘贴配置后根据需要修改凭证设置即可。
这个工作流适合什么场景?
这是一个高级难度的工作流,适用于Content Creation、Multimodal AI等场景。适合高级用户,包含 16+ 个节点的复杂工作流
需要付费吗?
本工作流完全免费,您可以直接导入使用。但请注意,工作流中使用的第三方服务(如 OpenAI API)可能需要您自行付费。
相关工作流推荐
使用 GPT-4o、Clearbit、HubSpot CRM 和 Slack 提醒筛选和路由潜在客户
使用 GPT-4o、Clearbit、HubSpot CRM 和 Slack 提醒筛选和路由潜在客户
If
Code
Slack
+10
18 节点Greypillar
Content Creation
博客文章转换为多平台内容(GPT-4o、Unsplash 和 Airtable)
使用 GPT-4o、Unsplash 和 Airtable 将博客文章转换为多平台内容
Code
Slack
Twitter
+8
14 节点Greypillar
Content Creation
AIAuto - 带深度研究的终极人机回环内容v2
WordPress博客自动化,集成Airtable界面、人工审核和AI研究v2
If
Set
Xml
+23
228 节点Daniel Ng
Content Creation
WordPress博客自动化专业版(深度研究)v2.1市场
使用GPT-4o、Perplexity AI和多语言支持自动化SEO优化的博客创建
If
Set
Xml
+27
125 节点Daniel Ng
Content Creation
使用OpenAI和Firecrawl从产品URL创建AI生成的Meta广告活动
使用OpenAI和Firecrawl从产品URL创建AI生成的Meta广告活动
If
Set
Code
+15
40 节点Adam Crafts
Content Creation
监控LinkedIn帖子并使用OpenAI和Airtable创建AI内容摘要
监控LinkedIn帖子并使用OpenAI和Airtable创建AI内容摘要
If
Set
Code
+10
30 节点Anna Bui
Content Creation
工作流信息
难度等级
高级
节点数量21
分类2
节点类型14
作者
Greypillar
@greypillarWe design AI systems that fix hidden revenue leaks in service businesses. Every engagement starts with one guaranteed win in 30 days — no risk, just results.
外部链接
在 n8n.io 上查看 →
分享此工作流