Meetup参加者登録と抽選アプリ

中級

これはMiscellaneous分野の自動化ワークフローで、12個のノードを含みます。主にSet, Code, Form, Webhook, Postgresなどのノードを使用。 PostgreSQLデータベースに基づくMeetup登録システムとインタラクティブな抽選ツール

前提条件
  • HTTP Webhookエンドポイント(n8nが自動生成)
  • PostgreSQLデータベース接続情報

カテゴリー

ワークフロープレビュー
ノード接続関係を可視化、ズームとパンをサポート
ワークフローをエクスポート
以下のJSON設定をn8nにインポートして、このワークフローを使用できます
{
  "id": "B1Tn4E0X4IfTUiHw",
  "meta": {
    "instanceId": "43905f7eef4dcd9dab6e186fbccfa78b0e88a07b5e6c19ebd17391441f834f49",
    "templateCredsSetupCompleted": true
  },
  "name": "Meetup Participant Registration & Giveaway App",
  "tags": [],
  "nodes": [
    {
      "id": "76bd011c-3ace-4094-8fa0-bac818192d9a",
      "name": "サンクス画面",
      "type": "n8n-nodes-base.form",
      "position": [
        620,
        600
      ],
      "webhookId": "b33ea633-f82b-4e16-b71f-5075fae13cdc",
      "parameters": {
        "options": {
          "customCss": ":root {\n\t--font-family: 'Inter', sans-serif;\n\t--font-weight-normal: 400;\n\t--font-weight-bold: 700;\n\t--font-size-body: 14px;\n\t--font-size-label: 16px;\n\t--font-size-header: 24px;\n\t--font-size-input: 16px;\n\t--font-size-error: 12px;\n\n\t/* Purple Themed Colors */\n\t--color-background: #f5f3ff; /* soft lavender */\n\t--color-card-bg: #ffffff;\n\t--color-card-border: #e0d7f8;\n\t--color-card-shadow: rgba(103, 80, 164, 0.12);\n\t--color-header: #3c1e74;\n\t--color-label: #4c1d95;\n\t--color-input-text: #1f1b2e;\n\t--color-input-border: #c4b5fd;\n\t--color-focus-border: #7c3aed;\n\t--color-submit-btn-bg: #7c3aed;\n\t--color-submit-btn-bg-hover: #6d28d9;\n\t--color-submit-btn-text: #ffffff;\n\t--color-error: #dc2626;\n\t--color-required: #dc2626;\n\t--color-test-notice-text: #7e22ce;\n\t--color-test-notice-bg: #f3e8ff;\n\t--color-test-notice-border: #e9d5ff;\n\n\t--border-radius-card: 12px;\n\t--border-radius-input: 8px;\n\t--submit-btn-height: 52px;\n\n\t--padding-card: 32px;\n\t--padding-form-input: 14px;\n\t--box-shadow-card: 0 8px 24px rgba(103, 80, 164, 0.15);\n}\n\n/* Body Background */\nbody {\n\tbackground-color: var(--color-background);\n\tfont-family: var(--font-family);\n\tmargin: 0;\n\tpadding: 0;\n\tcolor: var(--color-input-text);\n}\n\n/* Form Container Card */\n.card {\n\tmax-width: 480px;\n\tmargin: 40px auto;\n\tbackground-color: var(--color-card-bg);\n\tborder-radius: var(--border-radius-card);\n\tbox-shadow: var(--box-shadow-card);\n\tpadding: var(--padding-card);\n\tborder: 1px solid var(--color-card-border);\n}\n\n/* Header */\n.card h1 {\n\tfont-size: var(--font-size-header);\n\tfont-weight: var(--font-weight-bold);\n\tcolor: var(--color-header);\n\tmargin-bottom: 24px;\n\ttext-align: center;\n}\n\n/* Test Notice */\n.test-notice {\n\tbackground-color: var(--color-test-notice-bg);\n\tcolor: var(--color-test-notice-text);\n\tborder: 1px solid var(--color-test-notice-border);\n\tborder-radius: 6px;\n\tpadding: 12px 16px;\n\tfont-size: 14px;\n\tmargin-bottom: 24px;\n}\n\n/* Label */\nlabel {\n\tdisplay: block;\n\tfont-size: var(--font-size-label);\n\tfont-weight: var(--font-weight-bold);\n\tcolor: var(--color-label);\n\tmargin-bottom: 8px;\n}\n\n/* Input Field */\ninput[type=\"text\"], input[type=\"email\"] {\n\twidth: 100%;\n\tpadding: var(--padding-form-input);\n\tborder: 1px solid var(--color-input-border);\n\tborder-radius: var(--border-radius-input);\n\tfont-size: var(--font-size-input);\n\tcolor: var(--color-input-text);\n\tbox-sizing: border-box;\n\ttransition: border-color 0.2s ease;\n}\n\ninput[type=\"text\"]:focus, input[type=\"email\"]:focus {\n\tborder-color: var(--color-focus-border);\n\toutline: none;\n}\n\n/* Error Message */\n.error {\n\tcolor: var(--color-error);\n\tfont-size: var(--font-size-error);\n\tmargin-top: 6px;\n}\n\n/* Submit Button */\nbutton[type=\"submit\"] {\n\twidth: 100%;\n\theight: var(--submit-btn-height);\n\tbackground-color: var(--color-submit-btn-bg);\n\tcolor: var(--color-submit-btn-text);\n\tfont-weight: var(--font-weight-bold);\n\tfont-size: 16px;\n\tborder: none;\n\tborder-radius: 10px;\n\tcursor: pointer;\n\ttransition: background-color 0.2s ease;\n}\n\nbutton[type=\"submit\"]:hover {\n\tbackground-color: var(--color-submit-btn-bg-hover);\n}\n\n/* Required Asterisk */\nlabel .required {\n\tcolor: var(--color-required);\n\tmargin-left: 4px;\n}\n"
        },
        "operation": "completion",
        "completionTitle": "Glad You're Here!",
        "completionMessage": "Thank you for being part of our meetup. Don’t miss the giveaway at the end of the session!"
      },
      "typeVersion": 1
    },
    {
      "id": "dc0a7158-2b27-4a83-8fc0-e826ce425b7f",
      "name": "参加者リストのフォーマット",
      "type": "n8n-nodes-base.code",
      "position": [
        420,
        1140
      ],
      "parameters": {
        "jsCode": "// Loop over input items and add a new field called 'myNewField' to the JSON of each one\nvar list = $input.all();\n\nfunction base64Encode(originalString) {\n  // Create a Buffer from the string\n  const buffer = Buffer.from(originalString, 'utf8');\n  // Convert the Buffer to a Base64 string\n  const encodedString = buffer.toString('base64');\n  return encodedString;\n}\nfunction redactWhatsapp(number) {\n  if (!number || number.length < 7) return number; // too short to redact safely\n  const start = number.slice(0, 4);\n  const end = number.slice(-4);\n  return `${start}****${end}`;\n}\nvar newList = list.map((row)=> {\n  var data = row.json\n  var name = data.nama_lengkap\n  var whatsapp = redactWhatsapp(data.whatsapp)\n  var label = name + ' (' +whatsapp+')'\n  return label;\n})\n\nreturn {names: newList}"
      },
      "typeVersion": 2
    },
    {
      "id": "7fba3d0f-8c7b-4f19-8954-9b8ab7a6d95b",
      "name": "フォームからデータベースへのマッピング",
      "type": "n8n-nodes-base.set",
      "position": [
        180,
        600
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "8d91a9a0-84fa-47c6-a8b9-31b21bb25ab0",
              "name": "nama_lengkap",
              "type": "string",
              "value": "={{ $json['Nama Lengkap'] }}"
            },
            {
              "id": "3459b5c2-0c65-4684-a7f7-bcdb2aece4d5",
              "name": "discord_username",
              "type": "string",
              "value": "={{ $json['Discord Username (yang join di discord channel)'] }}"
            },
            {
              "id": "59ac4d04-3dee-4ccb-bd08-351f5529bd6b",
              "name": "domisili_kota",
              "type": "string",
              "value": "={{ $json['Domisili (Kota)'] }}"
            },
            {
              "id": "c0ac2b89-4d7b-4e79-87de-c7f58efcba1f",
              "name": "bio",
              "type": "string",
              "value": "={{ $json['Bio (pekerjaan, specialty, dsb)'] }}"
            },
            {
              "id": "7460a976-89e9-4d9c-8680-74ac823a6aca",
              "name": "email",
              "type": "string",
              "value": "={{ $json.Email }}"
            },
            {
              "id": "9018f12d-2aaf-4e9c-941c-9db53da5e83c",
              "name": "whatsapp",
              "type": "string",
              "value": "={{ $json.Whatsapp }}"
            },
            {
              "id": "483859a7-add4-46e5-a39d-d9199c86e59b",
              "name": "threads_username",
              "type": "string",
              "value": "={{ $json['Threads Username'] }}"
            },
            {
              "id": "9717df91-b9f1-4098-8eb3-6c97dfede3d7",
              "name": "instagram_username",
              "type": "string",
              "value": "={{ $json['Instagram Username'] }}"
            },
            {
              "id": "0d2fb350-61ec-4822-8dc5-c3ab9a20ce1c",
              "name": "created_at",
              "type": "string",
              "value": "={{ $json.submittedAt }}"
            },
            {
              "id": "32b9a3fa-0ef7-4a84-9adb-df25d112d4af",
              "name": "event",
              "type": "string",
              "value": "={{ $json.Event }}"
            },
            {
              "id": "8e2be506-a19b-4c0d-97c4-1fa73fe1546e",
              "name": "id",
              "type": "string",
              "value": "={{ $json.Event }}--{{ $json.Whatsapp }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "6d66e53e-147c-42a8-a742-349901287c96",
      "name": "全参加者の取得",
      "type": "n8n-nodes-base.postgres",
      "position": [
        200,
        1140
      ],
      "parameters": {
        "table": {
          "__rl": true,
          "mode": "list",
          "value": "n8n_meetup_participants",
          "cachedResultName": "n8n_meetup_participants"
        },
        "where": {
          "values": [
            {
              "value": "Meetup #2",
              "column": "event"
            }
          ]
        },
        "schema": {
          "__rl": true,
          "mode": "list",
          "value": "public"
        },
        "options": {},
        "operation": "select",
        "returnAll": true
      },
      "credentials": {
        "postgres": {
          "id": "irlIPHqjhjs13ldK",
          "name": "Neon N8N Community Indonesia"
        }
      },
      "typeVersion": 2.6
    },
    {
      "id": "8478dcf5-7e9c-471e-b7db-d7b601f4fd58",
      "name": "Giveaway App",
      "type": "n8n-nodes-base.webhook",
      "position": [
        -20,
        1140
      ],
      "webhookId": "6706b347-20f6-41cc-a17c-7afb747d4f24",
      "parameters": {
        "path": "giveaway",
        "options": {},
        "responseMode": "responseNode"
      },
      "typeVersion": 2
    },
    {
      "id": "0df6e338-46ee-42fc-b2b8-4986e167f271",
      "name": "Giveaway Appへの応答",
      "type": "n8n-nodes-base.respondToWebhook",
      "position": [
        620,
        1140
      ],
      "parameters": {
        "options": {},
        "respondWith": "text",
        "responseBody": "=<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\" />\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/>\n  <title>n8n Meetup Name Picker</title>\n  <style>\n    body {\n      font-family: 'Inter', sans-serif;\n      background-color: #f5f3ff;\n      margin: 0;\n      padding: 0;\n      display: flex;\n      flex-direction: column;\n      align-items: center;\n      min-height: 100vh;\n      justify-content: center;\n    }\n\n    .container {\n      background-color: #ffffff;\n      border-radius: 12px;\n      padding: 32px;\n      max-width: 500px;\n      width: 100%;\n      box-shadow: 0 8px 24px rgba(103, 80, 164, 0.15);\n      text-align: center;\n    }\n\n    h1 {\n      color: #4c1d95;\n      margin-bottom: 24px;\n    }\n\n    textarea {\n      width: 100%;\n      height: 150px;\n      border: 1px solid #c4b5fd;\n      border-radius: 8px;\n      padding: 12px 20px 12px 16px;\n      font-family: 'Inter', sans-serif;\n      box-sizing: border-box;\n      font-size: 14px;\n      margin-bottom: 16px;\n      resize: none;\n    }\n\n    input[type=\"number\"] {\n      width: 60px;\n      padding: 8px;\n      margin: 8px 0;\n      border-radius: 6px;\n      border: 1px solid #c4b5fd;\n      text-align: center;\n    }\n\n    button {\n      background-color: #7c3aed;\n      color: white;\n      border: none;\n      padding: 12px 24px;\n      border-radius: 8px;\n      font-size: 16px;\n      cursor: pointer;\n      margin-top: 12px;\n    }\n\n    button:hover {\n      background-color: #6d28d9;\n    }\n\n    .results {\n      margin-top: 24px;\n      font-size: 18px;\n      color: #1f1b2e;\n    }\n\n    .results li {\n      margin: 4px 0;\n    }\n  </style>\n</head>\n<body>\n  <div class=\"container\">\n    <h1>🎉 Giveaway <br/> N8N ID Meetup #2</h1>\n    <div id=\"formSection\">\n      <p>Paste the list of attendee names below (one per line):</p>\n      <textarea id=\"nameInput\" placeholder=\"e.g. John Doe&#10;Jane Smith&#10;Andi Prasetyo\"></textarea>\n      <p>Select how many names to pick:</p>\n      <input type=\"number\" id=\"countInput\" value=\"5\" min=\"1\" />\n      <br />\n      <button onclick=\"pickNames()\">Pick Random Name(s)</button>\n    </div>\n    <div id=\"rollingSection\" style=\"display:none; margin-top:32px; text-align:center;\">\n      <div id=\"rollingNames\" style=\"font-size:2rem; color:#7c3aed; min-height:2.5em; font-weight:bold;\"></div>\n      <div id=\"rollingCount\" style=\"margin-top:8px; color:#6d28d9;\"></div>\n      <button id=\"backButton\" style=\"display:none; margin-top:24px; background:#e0e7ff; color:#4c1d95; border:none; padding:10px 24px; border-radius:8px; font-size:15px; cursor:pointer;\" onclick=\"backToInput()\">Back to Input</button>\n    </div>\n  </div>\n\n  <script src=\"https://cdn.jsdelivr.net/npm/canvas-confetti@1.6.0/dist/confetti.browser.min.js\"></script>\n\n  <script>\n    // Daftar nama peserta (bisa diubah sesuai kebutuhan)\n    const predefinedNames = {{ JSON.stringify($json.names) }}\n\n    // Isi textarea dengan daftar nama saat halaman dimuat\n    window.onload = function() {\n      document.getElementById('nameInput').value = predefinedNames.join('\\n');\n    };\n\n    function pickNames() {\n      const input = document.getElementById('nameInput').value.trim();\n      const count = parseInt(document.getElementById('countInput').value);\n      const resultsList = document.getElementById('resultsList');\n      const formSection = document.getElementById('formSection');\n      const rollingSection = document.getElementById('rollingSection');\n      const rollingNames = document.getElementById('rollingNames');\n      const rollingCount = document.getElementById('rollingCount');\n\n      if (!input) {\n        alert('Please enter at least one name.');\n        return;\n      }\n\n      const names = input.split('\\n').map(name => name.trim()).filter(name => name !== '');\n\n      if (count > names.length) {\n        alert('Not enough names to pick from.');\n        return;\n      }\n\n      // Sembunyikan form, tampilkan rolling\n      formSection.style.display = 'none';\n      rollingSection.style.display = 'block';\n\n      // Rolling animation\n      let rollingInterval;\n      let rollingDuration = 2000; // ms\n      let rollingSpeed = 60; // ms\n      let rollingNamesArr = [];\n      let rollingStep = 0;\n\n      if (count === 1) {\n        // Rolling satu nama\n        rollingInterval = setInterval(() => {\n          const randomName = names[Math.floor(Math.random() * names.length)];\n          rollingNames.textContent = randomName;\n        }, rollingSpeed);\n      } else {\n        // Rolling beberapa nama sekaligus\n        rollingInterval = setInterval(() => {\n          rollingNamesArr = [];\n          let tempNames = [...names];\n          for (let i = 0; i < count; i++) {\n            if (tempNames.length === 0) break;\n            const idx = Math.floor(Math.random() * tempNames.length);\n            rollingNamesArr.push(tempNames[idx]);\n            tempNames.splice(idx, 1);\n          }\n          rollingNames.innerHTML = rollingNamesArr.map(n => `<div>${n}</div>`).join('');\n        }, rollingSpeed);\n      }\n      rollingCount.textContent = 'Picking winner...';\n\n      setTimeout(() => {\n        clearInterval(rollingInterval);\n        // Pilih pemenang sebenarnya\n        const shuffled = names.sort(() => 0.5 - Math.random());\n        const selected = shuffled.slice(0, count);\n        rollingNames.innerHTML = selected.map(n => `<div style=\\\"color:#22c55e;\\\">${n}</div>`).join('');\n        rollingCount.textContent = 'Winner' + (count > 1 ? 's' : '') + ' 🎉';\n\n        // Tampilkan confetti\n        confetti({\n          particleCount: 120,\n          spread: 90,\n          origin: { y: 0.6 }\n        });\n\n        document.getElementById('backButton').style.display = 'inline-block';\n      }, rollingDuration);\n    }\n\n    function backToInput() {\n      document.getElementById('formSection').style.display = 'block';\n      document.getElementById('rollingSection').style.display = 'none';\n      document.getElementById('backButton').style.display = 'none';\n      document.getElementById('resultsList').innerHTML = '';\n      document.getElementById('rollingNames').textContent = '';\n      document.getElementById('rollingCount').textContent = '';\n    }\n  </script>\n</body>\n</html>\n"
      },
      "typeVersion": 1.4
    },
    {
      "id": "99f96a32-d847-43f7-8740-cff828d7b314",
      "name": "付箋",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1500,
        420
      ],
      "parameters": {
        "width": 660,
        "height": 520,
        "content": "# 🎉 n8n Workflow: Meetup Participant Registration & Giveaway App\n\nThis n8n workflow is designed to handle both the participant registration process and the random selection of giveaway winners via a frontend integration.\n\n## ✅ Use Case Summary\n\n- Efficiently collects and stores attendee information\n- Securely exposes a simplified participant list to the frontend\n- Prepares giveaway-ready data with privacy protection\n- Perfect for community events or randomized prize draws\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "cf039ad9-01ee-4484-ae3d-d0225227da32",
      "name": "参加者フォーム",
      "type": "n8n-nodes-base.formTrigger",
      "position": [
        -40,
        600
      ],
      "webhookId": "48c80b3d-22a0-4add-9d7f-384bff7791b1",
      "parameters": {
        "options": {
          "path": "giveaway",
          "customCss": ":root {\n\t--font-family: 'Inter', sans-serif;\n\t--font-weight-normal: 400;\n\t--font-weight-bold: 700;\n\t--font-size-body: 14px;\n\t--font-size-label: 16px;\n\t--font-size-header: 24px;\n\t--font-size-input: 16px;\n\t--font-size-error: 12px;\n\n\t/* Purple Themed Colors */\n\t--color-background: #f5f3ff; /* soft lavender */\n\t--color-card-bg: #ffffff;\n\t--color-card-border: #e0d7f8;\n\t--color-card-shadow: rgba(103, 80, 164, 0.12);\n\t--color-header: #3c1e74;\n\t--color-label: #4c1d95;\n\t--color-input-text: #1f1b2e;\n\t--color-input-border: #c4b5fd;\n\t--color-focus-border: #7c3aed;\n\t--color-submit-btn-bg: #7c3aed;\n\t--color-submit-btn-bg-hover: #6d28d9;\n\t--color-submit-btn-text: #ffffff;\n\t--color-error: #dc2626;\n\t--color-required: #dc2626;\n\t--color-test-notice-text: #7e22ce;\n\t--color-test-notice-bg: #f3e8ff;\n\t--color-test-notice-border: #e9d5ff;\n\n\t--border-radius-card: 12px;\n\t--border-radius-input: 8px;\n\t--submit-btn-height: 52px;\n\n\t--padding-card: 32px;\n\t--padding-form-input: 14px;\n\t--box-shadow-card: 0 8px 24px rgba(103, 80, 164, 0.15);\n}\n\n/* Body Background */\nbody {\n\tbackground-color: var(--color-background);\n\tfont-family: var(--font-family);\n\tmargin: 0;\n\tpadding: 0;\n\tcolor: var(--color-input-text);\n}\n\n/* Form Container Card */\n.card {\n\tmax-width: 480px;\n\tmargin: 40px auto;\n\tbackground-color: var(--color-card-bg);\n\tborder-radius: var(--border-radius-card);\n\tbox-shadow: var(--box-shadow-card);\n\tpadding: var(--padding-card);\n\tborder: 1px solid var(--color-card-border);\n}\n\n/* Header */\n.card h1 {\n\tfont-size: var(--font-size-header);\n\tfont-weight: var(--font-weight-bold);\n\tcolor: var(--color-header);\n\tmargin-bottom: 24px;\n\ttext-align: center;\n}\n\n/* Test Notice */\n.test-notice {\n\tbackground-color: var(--color-test-notice-bg);\n\tcolor: var(--color-test-notice-text);\n\tborder: 1px solid var(--color-test-notice-border);\n\tborder-radius: 6px;\n\tpadding: 12px 16px;\n\tfont-size: 14px;\n\tmargin-bottom: 24px;\n}\n\n/* Label */\nlabel {\n\tdisplay: block;\n\tfont-size: var(--font-size-label);\n\tfont-weight: var(--font-weight-bold);\n\tcolor: var(--color-label);\n\tmargin-bottom: 8px;\n}\n\n/* Input Field */\ninput[type=\"text\"], input[type=\"email\"] {\n\twidth: 100%;\n\tpadding: var(--padding-form-input);\n\tborder: 1px solid var(--color-input-border);\n\tborder-radius: var(--border-radius-input);\n\tfont-size: var(--font-size-input);\n\tcolor: var(--color-input-text);\n\tbox-sizing: border-box;\n\ttransition: border-color 0.2s ease;\n}\n\ninput[type=\"text\"]:focus, input[type=\"email\"]:focus {\n\tborder-color: var(--color-focus-border);\n\toutline: none;\n}\n\n/* Error Message */\n.error {\n\tcolor: var(--color-error);\n\tfont-size: var(--font-size-error);\n\tmargin-top: 6px;\n}\n\n/* Submit Button */\nbutton[type=\"submit\"] {\n\twidth: 100%;\n\theight: var(--submit-btn-height);\n\tbackground-color: var(--color-submit-btn-bg);\n\tcolor: var(--color-submit-btn-text);\n\tfont-weight: var(--font-weight-bold);\n\tfont-size: 16px;\n\tborder: none;\n\tborder-radius: 10px;\n\tcursor: pointer;\n\ttransition: background-color 0.2s ease;\n}\n\nbutton[type=\"submit\"]:hover {\n\tbackground-color: var(--color-submit-btn-bg-hover);\n}\n\n/* Required Asterisk */\nlabel .required {\n\tcolor: var(--color-required);\n\tmargin-left: 4px;\n}\n",
          "ignoreBots": true,
          "buttonLabel": "Submit",
          "appendAttribution": false
        },
        "formTitle": "n8n Indonesia Community Meetup #2",
        "formFields": {
          "values": [
            {
              "fieldName": "Event",
              "fieldType": "hiddenField",
              "fieldValue": "=Meetup #2"
            },
            {
              "fieldLabel": "Nama Lengkap",
              "requiredField": true
            },
            {
              "fieldLabel": "Domisili (Kota)",
              "requiredField": true
            },
            {
              "fieldType": "textarea",
              "fieldLabel": "Bio (pekerjaan, specialty, dsb)",
              "requiredField": true
            },
            {
              "fieldLabel": "Whatsapp",
              "requiredField": true
            },
            {
              "fieldLabel": "Discord Username (yang join di discord channel)"
            },
            {
              "fieldLabel": "Threads Username"
            },
            {
              "fieldLabel": "Instagram Username"
            },
            {
              "fieldType": "email",
              "fieldLabel": "Email"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "d1387478-3489-4d10-b2a0-910eda73469c",
      "name": "参加者をデータベースに保存",
      "type": "n8n-nodes-base.postgres",
      "position": [
        400,
        600
      ],
      "parameters": {
        "table": {
          "__rl": true,
          "mode": "list",
          "value": "n8n_meetup_participants",
          "cachedResultName": "n8n_meetup_participants"
        },
        "schema": {
          "__rl": true,
          "mode": "list",
          "value": "public"
        },
        "columns": {
          "value": {},
          "schema": [
            {
              "id": "id",
              "type": "string",
              "display": true,
              "removed": false,
              "required": true,
              "displayName": "id",
              "defaultMatch": true,
              "canBeUsedToMatch": true
            },
            {
              "id": "nama_lengkap",
              "type": "string",
              "display": true,
              "required": true,
              "displayName": "nama_lengkap",
              "defaultMatch": false,
              "canBeUsedToMatch": false
            },
            {
              "id": "discord_username",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "discord_username",
              "defaultMatch": false,
              "canBeUsedToMatch": false
            },
            {
              "id": "domisili_kota",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "domisili_kota",
              "defaultMatch": false,
              "canBeUsedToMatch": false
            },
            {
              "id": "bio",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "bio",
              "defaultMatch": false,
              "canBeUsedToMatch": false
            },
            {
              "id": "email",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "email",
              "defaultMatch": false,
              "canBeUsedToMatch": false
            },
            {
              "id": "whatsapp",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "whatsapp",
              "defaultMatch": false,
              "canBeUsedToMatch": false
            },
            {
              "id": "threads_username",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "threads_username",
              "defaultMatch": false,
              "canBeUsedToMatch": false
            },
            {
              "id": "instagram_username",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "instagram_username",
              "defaultMatch": false,
              "canBeUsedToMatch": false
            },
            {
              "id": "created_at",
              "type": "dateTime",
              "display": true,
              "required": false,
              "displayName": "created_at",
              "defaultMatch": false,
              "canBeUsedToMatch": false
            },
            {
              "id": "event",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "event",
              "defaultMatch": false,
              "canBeUsedToMatch": false
            }
          ],
          "mappingMode": "autoMapInputData",
          "matchingColumns": [
            "id"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "upsert"
      },
      "credentials": {
        "postgres": {
          "id": "irlIPHqjhjs13ldK",
          "name": "Neon N8N Community Indonesia"
        }
      },
      "typeVersion": 2.6
    },
    {
      "id": "7222a521-913f-4326-84c3-8b84e1d07735",
      "name": "付箋1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -800,
        420
      ],
      "parameters": {
        "color": 6,
        "width": 1660,
        "height": 520,
        "content": "\n## 📋 Participant Registration Flow\n\nThis part of the workflow handles user submissions from a registration form.\n\n### 🔄 Steps:\n1. **📝 Participant Form**\n   - Triggered when a participant submits the form.\n   - Collects fields like `nama_lengkap`, `email`, `whatsapp`, `discord_username`, etc.\n\n2. **🛠️ Mapping Form to Database**\n   - Manual mapping node that prepares form data for the database.\n   - Can include trimming, validation, and formatting.\n\n3. **💾 Save Participant to Database**\n   - Uses an *upsert* operation to insert or update records in PostgreSQL.\n   - Avoids duplicate entries based on `id`.\n\n4. **✅ Thank You Screen**\n   - Displays a confirmation or success message to the participant after submission.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "0562529e-7a41-4a25-a949-87fed3007814",
      "name": "付箋2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -800,
        980
      ],
      "parameters": {
        "color": 5,
        "width": 1660,
        "height": 480,
        "content": "## 🎁 Giveaway App\n\nThis section serve frontend app to display and select random winners.\n\n### 🔄 Steps:\n1. **🌐 Webhook GET (Giveaway App)**\n   - Exposes a public endpoint that delivers a ready-to-use HTML app.\n   - Can be opened in a browser or projected during the event.\n\n2. **📥 Fetch Participants**\n   - Executes a SQL query to retrieve all participant records from the database.\n\n3. **🧮 Format Participant Data**\n   - Redacts personal details (e.g., masks WhatsApp numbers).\n   - Encodes the `id` using Base64 for privacy and uniqueness.\n\n4. **📤 Render Giveaway App**\n   - Returns an HTML-based Single Page Application with the participant list included.\n   - Allows the host to click a button to pick random winners live."
      },
      "typeVersion": 1
    },
    {
      "id": "f166d098-c4c9-470f-9bb2-afbf7e9df119",
      "name": "付箋3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1500,
        980
      ],
      "parameters": {
        "width": 660,
        "height": 480,
        "content": "# Preview\n![Preview](https://raw.githubusercontent.com/Ficky-Dev/images/refs/heads/main/Meetup%20Giveaway.gif)"
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "pinData": {},
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "5e3676e8-9daa-402d-bdba-994aad9b7596",
  "connections": {
    "8478dcf5-7e9c-471e-b7db-d7b601f4fd58": {
      "main": [
        [
          {
            "node": "6d66e53e-147c-42a8-a742-349901287c96",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "cf039ad9-01ee-4484-ae3d-d0225227da32": {
      "main": [
        [
          {
            "node": "7fba3d0f-8c7b-4f19-8954-9b8ab7a6d95b",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "6d66e53e-147c-42a8-a742-349901287c96": {
      "main": [
        [
          {
            "node": "dc0a7158-2b27-4a83-8fc0-e826ce425b7f",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "dc0a7158-2b27-4a83-8fc0-e826ce425b7f": {
      "main": [
        [
          {
            "node": "0df6e338-46ee-42fc-b2b8-4986e167f271",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "7fba3d0f-8c7b-4f19-8954-9b8ab7a6d95b": {
      "main": [
        [
          {
            "node": "d1387478-3489-4d10-b2a0-910eda73469c",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "d1387478-3489-4d10-b2a0-910eda73469c": {
      "main": [
        [
          {
            "node": "76bd011c-3ace-4094-8fa0-bac818192d9a",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
よくある質問

このワークフローの使い方は?

上記のJSON設定コードをコピーし、n8nインスタンスで新しいワークフローを作成して「JSONからインポート」を選択、設定を貼り付けて認証情報を必要に応じて変更してください。

このワークフローはどんな場面に適していますか?

中級 - その他

有料ですか?

このワークフローは完全無料です。ただし、ワークフローで使用するサードパーティサービス(OpenAI APIなど)は別途料金が発生する場合があります。

ワークフロー情報
難易度
中級
ノード数12
カテゴリー1
ノードタイプ8
難易度説明

経験者向け、6-15ノードの中程度の複雑さのワークフロー

作成者
Ficky

Ficky

@ficky

Turning Tech & AI into Real Business Results I’ve been in software development for over 15 years, helping businesses solve real problems with smart and practical solutions. These days, I focus on automation using tools like n8n, along with custom software and AI. I enjoy making tech work for people in a way that’s clear, useful, and effective.

外部リンク
n8n.ioで表示

このワークフローを共有

カテゴリー

カテゴリー: 34