AutomationFlowsEmail & Gmail › Automate Event Registration and Qr Check-ins with Google Sheets, Gmail, and…

Automate Event Registration and Qr Check-ins with Google Sheets, Gmail, and…

Original n8n title: Automate Event Registration and Qr Check-ins with Google Sheets, Gmail, and Slack

Bymasahiro hanawa @masahiro on n8n.io

Who is this for? This template is ideal for event organizers, conference managers, and community teams who need an automated participant management system. Perfect for workshops, conferences, meetups, or any event requiring registration and check-in tracking. What this workflow…

Webhook trigger★★★★☆ complexity26 nodesGoogle SheetsHTTP RequestGmailSlack
Email & Gmail Trigger: Webhook Nodes: 26 Complexity: ★★★★☆ Added:

This workflow corresponds to n8n.io template #11821 — we link there as the canonical source.

This workflow follows the Gmail → Google Sheets recipe pattern — see all workflows that pair these two integrations.

The workflow JSON

Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →

Download .json
{
  "nodes": [
    {
      "id": "f2a4e703-2598-414b-8e2c-a43317171315",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -304,
        -128
      ],
      "parameters": {
        "width": 400,
        "height": 880,
        "content": "## Manage event participants and process QR code check-ins\n\n### Who is this for?\nEvent organizers, conference managers, and community teams who need automated participant management with registration and check-in tracking.\n\n### What this workflow does\n**Registration Flow:**\n- Receives registration via webhook\n- Generates unique ticket ID and QR code\n- Stores in Google Sheets and sends confirmation email\n\n**Check-in Flow:**\n- Decodes scanned QR code\n- Validates ticket and blocks duplicates\n- Sends Slack alerts for VIP arrivals\n- Returns attendance statistics\n\n### Setup\n1. Create Google Sheet with participant columns\n2. Connect Google Sheets and Gmail credentials\n3. Configure Slack for VIP notifications\n\n### Requirements\n- Google Sheets\n- Gmail account\n- Slack workspace"
      },
      "typeVersion": 1
    },
    {
      "id": "1228946c-c619-4a3d-afa3-5245cd52ea41",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        176,
        -128
      ],
      "parameters": {
        "color": 7,
        "width": 280,
        "height": 80,
        "content": "**Step 1: Registration**\nReceive participant data, create ticket ID, and save to Google Sheets."
      },
      "typeVersion": 1
    },
    {
      "id": "f58e2b56-ebf4-4d98-957e-f2c387de94d9",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        672,
        -128
      ],
      "parameters": {
        "color": 7,
        "width": 300,
        "height": 80,
        "content": "**Step 2: QR Code & Email**\nGenerate QR code with ticket data and send confirmation email with attachment."
      },
      "typeVersion": 1
    },
    {
      "id": "a2a90ffa-427f-4aae-b5bf-a367859b08fe",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        160,
        368
      ],
      "parameters": {
        "color": 7,
        "width": 280,
        "height": 96,
        "content": "**Step 3: Check-in Validation**\nDecode QR, validate ticket, and check for duplicate entries."
      },
      "typeVersion": 1
    },
    {
      "id": "c4eb5603-e201-4939-a695-e23f4783db98",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1488,
        192
      ],
      "parameters": {
        "color": 7,
        "width": 260,
        "height": 80,
        "content": "**Step 4: VIP Handling**\nDetect VIP tickets and send Slack notification to event staff."
      },
      "typeVersion": 1
    },
    {
      "id": "7708123a-6137-4f8a-8454-808d91bf4dd8",
      "name": "Registration Webhook",
      "type": "n8n-nodes-base.webhook",
      "position": [
        176,
        -16
      ],
      "parameters": {
        "path": "event-register",
        "options": {},
        "httpMethod": "POST",
        "responseMode": "responseNode"
      },
      "typeVersion": 2
    },
    {
      "id": "6305126d-eab7-49a6-98cf-2384615bdf76",
      "name": "Create Ticket Data",
      "type": "n8n-nodes-base.set",
      "position": [
        400,
        -16
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "1",
              "name": "ticketId",
              "type": "string",
              "value": "={{ 'TKT-' + $json.body.eventId + '-' + $now.format('HHmmssSSS') }}"
            },
            {
              "id": "2",
              "name": "eventId",
              "type": "string",
              "value": "={{ $json.body.eventId }}"
            },
            {
              "id": "3",
              "name": "participantName",
              "type": "string",
              "value": "={{ $json.body.name }}"
            },
            {
              "id": "4",
              "name": "email",
              "type": "string",
              "value": "={{ $json.body.email }}"
            },
            {
              "id": "5",
              "name": "ticketType",
              "type": "string",
              "value": "={{ $json.body.ticketType || 'standard' }}"
            },
            {
              "id": "6",
              "name": "registeredAt",
              "type": "string",
              "value": "={{ $now.toISO() }}"
            },
            {
              "id": "7",
              "name": "checkedIn",
              "type": "string",
              "value": "no"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "e9a53078-081a-4cf2-8bad-47b0b6fc94c0",
      "name": "Save to Participants Sheet",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        624,
        -16
      ],
      "parameters": {
        "columns": {
          "value": {
            "Name": "={{ $json.participantName }}",
            "Email": "={{ $json.email }}",
            "Event ID": "={{ $json.eventId }}",
            "Ticket ID": "={{ $json.ticketId }}",
            "Checked In": "={{ $json.checkedIn }}",
            "Ticket Type": "={{ $json.ticketType }}",
            "Check-in Time": "",
            "Registered At": "={{ $json.registeredAt }}"
          },
          "mappingMode": "defineBelow"
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "Participants"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": ""
        }
      },
      "typeVersion": 4.5
    },
    {
      "id": "5cce1cc0-faf8-4527-9eee-37f9e75ab31a",
      "name": "Prepare QR Payload",
      "type": "n8n-nodes-base.code",
      "position": [
        832,
        -16
      ],
      "parameters": {
        "jsCode": "const ticket = $input.first().json;\n\nconst qrPayload = JSON.stringify({\n  t: ticket.ticketId,\n  e: ticket.eventId,\n  n: ticket.participantName.substring(0, 20),\n  ts: Date.now()\n});\n\nconst encodedPayload = Buffer.from(qrPayload).toString('base64');\n\nreturn [{\n  json: {\n    ...ticket,\n    qrData: encodedPayload,\n    qrContent: `https://event.company.com/checkin?code=${encodedPayload}`\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "044255d1-666d-46e1-ba77-0347a16078b7",
      "name": "Generate QR Code",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1056,
        -16
      ],
      "parameters": {
        "url": "=https://api.qrserver.com/v1/create-qr-code/?size=300x300&data={{ encodeURIComponent($json.qrContent) }}",
        "options": {
          "response": {
            "response": {
              "responseFormat": "file"
            }
          }
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "4096158e-0722-4bdb-98b3-cf25b7d61c56",
      "name": "Send Ticket Email",
      "type": "n8n-nodes-base.gmail",
      "position": [
        1280,
        -16
      ],
      "parameters": {
        "sendTo": "={{ $json.email }}",
        "message": "=Hello {{ $json.participantName }},\n\nThank you for registering!\n\nTicket ID: {{ $json.ticketId }}\nTicket Type: {{ $json.ticketType }}\n\nPlease present the attached QR code at the venue entrance.",
        "options": {
          "attachmentsUi": {
            "attachmentsBinary": [
              {}
            ]
          }
        },
        "subject": "=Your Ticket for {{ $json.eventId }}"
      },
      "typeVersion": 2.1
    },
    {
      "id": "39756491-416a-454b-be79-b5a66dd0313f",
      "name": "Registration Success",
      "type": "n8n-nodes-base.respondToWebhook",
      "position": [
        1504,
        -16
      ],
      "parameters": {
        "options": {},
        "respondWith": "json",
        "responseBody": "={{ JSON.stringify({ success: true, ticketId: $json.ticketId, message: 'Ticket sent to ' + $json.email }) }}"
      },
      "typeVersion": 1.1
    },
    {
      "id": "31ba1d12-9c7f-43ca-bc3b-00cf5118d869",
      "name": "Check-in Webhook",
      "type": "n8n-nodes-base.webhook",
      "position": [
        176,
        512
      ],
      "parameters": {
        "path": "event-checkin",
        "options": {},
        "httpMethod": "POST",
        "responseMode": "responseNode"
      },
      "typeVersion": 2
    },
    {
      "id": "c48a2ec3-6cca-4193-bc26-4577e4f88e86",
      "name": "Decode QR Code",
      "type": "n8n-nodes-base.code",
      "position": [
        384,
        512
      ],
      "parameters": {
        "jsCode": "const input = $input.first().json;\nconst qrCode = input.body?.code || input.body?.qrCode || '';\n\nif (!qrCode) {\n  return [{ json: { valid: false, error: 'No QR code provided' } }];\n}\n\ntry {\n  const decoded = Buffer.from(qrCode, 'base64').toString('utf8');\n  const payload = JSON.parse(decoded);\n  \n  return [{\n    json: {\n      valid: true,\n      ticketId: payload.t,\n      eventId: payload.e,\n      participantName: payload.n,\n      scanTime: new Date().toISOString()\n    }\n  }];\n} catch (e) {\n  return [{ json: { valid: false, error: 'Invalid QR code format' } }];\n}"
      },
      "typeVersion": 2
    },
    {
      "id": "2c87839a-641f-4c98-87a8-844b9ad03926",
      "name": "Is Valid QR?",
      "type": "n8n-nodes-base.if",
      "position": [
        608,
        512
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "loose"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "valid",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              },
              "leftValue": "={{ $json.valid }}"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "61304708-30fd-4254-9009-59d738104e0c",
      "name": "Lookup Ticket in DB",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        832,
        400
      ],
      "parameters": {
        "operation": "getMany",
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": ""
        }
      },
      "typeVersion": 4.5
    },
    {
      "id": "ee2e1e8e-8f95-481f-adb0-098778cc016c",
      "name": "Validate Check-in",
      "type": "n8n-nodes-base.code",
      "position": [
        1056,
        400
      ],
      "parameters": {
        "jsCode": "const qrData = $('Decode QR Code').first().json;\nconst ticketRecords = $input.all();\n\nif (ticketRecords.length === 0) {\n  return [{ json: { allowed: false, reason: 'Ticket not found', ticketId: qrData.ticketId } }];\n}\n\nconst ticket = ticketRecords[0].json;\n\nif (ticket['Checked In'] === 'yes') {\n  return [{ json: { \n    allowed: false, \n    reason: 'Already checked in at ' + ticket['Check-in Time'],\n    ticketId: qrData.ticketId,\n    participantName: ticket.Name\n  } }];\n}\n\nreturn [{ json: {\n  allowed: true,\n  ticketId: qrData.ticketId,\n  eventId: ticket['Event ID'],\n  participantName: ticket.Name,\n  ticketType: ticket['Ticket Type'],\n  isVIP: ticket['Ticket Type']?.toLowerCase() === 'vip',\n  checkInTime: qrData.scanTime\n} }];"
      },
      "typeVersion": 2
    },
    {
      "id": "74239af4-ebb7-4771-8f13-aee588c67605",
      "name": "Check-in Allowed?",
      "type": "n8n-nodes-base.if",
      "position": [
        1264,
        400
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "loose"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "allowed",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              },
              "leftValue": "={{ $json.allowed }}"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "100b8983-8cba-4a66-9f0a-7ef4b621be0a",
      "name": "Mark as Checked In",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        1488,
        304
      ],
      "parameters": {
        "columns": {
          "value": {
            "Ticket ID": "={{ $json.ticketId }}",
            "Checked In": "yes",
            "Check-in Time": "={{ $json.checkInTime }}"
          },
          "mappingMode": "defineBelow"
        },
        "options": {},
        "operation": "update",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "Participants"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": ""
        }
      },
      "typeVersion": 4.5
    },
    {
      "id": "1938e6f2-a284-443f-9799-dab383c43f32",
      "name": "Is VIP?",
      "type": "n8n-nodes-base.if",
      "position": [
        1712,
        304
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "loose"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "vip",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              },
              "leftValue": "={{ $json.isVIP }}"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "4b2a9d05-8501-44ae-9556-1ec88156c2c2",
      "name": "Slack VIP Alert",
      "type": "n8n-nodes-base.slack",
      "position": [
        1936,
        208
      ],
      "parameters": {
        "text": "=:star: *VIP Arrival*\n{{ $json.participantName }} has arrived!\nTicket: {{ $json.ticketId }}",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "name",
          "value": "#event-vip"
        },
        "otherOptions": {}
      },
      "typeVersion": 2.2
    },
    {
      "id": "536b9854-756b-489f-a781-9ea15eb60c67",
      "name": "Merge VIP Path",
      "type": "n8n-nodes-base.merge",
      "position": [
        2144,
        304
      ],
      "parameters": {
        "mode": "chooseBranch"
      },
      "typeVersion": 3
    },
    {
      "id": "e27d9c5b-f24c-4c32-b48b-406e79c40438",
      "name": "Build Success Response",
      "type": "n8n-nodes-base.code",
      "position": [
        2368,
        304
      ],
      "parameters": {
        "jsCode": "const checkinData = $('Validate Check-in').first().json;\n\nconst mockAttendance = 245;\nconst capacity = 300;\nconst attendancePercent = (mockAttendance / capacity * 100).toFixed(1);\n\nreturn [{\n  json: {\n    status: 'success',\n    message: `Welcome, ${checkinData.participantName}!`,\n    ticketId: checkinData.ticketId,\n    ticketType: checkinData.ticketType,\n    checkInTime: checkinData.checkInTime,\n    attendanceCount: mockAttendance,\n    capacityPercent: parseFloat(attendancePercent)\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "db1f12e8-a819-49dd-8c57-6fa1da26c0c8",
      "name": "Check-in Success",
      "type": "n8n-nodes-base.respondToWebhook",
      "position": [
        2592,
        304
      ],
      "parameters": {
        "options": {},
        "respondWith": "json",
        "responseBody": "={{ JSON.stringify($json) }}"
      },
      "typeVersion": 1.1
    },
    {
      "id": "477702f1-5df6-48e3-b623-dc904858a2a2",
      "name": "Check-in Denied",
      "type": "n8n-nodes-base.respondToWebhook",
      "position": [
        1488,
        512
      ],
      "parameters": {
        "options": {},
        "respondWith": "json",
        "responseBody": "={{ JSON.stringify({ status: 'denied', reason: $json.reason, ticketId: $json.ticketId }) }}"
      },
      "typeVersion": 1.1
    },
    {
      "id": "7cb84ed5-7834-4815-ae61-e0d09608b9cc",
      "name": "Invalid QR Response",
      "type": "n8n-nodes-base.respondToWebhook",
      "position": [
        832,
        608
      ],
      "parameters": {
        "options": {},
        "respondWith": "json",
        "responseBody": "={{ JSON.stringify({ status: 'error', error: $json.error }) }}"
      },
      "typeVersion": 1.1
    }
  ],
  "connections": {
    "Is VIP?": {
      "main": [
        [
          {
            "node": "Slack VIP Alert",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Merge VIP Path",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Is Valid QR?": {
      "main": [
        [
          {
            "node": "Lookup Ticket in DB",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Invalid QR Response",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Decode QR Code": {
      "main": [
        [
          {
            "node": "Is Valid QR?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge VIP Path": {
      "main": [
        [
          {
            "node": "Build Success Response",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Slack VIP Alert": {
      "main": [
        [
          {
            "node": "Merge VIP Path",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check-in Webhook": {
      "main": [
        [
          {
            "node": "Decode QR Code",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Generate QR Code": {
      "main": [
        [
          {
            "node": "Send Ticket Email",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check-in Allowed?": {
      "main": [
        [
          {
            "node": "Mark as Checked In",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Check-in Denied",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send Ticket Email": {
      "main": [
        [
          {
            "node": "Registration Success",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Validate Check-in": {
      "main": [
        [
          {
            "node": "Check-in Allowed?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Create Ticket Data": {
      "main": [
        [
          {
            "node": "Save to Participants Sheet",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Mark as Checked In": {
      "main": [
        [
          {
            "node": "Is VIP?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prepare QR Payload": {
      "main": [
        [
          {
            "node": "Generate QR Code",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Lookup Ticket in DB": {
      "main": [
        [
          {
            "node": "Validate Check-in",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Registration Webhook": {
      "main": [
        [
          {
            "node": "Create Ticket Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Build Success Response": {
      "main": [
        [
          {
            "node": "Check-in Success",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Save to Participants Sheet": {
      "main": [
        [
          {
            "node": "Prepare QR Payload",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

Who is this for? This template is ideal for event organizers, conference managers, and community teams who need an automated participant management system. Perfect for workshops, conferences, meetups, or any event requiring registration and check-in tracking. What this workflow…

Source: https://n8n.io/workflows/11821/ — original creator credit. Request a take-down →

More Email & Gmail workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

Email & Gmail

Streamline and standardize your entire client onboarding process with a single end-to-end automation. 🚀📋 This workflow captures detailed client intake data via webhook, automatically creates a fully s

Slack, Asana, HTTP Request +4
Email & Gmail

Human Approval AI Response. Uses httpRequest, slack, gmail, googleSheets. Webhook trigger; 20 nodes.

HTTP Request, Slack, Gmail +2
Email & Gmail

Automate WhatsApp communication for recruitment agencies with an interactive, structured customer experience. This workflow handles pricing inquiries, request submissions, tracking, complaints, and hu

HTTP Request, Google Sheets, Gmail +1
Email & Gmail

Suspicious_login_detection. Uses postgres, httpRequest, noOp, html. Webhook trigger; 43 nodes.

Postgres, HTTP Request, Gmail +1
Email & Gmail

This n8n workflow is designed for security monitoring and incident response when suspicious login events are detected. It can be initiated either manually from within the n8n UI for testing or automat

Postgres, HTTP Request, Gmail +1