8
n8n 한국어amn8n.com

SignSnapHome, Discord 및 Twilio를 사용한 오픈하우스 잠재 고객 관리 자동화

중급

이것은Content Creation, Multimodal AI분야의자동화 워크플로우로, 13개의 노드를 포함합니다.주로 If, Code, Twilio, Webhook, EmailSend 등의 노드를 사용하며. SignSnapHome, Discord 및 Twilio를 사용한 오픈하우스 리드 관리 자동화

사전 요구사항
  • HTTP Webhook 엔드포인트(n8n이 자동으로 생성)
  • 대상 API의 인증 정보가 필요할 수 있음
워크플로우 미리보기
노드 연결 관계를 시각적으로 표시하며, 확대/축소 및 이동을 지원합니다
워크플로우 내보내기
다음 JSON 구성을 복사하여 n8n에 가져오면 이 워크플로우를 사용할 수 있습니다
{
  "meta": {
    "instanceId": "105694f414213a0eca348284005921253960bd1b0223294a4970522d0da53055",
    "templateCredsSetupCompleted": true
  },
  "nodes": [
    {
      "id": "655b90b2-0e86-4bef-adfd-0a5f1525c3ee",
      "name": "웹훅",
      "type": "n8n-nodes-base.webhook",
      "position": [
        0,
        0
      ],
      "webhookId": "7c58ab04-b71f-4d81-82a1-ff0b08782b54",
      "parameters": {
        "path": "signsnaphome-sign-in-trigger",
        "options": {},
        "httpMethod": "POST"
      },
      "typeVersion": 2.1
    },
    {
      "id": "5e350a04-18b9-4dc0-b201-c0ac2022f0e3",
      "name": "데이터 파싱 및 보강",
      "type": "n8n-nodes-base.code",
      "position": [
        176,
        0
      ],
      "parameters": {
        "jsCode": "// Extract webhook data from body\nconst items = $input.all();\nconst webhookData = items[0].json.body;\n\n// Standard fields that might exist\nconst standardFields = [\n  'openHouseTitle',\n  'openHouseType', \n  'submissionTimestamp',\n  'guestPhotoUrl',\n  'first_name',\n  'last_name',\n  'phone_number',\n  'email',\n  'are_you_currently_working_with_an_agent',\n  'what_did_you_rate_the_house',\n  'do_you_have_a_signed_buyer_agreement',\n  'webhookUrl',\n  'executionMode'\n];\n\n// Separate standard and custom fields\nconst standardData = {};\nconst customFields = {};\n\nfor (const [key, value] of Object.entries(webhookData)) {\n  if (standardFields.includes(key)) {\n    standardData[key] = value;\n  } else {\n    customFields[key] = value;\n  }\n}\n\n// Format timestamp\nconst timestamp = standardData.submissionTimestamp ? \n  new Date(standardData.submissionTimestamp).toLocaleString('en-US', {\n    dateStyle: 'full',\n    timeStyle: 'short'\n  }) : 'Not provided';\n\n// Check if rating field exists\nconst hasRating = standardData.what_did_you_rate_the_house !== undefined && \n                  standardData.what_did_you_rate_the_house !== null &&\n                  standardData.what_did_you_rate_the_house !== '';\n\nconst rating = hasRating ? parseInt(standardData.what_did_you_rate_the_house) : null;\n\n// Determine lead priority based on agent status and rating (if available)\nlet leadPriority = 'MEDIUM';\nlet embedColor = 0xFFA500; // Orange for medium\n\nconst hasAgent = standardData.are_you_currently_working_with_an_agent?.toLowerCase();\nconst hasBuyerAgreement = standardData.do_you_have_a_signed_buyer_agreement?.toLowerCase();\n\n// HOT lead: No agent and high rating (or no rating field but no agent)\nif (hasAgent === 'no' && (!hasRating || rating >= 4)) {\n  leadPriority = 'HOT';\n  embedColor = 0xFF0000; // Red for hot\n} \n// COLD lead: Has agent with agreement OR low rating\nelse if ((hasAgent === 'yes' && hasBuyerAgreement === 'yes') || (hasRating && rating <= 2)) {\n  leadPriority = 'COLD';\n  embedColor = 0x0099FF; // Blue for cold\n}\n// WARM lead: Has agent but no agreement\nelse if (hasAgent === 'yes' && hasBuyerAgreement === 'no') {\n  leadPriority = 'WARM';\n  embedColor = 0xFFA500; // Orange for warm\n}\n\n// Process base64 image\nlet imageBase64 = null;\nlet hasPhoto = false;\nlet imageMimeType = 'image/jpeg';\n\nif (standardData.guestPhotoUrl && standardData.guestPhotoUrl.startsWith('data:image')) {\n  try {\n    // Extract mime type\n    const mimeMatch = standardData.guestPhotoUrl.match(/data:(image\\/[a-zA-Z]+);base64,/);\n    if (mimeMatch) {\n      imageMimeType = mimeMatch[1];\n    }\n    \n    // Extract base64 data\n    const base64Data = standardData.guestPhotoUrl.split(',')[1];\n    imageBase64 = base64Data;\n    hasPhoto = true;\n  } catch (error) {\n    console.log('Error processing image:', error.message);\n  }\n}\n\n// Build custom fields display\nconst customFieldsArray = Object.entries(customFields)\n  .filter(([key, value]) => value !== null && value !== undefined && value !== '')\n  .map(([key, value]) => {\n    const formattedKey = key.replace(/_/g, ' ')\n      .split(' ')\n      .map(word => word.charAt(0).toUpperCase() + word.slice(1))\n      .join(' ');\n    return { name: formattedKey, value: String(value), inline: true };\n  });\n\nreturn [{\n  json: {\n    // Core guest data\n    firstName: standardData.first_name || 'Not provided',\n    lastName: standardData.last_name || 'Not provided',\n    fullName: `${standardData.first_name || ''} ${standardData.last_name || ''}`.trim() || 'Anonymous Guest',\n    email: standardData.email || null,\n    phone: standardData.phone_number || null,\n    \n    // Property info\n    propertyAddress: standardData.openHouseTitle || 'Unknown Property',\n    openHouseType: standardData.openHouseType || 'open-house',\n    \n    // Engagement data\n    hasRating: hasRating,\n    rating: rating,\n    ratingDisplay: hasRating ? `${rating}/5` : 'Not rated',\n    hasAgent: standardData.are_you_currently_working_with_an_agent || 'Not specified',\n    hasBuyerAgreement: standardData.do_you_have_a_signed_buyer_agreement || null,\n    timestamp: timestamp,\n    rawTimestamp: standardData.submissionTimestamp,\n    \n    // Lead scoring\n    leadPriority: leadPriority,\n    embedColor: embedColor,\n    \n    // Image data\n    hasPhoto: hasPhoto,\n    imageBase64: imageBase64,\n    imageMimeType: imageMimeType,\n    \n    // Custom fields\n    customFields: customFieldsArray,\n    hasCustomFields: customFieldsArray.length > 0,\n    \n    // Contact preferences\n    hasEmail: !!standardData.email,\n    hasPhone: !!standardData.phone_number,\n    \n    // Raw data for reference\n    rawData: webhookData\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "51e8b880-f380-4539-b1c9-980e2260454d",
      "name": "이미지를 바이너리로 변환",
      "type": "n8n-nodes-base.moveBinaryData",
      "position": [
        400,
        0
      ],
      "parameters": {
        "mode": "jsonToBinary",
        "options": {
          "encoding": "base64",
          "fileName": "={{ $json.fullName.replace(/ /g, '_') }}_photo.jpg",
          "mimeType": "={{ $json.imageMimeType }}"
        },
        "sourceKey": "imageBase64",
        "convertAllData": false,
        "destinationKey": "photo"
      },
      "typeVersion": 1.1
    },
    {
      "id": "78954bf0-f3d9-4af5-bddc-dbcb1a77e8c9",
      "name": "Discord 알림",
      "type": "n8n-nodes-base.httpRequest",
      "notes": "Sends to Discord with photo thumbnail",
      "position": [
        624,
        0
      ],
      "parameters": {
        "url": "YOUR_WEBHOOK_URL_HERE",
        "method": "POST",
        "options": {},
        "sendBody": true,
        "contentType": "multipart-form-data",
        "bodyParameters": {
          "parameters": [
            {
              "name": "payload_json",
              "value": "={{ \n  (function() {\n    // Build fields array\n    const fields = [\n      {\n        \"name\": \"👤 Name\",\n        \"value\": $json.fullName,\n        \"inline\": true\n      },\n      {\n        \"name\": \"🏢 Has Agent?\",\n        \"value\": $json.hasAgent,\n        \"inline\": true\n      }\n    ];\n    \n    // Add rating field only if it exists\n    if ($json.hasRating) {\n      fields.push({\n        \"name\": \"⭐ Rating\",\n        \"value\": $json.ratingDisplay,\n        \"inline\": true\n      });\n    }\n    \n    // Add buyer agreement if available\n    if ($json.hasBuyerAgreement) {\n      fields.push({\n        \"name\": \"📝 Buyer Agreement\",\n        \"value\": $json.hasBuyerAgreement,\n        \"inline\": true\n      });\n    }\n    \n    // Add contact info\n    fields.push(\n      {\n        \"name\": \"📧 Email\",\n        \"value\": $json.email || 'Not provided',\n        \"inline\": true\n      },\n      {\n        \"name\": \"📱 Phone\",\n        \"value\": $json.phone || 'Not provided',\n        \"inline\": true\n      },\n      {\n        \"name\": \"🕒 Visit Time\",\n        \"value\": $json.timestamp,\n        \"inline\": false\n      }\n    );\n    \n    // Add custom fields if any\n    if ($json.customFields && $json.customFields.length > 0) {\n      fields.push(...$json.customFields);\n    }\n    \n    const payload = {\n      \"embeds\": [\n        {\n          \"title\": \"🏠 New Open House Visitor - \" + $json.leadPriority + \" LEAD\",\n          \"description\": \"**\" + $json.fullName + \"** visited **\" + $json.propertyAddress + \"**\",\n          \"color\": $json.embedColor,\n          \"fields\": fields,\n          \"footer\": {\n            \"text\": \"SignSnap Home | Lead Priority: \" + $json.leadPriority\n          },\n          \"timestamp\": $json.rawTimestamp\n        }\n      ]\n    };\n    \n    // Add thumbnail if photo exists (will use attachment)\n    if ($json.hasPhoto) {\n      payload.embeds[0].thumbnail = {\n        \"url\": \"attachment://\" + $json.fullName.replace(/ /g, '_') + \"_photo.jpg\"\n      };\n    }\n    \n    return JSON.stringify(payload);\n  })()\n}}"
            },
            {
              "name": "files[0]",
              "parameterType": "formBinaryData",
              "inputDataFieldName": "photo"
            }
          ]
        }
      },
      "typeVersion": 4.2,
      "alwaysOutputData": true
    },
    {
      "id": "36952b83-ea4c-4001-a53b-a179c5dea94e",
      "name": "전화번호가 있나요?",
      "type": "n8n-nodes-base.if",
      "position": [
        848,
        0
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "phone-check",
              "operator": {
                "type": "boolean",
                "operation": "equals"
              },
              "leftValue": "={{ $('Parse & Enrich Data').item.json.hasPhone }}",
              "rightValue": true
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "c2e72a81-eb01-4ebc-bade-f1aa0735c1d9",
      "name": "SMS 전송 (Twilio)",
      "type": "n8n-nodes-base.twilio",
      "notes": "Configure Twilio credentials in n8n",
      "position": [
        1056,
        -112
      ],
      "parameters": {
        "to": "={{ $('Parse & Enrich Data').item.json.phone }}",
        "from": "={{ $credentials.twilioPhoneNumber }}",
        "message": "=Hi {{ $('Parse & Enrich Data').item.json.firstName }}! Thank you for visiting {{ $('Parse & Enrich Data').item.json.propertyAddress }} today. {{ $json.embeds[0].fields[1].value === 'No' ? \"We'd love to help you find your perfect home! Our experienced team can provide exclusive listings and personalized service. Reply to schedule a private consultation!\" : \"Hope you enjoy the property! Feel free to reach out if you have any additional questions.\" }}",
        "options": {}
      },
      "typeVersion": 1
    },
    {
      "id": "4c73efc1-4cc0-4eaa-8f5c-09b59b9a4958",
      "name": "이메일이 있나요?",
      "type": "n8n-nodes-base.if",
      "position": [
        1056,
        96
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "email-check",
              "operator": {
                "type": "boolean",
                "operation": "equals"
              },
              "leftValue": "={{ $('Parse & Enrich Data').item.json.hasEmail }}",
              "rightValue": true
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "c02d15c4-0254-4dff-82a8-603eeda2982d",
      "name": "환영 이메일 전송",
      "type": "n8n-nodes-base.emailSend",
      "notes": "Configure SMTP credentials in n8n",
      "position": [
        1280,
        96
      ],
      "webhookId": "0119fc19-8eb0-4108-954b-8ca510416c78",
      "parameters": {
        "html": "=Hi {{ $('Parse & Enrich Data').item.json.firstName }}!\n\nThank you for visiting {{ $('Parse & Enrich Data').item.json.propertyAddress }} today. \n{{ $json.embeds[0].fields[1].value === 'No' ? \"We'd love to help you find your perfect home! Our experienced team can provide exclusive listings and personalized service. Reply to schedule a private consultation!\" : \"Hope you enjoy the property! Feel free to reach out if you have any additional questions.\" }}\n\n{SET YOUR TEAM OR PERSONAL FOOTER HERE}",
        "options": {},
        "subject": "=Thank You for Visiting {{ $('Parse & Enrich Data').item.json.propertyAddress }}!",
        "toEmail": "={{ $('Parse & Enrich Data').item.json.email }}",
        "fromEmail": "YOUR_EMAIL_HERE"
      },
      "typeVersion": 2.1
    },
    {
      "id": "2f817a77-00c0-48ca-b640-800559834b2c",
      "name": "스티커 메모",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -240,
        -304
      ],
      "parameters": {
        "height": 256,
        "content": "## Recieve Sign In Data from Sign Snap Home\n**Start Free Here** signsnaphome.com\n\nSet up a custom webhook and set it to auto fire! Use the link below to paste into Sign Snap Home."
      },
      "typeVersion": 1
    },
    {
      "id": "a3a41519-d806-4582-ad58-2d6834c1a663",
      "name": "스티커 메모1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        144,
        -192
      ],
      "parameters": {
        "width": 160,
        "height": 128,
        "content": "## Check and Enrich Sign In Data\n"
      },
      "typeVersion": 1
    },
    {
      "id": "d5fc183c-7fdd-4f6e-8856-43bb21b834c8",
      "name": "스티커 메모2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        368,
        -160
      ],
      "parameters": {
        "width": 150,
        "height": 96,
        "content": "Convert Guest Photo from Base64 to Binary for Discord Send"
      },
      "typeVersion": 1
    },
    {
      "id": "7aa663fa-1756-4f0e-bb98-d4defecd8481",
      "name": "스티커 메모3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        608,
        -336
      ],
      "parameters": {
        "width": 150,
        "height": 272,
        "content": "## Send to Discord\n\nAdd your Webhook URL Below. Great to get updates for team member sign ins or if you're chatting with another guest."
      },
      "typeVersion": 1
    },
    {
      "id": "39a19190-f7cb-43bb-8c78-475e86d1c7d0",
      "name": "스티커 메모4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        880,
        -384
      ],
      "parameters": {
        "width": 624,
        "height": 192,
        "content": "## Check if Phone is provided\n**Otherwise Send Email** \n\nCheck the Send SMS and Send Email to customize your messaging. If guest does not have agent they recieve longer custom messaging saying we'd love to help them. \n\nEdit the if no part of the josn to change the if no agent response. Make sure you preview and test your use cases."
      },
      "typeVersion": 1
    }
  ],
  "pinData": {},
  "connections": {
    "655b90b2-0e86-4bef-adfd-0a5f1525c3ee": {
      "main": [
        [
          {
            "node": "5e350a04-18b9-4dc0-b201-c0ac2022f0e3",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "4c73efc1-4cc0-4eaa-8f5c-09b59b9a4958": {
      "main": [
        [
          {
            "node": "c02d15c4-0254-4dff-82a8-603eeda2982d",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "36952b83-ea4c-4001-a53b-a179c5dea94e": {
      "main": [
        [
          {
            "node": "c2e72a81-eb01-4ebc-bade-f1aa0735c1d9",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "4c73efc1-4cc0-4eaa-8f5c-09b59b9a4958",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "5e350a04-18b9-4dc0-b201-c0ac2022f0e3": {
      "main": [
        [
          {
            "node": "51e8b880-f380-4539-b1c9-980e2260454d",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "78954bf0-f3d9-4af5-bddc-dbcb1a77e8c9": {
      "main": [
        [
          {
            "node": "36952b83-ea4c-4001-a53b-a179c5dea94e",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "51e8b880-f380-4539-b1c9-980e2260454d": {
      "main": [
        [
          {
            "node": "78954bf0-f3d9-4af5-bddc-dbcb1a77e8c9",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
자주 묻는 질문

이 워크플로우를 어떻게 사용하나요?

위의 JSON 구성 코드를 복사하여 n8n 인스턴스에서 새 워크플로우를 생성하고 "JSON에서 가져오기"를 선택한 후, 구성을 붙여넣고 필요에 따라 인증 설정을 수정하세요.

이 워크플로우는 어떤 시나리오에 적합한가요?

중급 - 콘텐츠 제작, 멀티모달 AI

유료인가요?

이 워크플로우는 완전히 무료이며 직접 가져와 사용할 수 있습니다. 다만, 워크플로우에서 사용하는 타사 서비스(예: OpenAI API)는 사용자 직접 비용을 지불해야 할 수 있습니다.

워크플로우 정보
난이도
중급
노드 수13
카테고리2
노드 유형8
난이도 설명

일정 경험을 가진 사용자를 위한 6-15개 노드의 중간 복잡도 워크플로우

저자
Kaden Reese

Kaden Reese

@kadenreese

I started automating with Python in 2020 and still use it in workflows when needed, but I’ve recently leaned into n8n for client-facing solutions. Lately I’ve focused on real estate automations, though I also build workflows for email, scraping, and other use cases. Currently Building 👇🏻

외부 링크
n8n.io에서 보기

이 워크플로우 공유

카테고리

카테고리: 34