This workflow corresponds to n8n.io template #10130 — 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 →
{
"id": "",
"meta": {
"templateCredsSetupCompleted": false
},
"name": "Event Badge Generator",
"tags": [
{
"id": "event-registration",
"name": "Event Registration"
},
{
"id": "conference",
"name": "Conference"
},
{
"id": "automation",
"name": "Automation"
},
{
"id": "productivity",
"name": "Productivity"
}
],
"nodes": [
{
"id": "4c1e6d44-4f5e-4f4e-a6ad-038860f9e11f",
"name": "Extract Image URL",
"type": "n8n-nodes-base.httpRequest",
"position": [
2912,
-112
],
"parameters": {
"url": "={{ $json['Badge URL'] }}",
"options": {
"response": {
"response": {
"responseFormat": "file",
"outputPropertyName": "badge"
}
}
}
},
"typeVersion": 4.2
},
{
"id": "f875b20b-393e-470c-8bf9-3c4cdfad8fb7",
"name": "Badge Design",
"type": "n8n-nodes-htmlcsstoimage.htmlCssToImage",
"position": [
2048,
-16
],
"parameters": {
"html_content": "=<!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 <style>\n * {\n margin: 0;\n padding: 0;\n box-sizing: border-box;\n }\n \n body {\n font-family: 'Arial', sans-serif;\n display: flex;\n justify-content: center;\n align-items: center;\n min-height: 100vh;\n background: transparent;\n padding: 20px;\n }\n \n .badge-container {\n width: 400px;\n height: 650px;\n background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n border-radius: 20px;\n padding: 25px;\n box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);\n position: relative;\n overflow: hidden;\n }\n \n .badge-container::before {\n content: '';\n position: absolute;\n top: -50%;\n right: -50%;\n width: 200%;\n height: 200%;\n background: radial-gradient(circle, rgba(255,255,255,0.1) 0%, transparent 70%);\n }\n \n .badge-header {\n text-align: center;\n margin-bottom: 20px;\n position: relative;\n z-index: 1;\n }\n \n .event-logo {\n width: 70px;\n height: 70px;\n background: white;\n border-radius: 50%;\n margin: 0 auto 12px;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 32px;\n font-weight: bold;\n color: #667eea;\n box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2);\n }\n \n .event-title {\n font-size: 22px;\n font-weight: bold;\n color: white;\n text-transform: uppercase;\n letter-spacing: 2px;\n margin-bottom: 5px;\n }\n \n .event-date {\n font-size: 13px;\n color: rgba(255, 255, 255, 0.9);\n font-weight: 500;\n }\n \n .badge-body {\n background: white;\n border-radius: 15px;\n padding: 25px 20px;\n text-align: center;\n position: relative;\n z-index: 1;\n box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);\n }\n \n .attendee-photo {\n width: 100px;\n height: 100px;\n border-radius: 50%;\n margin: 0 auto 15px;\n background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 42px;\n color: white;\n font-weight: bold;\n border: 4px solid #f0f0f0;\n }\n \n .attendee-name {\n font-size: 26px;\n font-weight: bold;\n color: #2d3748;\n margin-bottom: 6px;\n line-height: 1.2;\n }\n \n .attendee-role {\n font-size: 15px;\n color: #718096;\n margin-bottom: 18px;\n font-weight: 500;\n }\n \n .qr-code-container {\n margin: 20px auto 12px;\n padding: 12px;\n background: #f7fafc;\n border-radius: 10px;\n display: inline-block;\n }\n \n .qr-code-container img {\n width: 140px;\n height: 140px;\n display: block;\n }\n \n .attendee-id {\n font-size: 11px;\n color: #a0aec0;\n font-weight: 600;\n letter-spacing: 1px;\n margin-top: 8px;\n }\n \n .badge-footer {\n text-align: center;\n margin-top: 18px;\n position: relative;\n z-index: 1;\n }\n \n .badge-footer p {\n font-size: 10px;\n color: rgba(255, 255, 255, 0.85);\n line-height: 1.4;\n }\n </style>\n</head>\n<body>\n <div class=\"badge-container\">\n <div class=\"badge-header\">\n <div class=\"event-logo\">{{ $json.initials }}</div>\n <div class=\"event-title\">{{ $json.event }}</div>\n <div class=\"event-date\">{{ $json.eventDate }}</div>\n </div>\n \n <div class=\"badge-body\">\n <div class=\"attendee-photo\">{{ $json.initials }}</div>\n <div class=\"attendee-name\">{{ $json.name }}</div>\n <div class=\"attendee-role\">{{ $json.role }}</div>\n \n <div class=\"qr-code-container\">\n <img src=\"{{ $json.qrCodeUrl }}\" alt=\"QR Code\">\n </div>\n \n <div class=\"attendee-id\">ID: {{ $json.attendeeId }}</div>\n </div>\n \n <div class=\"badge-footer\">\n <p>Please present this badge at the entrance<br>Valid for event duration only</p>\n </div>\n </div>\n</body>\n</html>"
},
"credentials": {
"htmlcsstoimgApi": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "d6843d6d-6411-4183-94b0-338bd2e51324",
"name": "Sticky Note10",
"type": "n8n-nodes-base.stickyNote",
"position": [
240,
-304
],
"parameters": {
"color": 7,
"width": 464,
"height": 500,
"content": "## SETUP CREDENTIALS FIRST\n\n**\ud83d\udd10 HTMLCSStoImage API**\n\u2022 Sign up: https://htmlcsstoimg.com\n\u2022 Get API credentials from dashboard\n\u2022 Add to n8n: Basic Auth credential\n\n**\ud83d\udce7 Gmail OAuth2**\n\u2022 Select: \"Gmail OAuth2 API\"\n\u2022 Connect your Gmail account\n\u2022 Grant send permissions\n\n**\ud83d\udcca Google Sheets API** \n\u2022 Select: \"Google Sheets OAuth2\"\n\u2022 Authenticate with Google\n\u2022 Grant read/write access\n\n**Test each credential before running the workflow**\n\n\n**\ud83d\udca1 Pro Tips:**\n\u2022 Use a dedicated Gmail for automation\n\u2022 Create a new Sheet for each event\n\u2022 Monitor API rate limits"
},
"typeVersion": 1
},
{
"id": "6bdd8ff7-3561-439c-afb9-cfa4ed7828dd",
"name": "Sticky Note9",
"type": "n8n-nodes-base.stickyNote",
"position": [
2624,
112
],
"parameters": {
"color": 7,
"width": 260,
"height": 568,
"content": "\n\n\n\n\n\n\n\n\n\n\n\n\n## ERROR HANDLING\n\nTriggered when badge generation fails\n\nSends admin alert with:\n- Full attendee details\n- Attendee ID\n- Timestamp\n- Possible failure causes\n- Action items\n\nTo: admin@example.com\n\nNext steps:\n- Check API status\n- Review logs\n- Retry manually"
},
"typeVersion": 1
},
{
"id": "116af5fb-934d-435d-8038-bffd493a2f37",
"name": "Sticky Note8",
"type": "n8n-nodes-base.stickyNote",
"position": [
3136,
-416
],
"parameters": {
"color": 7,
"width": 372,
"height": 468,
"content": "## STEP 9: SEND BADGE EMAIL\n\nSends via Gmail with:\n- Personalized HTML email\n- Badge download link\n- Event instructions\n- Check-in details\n- Contact information\n\nTo: Attendee email\nAttachment: Badge PNG from URL\n\nContinue on fail: ON"
},
"typeVersion": 1
},
{
"id": "ee261506-4c6f-4f6a-a30d-cb455be0ddb1",
"name": "Sticky Note7",
"type": "n8n-nodes-base.stickyNote",
"position": [
2848,
-368
],
"parameters": {
"color": 7,
"height": 396,
"content": "## STEP 8: EXTRACT BADGE URL\n\nExtracts image URL from API response\n\nReturns clean data:\n- binary file named badge\n\nUsed for: Logging & email"
},
"typeVersion": 1
},
{
"id": "7c784e20-dd16-4f47-94cc-7c905603ce3e",
"name": "Sticky Note6",
"type": "n8n-nodes-base.stickyNote",
"position": [
2256,
-384
],
"parameters": {
"color": 7,
"width": 272,
"height": 524,
"content": "## STEP 6: CONDITIONAL LOGIC\n\nCONDITIONAL CHECK\n\nVerifies badge generation success\n\nCondition: {{ $json.image_url }} is not empty\n\nTRUE (Green):\n\u2192 Badge generated successfully\n\u2192 Continue to email delivery\n\nFALSE (Red):\n\u2192 Generation failed\n\u2192 Send error alert to admin"
},
"typeVersion": 1
},
{
"id": "e44f9c73-c536-4304-8f18-3a5efea15d8c",
"name": "Sticky Note5",
"type": "n8n-nodes-base.stickyNote",
"position": [
1984,
-368
],
"parameters": {
"color": 7,
"height": 500,
"content": "## STEP 5: BUILD HTML BADGE\n\nUses HTMLCSStoImage AP\n\nSends:\n- Full HTML code\n- Viewport: 400x680px\n\nReturns: Image URL\n\nAuth: Basic Auth with API credentials\n\nContinue on fail: ON"
},
"typeVersion": 1
},
{
"id": "f450caab-0b6b-42ce-828e-d1bcffb4ef28",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
1680,
-256
],
"parameters": {
"color": 7,
"width": 288,
"height": 368,
"content": "## STEP 4: PREPARE QR URL\n\nConverts binary QR to accessible URL\n\nCreates URL:\nhttps://api.qrserver.com/...?data=ATD-XXX\n\nUsed for: Embedding in HTML badge template"
},
"typeVersion": 1
},
{
"id": "ae2d3024-f48b-4fc9-844b-c8fe61350c64",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
1424,
-352
],
"parameters": {
"color": 7,
"height": 492,
"content": "## STEP 3: QR CODE GENERATION\n\nCreates QR code via qrserver.com API\n\nParameters:\n- Size: 300x300px\n- Data: Attendee ID\n- Format: PNG image\n\nOutput: Binary QR code file\n\nContinue on fail: ON"
},
"typeVersion": 1
},
{
"id": "aedbf094-b3b9-4230-ac41-9f516fe5ad5d",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
1136,
-400
],
"parameters": {
"color": 7,
"width": 256,
"height": 528,
"content": "## STEP 2: DATA VALIDATION\n\nOperations:\n\u2713 Validates email format\n\u2713 Checks name exists\n\u2713 Generates unique attendee ID\n\u2713 Capitalizes name properly\n\u2713 Extracts initials (2 letters)\n\u2713 Normalizes email to lowercase\n\u2713 Sets default event/role if missing\n\u2713 Adds timestamp\n\nThrows error if:\n- Email invalid\n- Name missing"
},
"typeVersion": 1
},
{
"id": "2d4702e5-361d-4259-b590-2566225db67e",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
752,
-304
],
"parameters": {
"color": 7,
"width": 368,
"height": 420,
"content": "## STEP 1: WEBHOOK TRIGGER\n\n**Test with cURL:**\n```bash\ncurl -X POST https://your-n8n.com/webhook/admissio\n-H \"Content-Type: application/json\" \\\n-d '{\n \"name\": \"Jane Smith\",\n \"email\": \"your-email@gmail.com\",\n \"event\": \"TechCon 2025\",\n \"role\": \"VIP Speaker\"\n}'\n```"
},
"typeVersion": 1
},
{
"id": "9af27c62-c599-4ace-88b5-2f59ade4770e",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
336,
-960
],
"parameters": {
"color": 7,
"width": 380,
"height": 588,
"content": "## WORKFLOW OVERVIEW\n\n**Purpose:** Automated event badge generation system\n\n**Processing Time:** 5-8 seconds end-to-end\n\n**Workflow Steps:**\n1. Receive registration data via webhook (POST)\n2. Validate email and format inputs\n3. Generate unique QR code with attendee ID\n4. Create custom HTML badge design\n5. Convert HTML to downloadable PNG\n6. Log all data to Google Sheets\n7. Send badge via email with instructions\n\n**Success Path:**\n\u2705 Valid data \u2192 Badge generated \u2192 Email sent\n\n**Error Path:**\n\u274c Invalid data \u2192 Workflow stopped \u2192 Error logged\n\n**Perfect For:**\n\u2022 Universities & colleges\n\u2022 Corporate events\n\u2022 Conferences & seminars\n\u2022 Training programs"
},
"typeVersion": 1
},
{
"id": "10d6aab4-3b05-45e7-a9f2-a724bc4788f6",
"name": "Send Error Alert",
"type": "n8n-nodes-base.gmail",
"position": [
2688,
128
],
"parameters": {
"sendTo": "admin@example.com",
"message": "=<!DOCTYPE html>\n<html>\n<head>\n <style>\n body { font-family: Arial, sans-serif; line-height: 1.6; color: #333; }\n .container { max-width: 600px; margin: 0 auto; padding: 20px; }\n .alert-header { background: #dc3545; color: white; padding: 20px; text-align: center; border-radius: 8px 8px 0 0; }\n .alert-content { background: #f8d7da; padding: 20px; border: 1px solid #f5c6cb; border-radius: 0 0 8px 8px; }\n .info-box { background: white; padding: 15px; border-radius: 5px; margin: 15px 0; }\n .info-row { padding: 8px 0; border-bottom: 1px solid #dee2e6; }\n .label { font-weight: bold; color: #495057; }\n .value { color: #212529; }\n </style>\n</head>\n<body>\n <div class=\"container\">\n <div class=\"alert-header\">\n <h2>\u26a0\ufe0f Badge Generation Failed</h2>\n </div>\n \n <div class=\"alert-content\">\n <p><strong>A badge generation request has failed.</strong></p>\n \n <div class=\"info-box\">\n <h3>Attendee Details:</h3>\n <div class=\"info-row\">\n <span class=\"label\">Name:</span>\n <span class=\"value\">{{ $('Validate & Sanitize').item.json.name }}</span>\n </div>\n <div class=\"info-row\">\n <span class=\"label\">Email:</span>\n <span class=\"value\">{{ $('Validate & Sanitize').item.json.email }}</span>\n </div>\n <div class=\"info-row\">\n <span class=\"label\">Event:</span>\n <span class=\"value\">{{ $('Validate & Sanitize').item.json.event }}</span>\n </div>\n <div class=\"info-row\">\n <span class=\"label\">Role:</span>\n <span class=\"value\">{{ $('Validate & Sanitize').item.json.role }}</span>\n </div>\n <div class=\"info-row\">\n <span class=\"label\">Attendee ID:</span>\n <span class=\"value\">{{ $('Validate & Sanitize').item.json.attendeeId }}</span>\n </div>\n <div class=\"info-row\">\n <span class=\"label\">Timestamp:</span>\n <span class=\"value\">{{ $('Validate & Sanitize').item.json.timestamp }}</span>\n </div>\n </div>\n \n <h3>Possible Causes:</h3>\n <ul>\n <li>HTMLCSStoImage API is down or rate limited</li>\n <li>API credentials expired or invalid</li>\n <li>Network connectivity issues</li>\n <li>Invalid HTML in badge template</li>\n </ul>\n \n <h3>Action Required:</h3>\n <ol>\n <li>Check n8n workflow execution logs</li>\n <li>Verify HTMLCSStoImage API status</li>\n <li>Manually regenerate badge for this attendee</li>\n <li>Contact attendee if urgent</li>\n </ol>\n \n <p><strong>Workflow Name:</strong> Event Badge Generator</p>\n <p><strong>n8n Instance:</strong> n8n.mediajade.com</p>\n </div>\n </div>\n</body>\n</html>",
"options": {},
"subject": "\u26a0\ufe0f Badge Generation Failed"
},
"credentials": {
"gmailOAuth2": {
"name": "<your credential>"
}
},
"typeVersion": 2.1
},
{
"id": "f1a3b78b-c10f-4595-9339-963b6f298d24",
"name": "Send Badge Email",
"type": "n8n-nodes-base.gmail",
"onError": "continueRegularOutput",
"position": [
3216,
-112
],
"parameters": {
"sendTo": "={{ $json.Email }}",
"message": "=<!DOCTYPE html>\n<html>\n<head>\n <style>\n body { font-family: Arial, sans-serif; line-height: 1.6; color: #333; }\n .container { max-width: 600px; margin: 0 auto; padding: 20px; }\n .header { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; padding: 30px; text-align: center; border-radius: 10px 10px 0 0; }\n .content { background: #f7fafc; padding: 30px; }\n .badge-info { background: white; padding: 20px; border-radius: 10px; margin: 20px 0; }\n .badge-info h3 { color: #667eea; margin-bottom: 15px; }\n .info-row { display: flex; justify-content: space-between; padding: 8px 0; border-bottom: 1px solid #e2e8f0; }\n .info-label { font-weight: bold; color: #4a5568; }\n .info-value { color: #2d3748; }\n .button { display: inline-block; background: #667eea; color: white; padding: 15px 30px; text-decoration: none; border-radius: 8px; margin: 20px 0; font-weight: bold; }\n .instructions { background: #fff3cd; padding: 15px; border-radius: 8px; border-left: 4px solid #ffc107; margin: 20px 0; }\n .footer { text-align: center; padding: 20px; color: #718096; font-size: 14px; }\n </style>\n</head>\n<body>\n <div class=\"container\">\n <div class=\"header\">\n <h1>\ud83c\udf89 Your Event Badge is Ready!</h1>\n <p>Welcome to {{ $json.Event }}</p>\n </div>\n \n <div class=\"content\">\n <p>Hello <strong>{{ $json.Name }}</strong>,</p>\n \n <p>Great news! Your personalized event badge for <strong>{{ $json.Event }}</strong> has been generated successfully.</p>\n \n <div class=\"badge-info\">\n <h3>\ud83d\udccb Your Badge Details</h3>\n <div class=\"info-row\">\n <span class=\"info-label\">Name:</span>\n <span class=\"info-value\">{{ $json.Name }}</span>\n </div>\n <div class=\"info-row\">\n <span class=\"info-label\">Role:</span>\n <span class=\"info-value\">{{ $json.Role }}</span>\n </div>\n <div class=\"info-row\">\n <span class=\"info-label\">Attendee ID:</span>\n <span class=\"info-value\">{{ $json['Attendee ID'] }}</span>\n </div>\n <div class=\"info-row\">\n <span class=\"info-label\">Event:</span>\n <span class=\"info-value\">{{ $json.Event }}</span>\n </div>\n </div>\n \n <div style=\"text-align: center;\">\n <a href=\"{{ $json['Badge URL'] }}\" class=\"button\">\ud83d\udce5 Download Your Badge</a>\n </div>\n \n <div class=\"instructions\">\n <h4>\ud83d\udccc Important Instructions:</h4>\n <ul>\n <li><strong>Download</strong> your badge using the button above</li>\n <li><strong>Print</strong> it in color on standard paper OR save it on your phone</li>\n <li><strong>Present</strong> your badge at the event entrance for check-in</li>\n <li>The QR code on your badge will be scanned for quick entry</li>\n </ul>\n </div>\n \n <p><strong>Event Details:</strong></p>\n <ul>\n <li>\ud83d\udcc5 <strong>Date:</strong> October 25-27, 2025</li>\n <li>\ud83d\udccd <strong>Venue:</strong> Convention Center</li>\n <li>\ud83d\udd50 <strong>Check-in:</strong> Opens 8:00 AM daily</li>\n </ul>\n \n <p>If you have any questions or need assistance, please reply to this email or contact our support team.</p>\n \n <p>We look forward to seeing you at the event! \ud83c\udf8a</p>\n \n <p>Best regards,<br>\n <strong>TechCon 2025 Team</strong></p>\n </div>\n \n <div class=\"footer\">\n <p>This is an automated email. Please do not reply to this message.</p>\n <p>\u00a9 2025 TechCon. All rights reserved.</p>\n </div>\n </div>\n</body>\n</html>",
"options": {
"attachmentsUi": {
"attachmentsBinary": [
{
"property": "badge"
}
]
}
},
"subject": "=Your Event Badge for {{ $json.Event }} \ud83c\udfab"
},
"credentials": {
"gmailOAuth2": {
"name": "<your credential>"
}
},
"typeVersion": 2.1
},
{
"id": "160ee018-7b7f-40ef-b448-f453e5ffadb2",
"name": "Log to Sheets",
"type": "n8n-nodes-base.googleSheets",
"onError": "continueRegularOutput",
"position": [
2672,
-112
],
"parameters": {
"columns": {
"value": {
"Name": "={{ $('Prepare QR URL').item.json.name }}",
"Role": "={{ $('Prepare QR URL').item.json.role }}",
"Email": "={{ $('Prepare QR URL').item.json.email }}",
"Event": "={{ $('Prepare QR URL').item.json.event }}",
"Status": "Sent",
"Badge URL": "={{ $json.image_url }}",
"Timestamp": "={{ $('Prepare QR URL').item.json.timestamp }}",
"Attendee ID": "={{ $('Prepare QR URL').item.json.attendeeId }}"
},
"schema": [
{
"id": "Name",
"type": "string",
"display": true,
"required": false,
"displayName": "Name",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Email",
"type": "string",
"display": true,
"required": false,
"displayName": "Email",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Event",
"type": "string",
"display": true,
"required": false,
"displayName": "Event",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Role",
"type": "string",
"display": true,
"required": false,
"displayName": "Role",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Attendee ID",
"type": "string",
"display": true,
"required": false,
"displayName": "Attendee ID",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Badge URL",
"type": "string",
"display": true,
"required": false,
"displayName": "Badge URL",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Timestamp",
"type": "string",
"display": true,
"required": false,
"displayName": "Timestamp",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Status",
"type": "string",
"display": true,
"required": false,
"displayName": "Status",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "defineBelow",
"matchingColumns": [],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"operation": "append",
"sheetName": {
"__rl": true,
"mode": "list",
"value": "gid=0",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/YOUR_GOOGLE_SHEETS_ID/edit#gid=0",
"cachedResultName": "BadgesLog"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "YOUR_GOOGLE_SHEETS_ID",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/YOUR_GOOGLE_SHEETS_ID/edit?usp=drivesdk",
"cachedResultName": "Event Badge Tracker"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.4
},
{
"id": "b06c61ed-c72a-434f-8963-8a9d971553e1",
"name": "Is Badge Generated?",
"type": "n8n-nodes-base.if",
"position": [
2352,
-16
],
"parameters": {
"conditions": {
"string": [
{
"value1": "={{ $json.image_url }}",
"operation": "isNotEmpty"
}
]
}
},
"typeVersion": 1
},
{
"id": "046da474-268b-4274-9741-6c73fa1cc462",
"name": "Prepare QR URL",
"type": "n8n-nodes-base.code",
"position": [
1760,
-16
],
"parameters": {
"jsCode": "// Get attendee data from previous node\nconst data = $input.first().json;\n\n// Create QR code URL that can be used in HTML\nconst qrCodeUrl = `https://api.qrserver.com/v1/create-qr-code/?size=300x300&data=${encodeURIComponent(data.attendeeId)}`;\n\n// Return all data with QR URL\nreturn {\n name: data.name,\n email: data.email,\n event: data.event,\n role: data.role,\n attendeeId: data.attendeeId,\n initials: data.initials,\n eventDate: data.eventDate,\n timestamp: data.timestamp,\n qrCodeUrl: qrCodeUrl\n};"
},
"typeVersion": 2
},
{
"id": "ae88dca5-7d9d-47cc-a26c-99b1fd937476",
"name": "Generate QR Code",
"type": "n8n-nodes-base.httpRequest",
"onError": "continueRegularOutput",
"position": [
1504,
-16
],
"parameters": {
"url": "https://api.qrserver.com/v1/create-qr-code/",
"options": {
"response": {
"response": {
"responseFormat": "file",
"outputPropertyName": "qrcode"
}
}
},
"sendQuery": true,
"queryParameters": {
"parameters": [
{
"name": "size",
"value": "300x300"
},
{
"name": "data",
"value": "={{ $json.attendeeId }}"
}
]
}
},
"typeVersion": 4.2
},
{
"id": "fbd2eb39-1544-4697-8a48-21439fd1eddc",
"name": "Validate & Sanitize",
"type": "n8n-nodes-base.code",
"position": [
1232,
-16
],
"parameters": {
"jsCode": "// Get input data from webhook body\nconst webhookData = $input.item.json.body;\n\n// Validation function\nfunction validateEmail(email) {\n const emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n return emailRegex.test(email);\n}\n\n// Extract and validate data\nconst name = webhookData.name?.trim() || '';\nconst email = webhookData.email?.trim().toLowerCase() || '';\nconst eventTitle = webhookData.event || 'TechCon 2025';\nconst role = webhookData.role || 'Attendee';\n\n// Check for required fields\nif (!name) {\n throw new Error('Name is required');\n}\n\nif (!email || !validateEmail(email)) {\n throw new Error('Valid email is required');\n}\n\n// Generate unique attendee ID\nconst attendeeId = 'ATD-' + Date.now().toString(36).toUpperCase() + '-' + Math.random().toString(36).substr(2, 4).toUpperCase();\n\n// Capitalize name properly\nconst capitalizedName = name\n .toLowerCase()\n .split(' ')\n .map(word => word.charAt(0).toUpperCase() + word.slice(1))\n .join(' ');\n\n// Get initials for badge\nconst initials = capitalizedName\n .split(' ')\n .map(word => word[0])\n .join('')\n .toUpperCase()\n .substr(0, 2);\n\n// Current date for event\nconst eventDate = 'October 25-27, 2025';\n\n// Return sanitized data\nreturn {\n name: capitalizedName,\n email: email,\n event: eventTitle,\n role: role,\n attendeeId: attendeeId,\n initials: initials,\n eventDate: eventDate,\n timestamp: new Date().toISOString()\n};"
},
"typeVersion": 2
},
{
"id": "3855779b-e567-4b44-8ac8-18ea02328f5c",
"name": "Webhook",
"type": "n8n-nodes-base.webhook",
"position": [
992,
-16
],
"parameters": {
"path": "new-attendee",
"options": {},
"httpMethod": "POST"
},
"typeVersion": 1.1
},
{
"id": "dd40ecde-5b4c-455d-998f-06c3f8b15a23",
"name": "Sticky Note11",
"type": "n8n-nodes-base.stickyNote",
"position": [
2576,
-448
],
"parameters": {
"color": 7,
"height": 480,
"content": "## STEP 9: LOG TO GOOGLE SHEETS\n\nAppends row to tracking sheet:\n- Name\n- Email\n- Event\n- Role\n- Attendee ID\n- Badge URL\n- Timestamp\n\nSheet: Event Badge Tracker\nContinue on fail: ON"
},
"typeVersion": 1
}
],
"active": false,
"settings": {
"executionOrder": "v1"
},
"versionId": "",
"connections": {
"Webhook": {
"main": [
[
{
"node": "Validate & Sanitize",
"type": "main",
"index": 0
}
]
]
},
"Badge Design": {
"main": [
[
{
"node": "Is Badge Generated?",
"type": "main",
"index": 0
}
]
]
},
"Log to Sheets": {
"main": [
[
{
"node": "Extract Image URL",
"type": "main",
"index": 0
}
]
]
},
"Prepare QR URL": {
"main": [
[
{
"node": "Badge Design",
"type": "main",
"index": 0
}
]
]
},
"Generate QR Code": {
"main": [
[
{
"node": "Prepare QR URL",
"type": "main",
"index": 0
}
]
]
},
"Extract Image URL": {
"main": [
[
{
"node": "Send Badge Email",
"type": "main",
"index": 0
}
]
]
},
"Is Badge Generated?": {
"main": [
[
{
"node": "Log to Sheets",
"type": "main",
"index": 0
}
],
[
{
"node": "Send Error Alert",
"type": "main",
"index": 0
}
]
]
},
"Validate & Sanitize": {
"main": [
[
{
"node": "Generate QR Code",
"type": "main",
"index": 0
}
]
]
}
}
}
Credentials you'll need
Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.
gmailOAuth2googleSheetsOAuth2ApihtmlcsstoimgApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
Streamline your event registration process with this fully automated badge generation system. Perfect for conferences, seminars, corporate events, universities, and training programs. Receives Registration Data via webhook (POST request) Validates & Sanitizes attendee…
Source: https://n8n.io/workflows/10130/ — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
This workflow automates the entire pre-issuance process of workshop participation certificates. When an attendee submits a registration form via a webhook, the workflow validates the data, verifies th
Automated Email Verification & Digital Health Card Generator
Simplify employee performance reviews with AI-powered automation. This workflow transforms raw feedback and evaluation inputs into clear, structured, and professional performance review summaries — sa
Verify candidate emails and auto-generate beautiful resume cards. Validates deliverability, creates professional PNG cards, and emails them instantly.
Overview