{"workflow":{"id":13634,"name":"Share time-limited preview links with UploadToURL, SendGrid, and Google Sheets","views":16,"recentViews":0,"totalViews":16,"createdAt":"2026-02-23T11:39:39.667Z","description":"Stop sending sensitive agency drafts as permanent email attachments. This workflow creates a \"self-destructing\" delivery system that hosts files via **UploadToURL**, sends branded previews via **SendGrid**, and automatically expires access after a set duration while logging the entire lifecycle in **Google Sheets**.\n\n## 🎯 What This Workflow Does\n\nTurns any sensitive file into a professional, time-limited client preview:\n\n1. **📝 Captures Delivery Request** - Receives the file (binary or URL), recipient info, and desired expiry duration (e.g., 24 hours) via Webhook.\n2. **☁️ Instant CDN Hosting** - **UploadToURL** hosts the asset and returns a high-speed public link.\n3. **🔑 Secure Token Generation** - Generates a unique hex token and calculates the exact UTC expiry timestamp.\n4. **📊 Real-time Logging** - Records the link in **Google Sheets** as `active` with all metadata before the email is sent.\n5. **📧 Branded Delivery** - Sends a professional HTML email via **SendGrid** featuring your branding, a secure \"View File\" button, and a clear expiry notice.\n6. **⏳ Automated Expiration** - Pauses execution for the specified duration using the **Wait node**, then updates the sheet to `expired` and notifies both the client and the agency.\n\n## ✨ Key Features\n\n- **UploadToURL Integration**: Native community node hosting ensures your files are web-ready instantly without manual cloud storage setup.\n- **Dynamic \"Burner\" Logic**: The link stays active only as long as you specify (from 1 to 168 hours).\n- **Dual-Phase Notifications**: Clients get a polite notice when the link is active and a second one when it has officially expired.\n- **Lifecycle Tracking**: A centralized Google Sheet acts as your \"Delivery Command Center,\" tracking tokens, sent times, and expiry statuses.\n- **Agency Audit Trail**: The agency receives a final summary email once a link's lifecycle is complete, providing a full record for project management.\n\n## 💼 Perfect For\n\n- **Creative Agencies**: Sharing draft designs, videos, or proposals that shouldn't live in a client's inbox forever.\n- **Legal & Finance**: Providing temporary access to sensitive documents or statements.\n- **Freelancers**: Delivering final assets that require a \"preview-only\" window before final payment.\n- **HR Teams**: Sending temporary access to employee handbooks or internal policy drafts.\n\n## 🔧 What You'll Need\n\n### Required Integrations\n- **[UploadToURL](https://uploadtourl.com)** - To host assets and provide secure CDN links.\n- **n8n Community Node** - `n8n-nodes-uploadtourl` must be installed.\n- **SendGrid** - To send the branded preview and expiry emails.\n- **Google Sheets** - To act as the database for link tracking.\n\n### Configuration Variables\n- `GSHEET_SPREADSHEET_ID`: The ID of your tracking sheet.\n- `DEFAULT_EXPIRY_HOURS`: Default time (e.g., 24) if not specified in the webhook.\n- `AGENCY_NAME` & `AGENCY_EMAIL`: For branding the automated emails.\n\n## 🚀 Quick Start\n\n1. **Import Template** - Copy the JSON and import it into your n8n canvas.\n2. **Install Node** - Ensure the **UploadToURL** community node is installed.\n3. **Set Credentials** - Link your UploadToURL, SendGrid, and Google Sheets accounts.\n4. **Prepare Sheet** - Create a sheet named `BurnerLinks` with columns: `Token`, `Recipient Email`, `Status`, `Sent At`, `Expires At`, and `CDN URL`.\n5. **Define Variables** - Update the n8n variables with your Sheet ID and Agency details.\n6. **Deploy** - Activate the workflow and start sending secure, timed previews.\n\n## 🎨 Customization Options\n\n- **Branding**: Edit the `Generate Link Record` code node to update the HTML/CSS for the email templates to match your brand colors.\n- **Extended Wait**: For links lasting weeks, ensure your n8n instance is configured to persist executions across restarts.\n- **Slack Alerts**: Add a Slack node to notify your team the moment a client clicks the link (requires a redirect/tracking layer).\n- **Password Protection**: Integrate an additional layer that requires a password (sent via a separate channel) to view the UploadToURL link.\n\n## 📈 Expected Results\n\n- **Enhanced Security**: Sensitive files no longer float around indefinitely in client inboxes.\n- **Professional Impression**: Clients receive branded, structured previews that emphasize security and professionalism.\n- **Zero Manual Cleanup**: No need to manually delete files or remember to \"turn off\" links.\n- **Complete Transparency**: Always know exactly which links are active and when they were accessed.\n\n## 🏆 Use Cases\n\n### Pitch Deck Delivery\nSend your high-stakes pitch deck with a 48-hour window. The urgency encourages the client to review it promptly while protecting your IP.\n\n### Contract Previews\nShare a draft agreement for a quick 24-hour review. Once the window closes, the client is prompted to contact you for the final version.\n\n### Limited-Time Portfolio\nShare a custom portfolio or \"lookbook\" with a lead, giving them 7 days of access to create a \"limited time\" feel to your availability.\n\n## 💡 Pro Tips\n\n- **Wait Node Execution**: Each link runs as a separate execution. If you send 100 links, you will see 100 \"Waiting\" executions in your history.\n- **File Types**: The workflow includes validation for PDF, JPG, PNG, DOCX, and MP4. You can expand this in the `Validate Payload` code node.\n- **BCC Records**: The workflow automatically BCCs the agency on the first email so you have a copy in your own sent folder.\n\n---\n\n**Ready to secure your deliveries?** Import this template and connect **UploadToURL** to start sending professional \"burner\" links today.\n\n**Questions about the Google Sheet setup?** The workflow includes a detailed sticky note explaining the exact column headers needed for the database sync.","workflow":{"meta":{"instanceId":"277842713620d9f5554de3b1518b865a152c8c4db680008bd8aec536fc18b4a8"},"nodes":[{"id":"17c1d5d4-e36e-4a9b-b940-00c41735e55e","name":"📋 Overview","type":"n8n-nodes-base.stickyNote","position":[-48,96],"parameters":{"width":560,"height":520,"content":"## Share time-limited preview links with UploadToURL, SendGrid, and Google Sheets\nThe Problem: Standard email attachments stay accessible forever, creating security risks and offering no tracking for sensitive agency drafts.\nThe Solution: A \"burner link\" delivery system that hosts files via UploadToURL, emails them via SendGrid, and automatically updates the link status to \"Expired\" in Google Sheets after a set time.\n\n⚙️ How it Works\nWebhook: Receives a file (Binary or URL) and an expiry duration (e.g., 24 hours).\n\nUploadToURL: Hosts the asset instantly and returns a public CDN link.\n\nSendGrid: Emails the branded preview link to the client with an expiry notice.\n\nWait & Expire: The workflow pauses for the set duration, then updates Google Sheets to mark the link as expired.\n\n🔐 Credentials & Setup\nNode: Install n8n-nodes-uploadtourl via Community Nodes.\n\nAPIs: UploadToURL, SendGrid, and Google Sheets.\n\nVariables: Set GSHEET_SPREADSHEET_ID and DEFAULT_EXPIRY_HOURS"},"typeVersion":1},{"id":"f3a0fb13-3e1d-42ea-8502-0ce4b5685712","name":"Section 1 — Upload","type":"n8n-nodes-base.stickyNote","position":[688,640],"parameters":{"color":7,"width":920,"height":493,"content":"## 1 — Upload & link generation\n\n**Webhook → Validate → Has Remote URL? → Upload to URL (×2) → Extract CDN URL → Generate Link Record**\n\nValidates recipient email format and expiry hours (1–168 range). UploadToURL hosts the file via the native community node. The Generate node creates a unique `token` (hex ID), computes `expiresAt` from `expiryHours`, and assembles the full delivery record before anything is sent."},"typeVersion":1},{"id":"351cb3b9-79c6-45fd-8eac-815e2f593050","name":"Section 2 — Log & Send","type":"n8n-nodes-base.stickyNote","position":[1632,704],"parameters":{"color":7,"width":440,"height":419,"content":"## 2 — Log & send\n\n**Sheets - Log Active Link → SendGrid - Send Preview Email**\n\nGoogle Sheets records the link immediately as `active` before the email is sent — so there's always a record even if SendGrid fails. The email is an HTML-formatted preview with the file name, expiry time, project name, and a clear CTA button. The agency receives a BCC copy."},"typeVersion":1},{"id":"cdfd8480-5a9f-4729-a72a-8951574114c0","name":"Section 3 — Wait & Expire","type":"n8n-nodes-base.stickyNote","position":[2544,544],"parameters":{"color":7,"width":712,"height":690,"content":"## 3 — Wait & expire\n\n**Wait Node (configurable duration) → Sheets - Mark Expired → SendGrid - Expiry Notice**\n\nThe Wait node pauses this execution instance for the exact `expiryHours` value. After resuming, the sheet row is updated to `expired` with an `Expired At` timestamp. Two emails fire: a polite expiry notice to the client, and a delivery summary to the agency confirming the link lifecycle is complete."},"typeVersion":1},{"id":"82015827-6144-492b-abff-bee0b98eb1c2","name":"Wait node note","type":"n8n-nodes-base.stickyNote","position":[2096,688],"parameters":{"color":7,"width":356,"height":430,"content":"## ⚙️ Wait node note\n\nThis workflow uses n8n's **Wait** node to pause execution between send and expiry. Each webhook submission runs as its own execution instance — multiple links can be in-flight simultaneously. Requires n8n to be running (cloud or self-hosted with executions enabled). The wait duration is set dynamically from the `expiryHours` field in the webhook payload."},"typeVersion":1},{"id":"4571c524-549e-4598-a56f-0e15afbf052e","name":"Webhook - Create Burner Link","type":"n8n-nodes-base.webhook","position":[688,928],"webhookId":"burner-link-webhook-001","parameters":{"path":"burner-link","options":{"allowedOrigins":"*"},"httpMethod":"POST","responseMode":"responseNode"},"typeVersion":2},{"id":"a72350ee-bfc4-4799-9566-cefec13ed12e","name":"Validate Payload","type":"n8n-nodes-base.code","position":[832,928],"parameters":{"jsCode":"const body = $input.first().json.body || $input.first().json;\n\n// ── Required field checks ────────────────────────────────────\nif (!body.recipientEmail) {\n  throw new Error('recipientEmail is required.');\n}\nif (!body.fileUrl && !body.filename) {\n  throw new Error('Provide either fileUrl (remote file) or filename (binary upload).');\n}\n\n// ── Email format validation ───────────────────────────────────\nconst emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\nif (!emailRegex.test(body.recipientEmail)) {\n  throw new Error(`Invalid recipientEmail: ${body.recipientEmail}`);\n}\n\n// ── Expiry hours — clamp between 1 and 168 (1 week) ──────────\nconst requestedHours = parseFloat(body.expiryHours);\nconst expiryHours = isNaN(requestedHours)\n  ? parseFloat($vars.DEFAULT_EXPIRY_HOURS || '24')\n  : Math.min(168, Math.max(1, requestedHours));\n\n// ── Filename & extension ──────────────────────────────────────\nconst filename = body.filename ||\n  body.fileUrl?.split('?')[0].split('/').pop() ||\n  'preview.pdf';\nconst ext = filename.split('.').pop()?.toLowerCase() || 'pdf';\nconst allowedExts = ['pdf', 'jpg', 'jpeg', 'png', 'docx', 'pptx', 'mp4', 'zip'];\nif (!allowedExts.includes(ext)) {\n  throw new Error(`File type .${ext} not supported. Accepted: ${allowedExts.join(', ')}`);\n}\n\n// ── Sanitise strings ──────────────────────────────────────────\nconst s = v => String(v || '').trim().slice(0, 255);\n\nreturn [{\n  json: {\n    fileUrl: body.fileUrl || null,\n    filename,\n    ext,\n    recipientEmail: body.recipientEmail.toLowerCase().trim(),\n    recipientName: s(body.recipientName) || 'Valued Client',\n    projectName: s(body.projectName) || 'Project Preview',\n    senderName: s(body.senderName) || s($vars.AGENCY_NAME) || 'The Team',\n    agencyEmail: s(body.agencyEmail) || s($vars.AGENCY_EMAIL),\n    expiryHours,\n    message: s(body.message),\n    receivedAt: new Date().toISOString()\n  }\n}];"},"typeVersion":2},{"id":"765d6d43-5953-41cb-8fb9-78749f4c4ca2","name":"Has Remote URL?","type":"n8n-nodes-base.if","position":[976,928],"parameters":{"options":{},"conditions":{"options":{"caseSensitive":false,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"cond-url","operator":{"type":"string","operation":"notEmpty"},"leftValue":"={{ $json.fileUrl }}","rightValue":""}]}},"typeVersion":2},{"id":"4c1525aa-a68f-4ff4-978a-f114f70da134","name":"Upload to URL - Remote","type":"n8n-nodes-uploadtourl.uploadToUrl","position":[1152,816],"parameters":{"operation":"uploadFile"},"credentials":{"uploadToUrlApi":{"id":"aTtpEWKPdBd8vRfH","name":"Upload to URL account 3"}},"typeVersion":1},{"id":"995e4b82-2dde-4a1f-9be7-5ba662423746","name":"Upload to URL - Binary","type":"n8n-nodes-uploadtourl.uploadToUrl","position":[1152,992],"parameters":{"operation":"uploadFile"},"credentials":{"uploadToUrlApi":{"id":"aTtpEWKPdBd8vRfH","name":"Upload to URL account 3"}},"typeVersion":1},{"id":"d10b01dc-82f6-4a59-8204-ab2b51d3ed6a","name":"Extract CDN URL","type":"n8n-nodes-base.code","position":[1328,928],"parameters":{"jsCode":"const uploadResp = $input.first().json;\nconst meta = $('Validate Payload').first().json;\n\nconst cdnUrl =\n  uploadResp.url ||\n  uploadResp.link ||\n  uploadResp.data?.url ||\n  uploadResp.file?.url ||\n  uploadResp.shortUrl;\n\nif (!cdnUrl) {\n  throw new Error('Upload to URL returned no public URL. Raw: ' + JSON.stringify(uploadResp).slice(0, 300));\n}\n\nreturn [{\n  json: {\n    ...meta,\n    cdnUrl: cdnUrl.replace(/^http:\\/\\//, 'https://'),\n    uploadId: uploadResp.id || uploadResp.data?.id || null,\n    fileSizeBytes: uploadResp.size || uploadResp.data?.size || null\n  }\n}];"},"typeVersion":2},{"id":"b8c5df77-1f69-4c7f-a708-52a1e11f5346","name":"Generate Link Record & Email HTML","type":"n8n-nodes-base.code","notes":"Generates a unique hex token and expiry timestamp. Pre-builds all three HTML emails (preview, client expiry notice, agency summary) in one pass so downstream nodes just reference the pre-rendered strings.","position":[1456,928],"parameters":{"jsCode":"const data = $input.first().json;\n\n// ── Generate unique token ─────────────────────────────────────\n// Hex token built from timestamp + random component\nconst randomPart = Math.random().toString(16).slice(2, 10).toUpperCase();\nconst timePart = Date.now().toString(16).toUpperCase();\nconst token = `${timePart}-${randomPart}`;\n\n// ── Compute expiry timestamp ──────────────────────────────────\nconst sentAt = new Date();\nconst expiresAt = new Date(sentAt.getTime() + data.expiryHours * 60 * 60 * 1000);\n\n// ── Human-readable expiry string for emails ───────────────────\nconst formatDate = d => d.toUTCString().replace('GMT', 'UTC');\n\n// ── Compute wait duration in milliseconds for Wait node ───────\nconst waitMs = data.expiryHours * 60 * 60 * 1000;\n\n// ── Build branded preview email HTML ─────────────────────────\nconst previewEmailHtml = `\n<!DOCTYPE html>\n<html>\n<body style=\"font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; max-width: 600px; margin: 0 auto; padding: 32px; color: #1a1a1a;\">\n  <div style=\"border-bottom: 3px solid #4F46E5; padding-bottom: 16px; margin-bottom: 24px;\">\n    <h1 style=\"margin: 0; font-size: 22px; color: #4F46E5;\">${data.senderName}</h1>\n    <p style=\"margin: 4px 0 0; color: #6b7280; font-size: 14px;\">Secure File Preview</p>\n  </div>\n  <p style=\"font-size: 16px;\">Hi ${data.recipientName},</p>\n  <p>You have a new file available for preview:</p>\n  <div style=\"background: #f9fafb; border: 1px solid #e5e7eb; border-radius: 8px; padding: 20px; margin: 20px 0;\">\n    <p style=\"margin: 0 0 8px; font-weight: 600; font-size: 18px;\">📄 ${data.filename}</p>\n    <p style=\"margin: 0; color: #6b7280; font-size: 14px;\">Project: ${data.projectName}</p>\n  </div>\n  ${data.message ? `<p style=\"background: #eff6ff; border-left: 4px solid #4F46E5; padding: 12px 16px; border-radius: 0 6px 6px 0; font-style: italic;\">${data.message}</p>` : ''}\n  <div style=\"text-align: center; margin: 32px 0;\">\n    <a href=\"${data.cdnUrl}\" style=\"background: #4F46E5; color: white; padding: 14px 32px; border-radius: 8px; text-decoration: none; font-weight: 600; font-size: 16px; display: inline-block;\">View File</a>\n  </div>\n  <div style=\"background: #fef3c7; border: 1px solid #fbbf24; border-radius: 6px; padding: 12px 16px; font-size: 13px; color: #92400e;\">\n    ⏱️ <strong>This link expires on ${formatDate(expiresAt)}</strong> (${data.expiryHours} hours from now). After that, you will no longer be able to access this file.\n  </div>\n  <p style=\"font-size: 13px; color: #9ca3af; margin-top: 32px;\">Sent securely via ${data.senderName} · Token: ${token}</p>\n</body>\n</html>`;\n\n// ── Build expiry notification HTML (to client) ────────────────\nconst expiryClientHtml = `\n<!DOCTYPE html>\n<html>\n<body style=\"font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; max-width: 600px; margin: 0 auto; padding: 32px; color: #1a1a1a;\">\n  <div style=\"border-bottom: 3px solid #ef4444; padding-bottom: 16px; margin-bottom: 24px;\">\n    <h1 style=\"margin: 0; font-size: 22px; color: #ef4444;\">Preview Link Expired</h1>\n  </div>\n  <p>Hi ${data.recipientName},</p>\n  <p>The preview link for <strong>${data.filename}</strong> (Project: ${data.projectName}) has now expired and is no longer accessible.</p>\n  <p>If you need continued access to this file, please contact <strong>${data.senderName}</strong>.</p>\n  <p style=\"font-size: 13px; color: #9ca3af;\">Token: ${token} · Expired: ${formatDate(expiresAt)}</p>\n</body>\n</html>`;\n\n// ── Build agency summary HTML ─────────────────────────────────\nconst agencySummaryHtml = `\n<!DOCTYPE html>\n<html>\n<body style=\"font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; max-width: 600px; margin: 0 auto; padding: 32px; color: #1a1a1a;\">\n  <h2>🔒 Link Lifecycle Complete</h2>\n  <table style=\"width: 100%; border-collapse: collapse; font-size: 14px;\">\n    <tr style=\"border-bottom: 1px solid #e5e7eb;\"><td style=\"padding: 8px; color: #6b7280;\">Token</td><td style=\"padding: 8px; font-weight: 600;\">${token}</td></tr>\n    <tr style=\"border-bottom: 1px solid #e5e7eb;\"><td style=\"padding: 8px; color: #6b7280;\">File</td><td style=\"padding: 8px;\">${data.filename}</td></tr>\n    <tr style=\"border-bottom: 1px solid #e5e7eb;\"><td style=\"padding: 8px; color: #6b7280;\">Project</td><td style=\"padding: 8px;\">${data.projectName}</td></tr>\n    <tr style=\"border-bottom: 1px solid #e5e7eb;\"><td style=\"padding: 8px; color: #6b7280;\">Recipient</td><td style=\"padding: 8px;\">${data.recipientName} &lt;${data.recipientEmail}&gt;</td></tr>\n    <tr style=\"border-bottom: 1px solid #e5e7eb;\"><td style=\"padding: 8px; color: #6b7280;\">Sent At</td><td style=\"padding: 8px;\">${formatDate(sentAt)}</td></tr>\n    <tr style=\"border-bottom: 1px solid #e5e7eb;\"><td style=\"padding: 8px; color: #6b7280;\">Expired At</td><td style=\"padding: 8px;\">${formatDate(expiresAt)}</td></tr>\n    <tr><td style=\"padding: 8px; color: #6b7280;\">CDN URL</td><td style=\"padding: 8px; word-break: break-all; font-size: 12px;\">${data.cdnUrl}</td></tr>\n  </table>\n</body>\n</html>`;\n\nreturn [{\n  json: {\n    ...data,\n    token,\n    sentAt: sentAt.toISOString(),\n    expiresAt: expiresAt.toISOString(),\n    expiresAtHuman: formatDate(expiresAt),\n    waitMs,\n    linkStatus: 'active',\n    previewEmailHtml,\n    expiryClientHtml,\n    agencySummaryHtml\n  }\n}];"},"typeVersion":2},{"id":"2407e4af-6584-4f00-a08c-94e36d36284a","name":"Sheets - Log Active Link","type":"n8n-nodes-base.googleSheets","notes":"Logs the link record BEFORE sending the email — ensures a row always exists even if SendGrid fails.","position":[1712,928],"parameters":{"columns":{"value":{"Token":"={{ $json.token }}","Sender":"={{ $json.senderName }}","Status":"active","CDN URL":"={{ $json.cdnUrl }}","Sent At":"={{ $json.sentAt }}","File Name":"={{ $json.filename }}","Expires At":"={{ $json.expiresAt }}","Expiry Hours":"={{ $json.expiryHours }}","Project Name":"={{ $json.projectName }}","Recipient Name":"={{ $json.recipientName }}","File Size Bytes":"={{ $json.fileSizeBytes }}","Recipient Email":"={{ $json.recipientEmail }}"},"mappingMode":"defineBelow"},"options":{},"operation":"append","sheetName":{"__rl":true,"mode":"name","value":"BurnerLinks"},"documentId":{"__rl":true,"mode":"id","value":"={{ $vars.GSHEET_SPREADSHEET_ID }}"}},"credentials":{"googleSheetsOAuth2Api":{"id":"Kz2DdSp11rxqwlFt","name":"Google Sheets account - Deepanshi"}},"typeVersion":4.5},{"id":"aa27043d-01a4-4efa-ada6-81ce4ce6a8ff","name":"SendGrid - Send Preview Email","type":"n8n-nodes-base.sendGrid","notes":"Sends a branded HTML preview email to the client with expiry notice. Agency email is BCC'd for records.","position":[1920,928],"parameters":{},"typeVersion":1},{"id":"b9cbd2f6-b0af-4f65-a6a0-2f7c09258e14","name":"Respond to Webhook","type":"n8n-nodes-base.respondToWebhook","notes":"Returns immediately after the email is sent — before the Wait node fires. The caller gets confirmation without waiting 24 hours for the workflow to complete.","position":[2192,928],"parameters":{"options":{"responseCode":201,"responseHeaders":{"entries":[{"name":"Content-Type","value":"application/json"}]}},"respondWith":"json","responseBody":"={\n  \"success\": true,\n  \"message\": \"Preview link sent to {{ $json.recipientEmail }}\",\n  \"token\": \"{{ $json.token }}\",\n  \"recipientEmail\": \"{{ $json.recipientEmail }}\",\n  \"cdnUrl\": \"{{ $json.cdnUrl }}\",\n  \"expiresAt\": \"{{ $json.expiresAt }}\",\n  \"expiryHours\": {{ $json.expiryHours }},\n  \"projectName\": \"{{ $json.projectName }}\",\n  \"filename\": \"{{ $json.filename }}\"\n}"},"typeVersion":1.1},{"id":"8807a34e-c45c-4b40-9af5-81c5904704ac","name":"Wait - Until Link Expires","type":"n8n-nodes-base.wait","notes":"Pauses this execution instance for the exact expiry duration. Set dynamically from expiryHours. n8n cloud persists the execution automatically; self-hosted requires execution persistence enabled.","position":[2624,928],"webhookId":"3fbc8025-5903-4d00-a066-7106e7179f7c","parameters":{"unit":"milliseconds","amount":"={{ $('Generate Link Record & Email HTML').first().json.waitMs }}"},"typeVersion":1.1},{"id":"6ddd47c7-58c0-4094-9834-965a45279237","name":"Sheets - Mark Link Expired","type":"n8n-nodes-base.googleSheets","position":[2832,928],"parameters":{"columns":{"value":{"Token":"={{ $('Generate Link Record & Email HTML').first().json.token }}","Status":"expired","Expired At":"={{ new Date().toISOString() }}"},"mappingMode":"defineBelow"},"options":{},"operation":"update","sheetName":{"__rl":true,"mode":"name","value":"BurnerLinks"},"documentId":{"__rl":true,"mode":"id","value":"={{ $vars.GSHEET_SPREADSHEET_ID }}"}},"credentials":{"googleSheetsOAuth2Api":{"id":"Kz2DdSp11rxqwlFt","name":"Google Sheets account - Deepanshi"}},"typeVersion":4.5},{"id":"95a593f7-9ccf-4fbf-b5bf-be34023acc05","name":"SendGrid - Notify Client Expired","type":"n8n-nodes-base.sendGrid","position":[3056,816],"parameters":{},"typeVersion":1},{"id":"a4a50667-1ff6-4330-8b6f-8cbb28a1e69c","name":"SendGrid - Agency Summary Email","type":"n8n-nodes-base.sendGrid","notes":"Sends the agency a full lifecycle summary: token, file, recipient, sent time, expired time, and CDN URL.","position":[3072,1040],"parameters":{},"typeVersion":1}],"pinData":{},"connections":{"Extract CDN URL":{"main":[[{"node":"Generate Link Record & Email HTML","type":"main","index":0}]]},"Has Remote URL?":{"main":[[{"node":"Upload to URL - Remote","type":"main","index":0}],[{"node":"Upload to URL - Binary","type":"main","index":0}]]},"Validate Payload":{"main":[[{"node":"Has Remote URL?","type":"main","index":0}]]},"Respond to Webhook":{"main":[[{"node":"Wait - Until Link Expires","type":"main","index":0}]]},"Upload to URL - Binary":{"main":[[{"node":"Extract CDN URL","type":"main","index":0}]]},"Upload to URL - Remote":{"main":[[{"node":"Extract CDN URL","type":"main","index":0}]]},"Sheets - Log Active Link":{"main":[[{"node":"SendGrid - Send Preview Email","type":"main","index":0}]]},"Wait - Until Link Expires":{"main":[[{"node":"Sheets - Mark Link Expired","type":"main","index":0}]]},"Sheets - Mark Link Expired":{"main":[[{"node":"SendGrid - Notify Client Expired","type":"main","index":0},{"node":"SendGrid - Agency Summary Email","type":"main","index":0}]]},"Webhook - Create Burner Link":{"main":[[{"node":"Validate Payload","type":"main","index":0}]]},"SendGrid - Send Preview Email":{"main":[[{"node":"Respond to Webhook","type":"main","index":0}]]},"Generate Link Record & Email HTML":{"main":[[{"node":"Sheets - Log Active Link","type":"main","index":0}]]}}},"lastUpdatedBy":1,"workflowInfo":{"nodeCount":19,"nodeTypes":{"n8n-nodes-base.if":{"count":1},"n8n-nodes-base.code":{"count":3},"n8n-nodes-base.wait":{"count":1},"n8n-nodes-base.webhook":{"count":1},"n8n-nodes-base.sendGrid":{"count":3},"n8n-nodes-base.stickyNote":{"count":5},"n8n-nodes-base.googleSheets":{"count":2},"n8n-nodes-base.respondToWebhook":{"count":1},"n8n-nodes-uploadtourl.uploadToUrl":{"count":2}}},"status":"published","readyToDemo":null,"user":{"name":"Jitesh Dugar","username":"jiteshdugar","bio":"AI Automation Specialist - OpenAI, CRM & Automation Expert with a solid understanding of various tools that include Zapier, Make, Zoho CRM, Hubspot, Google Sheets, Airtable, Pipedrive, Google Analytics, and more.","verified":true,"links":["https://www.linkedin.com/in/jiteshdugar"],"avatar":"https://gravatar.com/avatar/edaa3abb99806b0586dced559d0a5417f24a507e7c4464a63960f0638a4b1b90?r=pg&d=retro&size=200"},"nodes":[{"id":18,"icon":"file:googleSheets.svg","name":"n8n-nodes-base.googleSheets","codex":{"data":{"alias":["CSV","Sheet","Spreadsheet","GS"],"resources":{"generic":[{"url":"https://n8n.io/blog/love-at-first-sight-ricardos-n8n-journey/","icon":"❤️","label":"Love at first sight: Ricardo’s n8n journey"},{"url":"https://n8n.io/blog/why-business-process-automation-with-n8n-can-change-your-daily-life/","icon":"🧬","label":"Why business process automation with n8n can change your daily life"},{"url":"https://n8n.io/blog/automatically-adding-expense-receipts-to-google-sheets-with-telegram-mindee-twilio-and-n8n/","icon":"🧾","label":"Automatically Adding Expense Receipts to Google Sheets with Telegram, Mindee, Twilio, and n8n"},{"url":"https://n8n.io/blog/supercharging-your-conference-registration-process-with-n8n/","icon":"🎫","label":"Supercharging your conference registration process with n8n"},{"url":"https://n8n.io/blog/creating-triggers-for-n8n-workflows-using-polling/","icon":"⏲","label":"Creating triggers for n8n workflows using polling"},{"url":"https://n8n.io/blog/no-code-ecommerce-workflow-automations/","icon":"store","label":"6 e-commerce workflows to power up your Shopify s"},{"url":"https://n8n.io/blog/migrating-community-metrics-to-orbit-using-n8n/","icon":"📈","label":"Migrating Community Metrics to Orbit using n8n"},{"url":"https://n8n.io/blog/automate-google-apps-for-productivity/","icon":"💡","label":"15 Google apps you can combine and automate to increase productivity"},{"url":"https://n8n.io/blog/your-business-doesnt-need-you-to-operate/","icon":" 🖥️","label":"Hey founders! Your business doesn't need you to operate"},{"url":"https://n8n.io/blog/how-honest-burgers-use-automation-to-save-100k-per-year/","icon":"🍔","label":"How Honest Burgers Use Automation to Save $100k per year"},{"url":"https://n8n.io/blog/how-a-digital-strategist-uses-n8n-for-online-marketing/","icon":"💻","label":"How a digital strategist uses n8n for online marketing"},{"url":"https://n8n.io/blog/why-this-product-manager-loves-workflow-automation-with-n8n/","icon":"🧠","label":"Why this Product Manager loves workflow automation with n8n"},{"url":"https://n8n.io/blog/sending-automated-congratulations-with-google-sheets-twilio-and-n8n/","icon":"🙌","label":"Sending Automated Congratulations with Google Sheets, Twilio, and n8n "},{"url":"https://n8n.io/blog/how-a-membership-development-manager-automates-his-work-and-investments/","icon":"📈","label":"How a Membership Development Manager automates his work and investments"},{"url":"https://n8n.io/blog/aws-workflow-automation/","label":"7 no-code workflow automations for Amazon Web Services"}],"primaryDocumentation":[{"url":"https://docs.n8n.io/integrations/builtin/app-nodes/n8n-nodes-base.googlesheets/"}],"credentialDocumentation":[{"url":"https://docs.n8n.io/integrations/builtin/credentials/google/oauth-single-service/"}]},"categories":["Data & Storage","Productivity"],"nodeVersion":"1.0","codexVersion":"1.0"}},"group":"[\"input\",\"output\"]","defaults":{"name":"Google Sheets"},"iconData":{"type":"file","fileBuffer":"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI2MCIgaGVpZ2h0PSI2MCI+PGcgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiPjxwYXRoIGZpbGw9IiMyOEI0NDYiIGQ9Ik0zNS42OSAxIDUyIDE3LjIyNXYzOS4wODdhMy42NyAzLjY3IDAgMCAxLTEuMDg0IDIuNjFBMy43IDMuNyAwIDAgMSA0OC4yOTMgNjBIMTIuNzA3YTMuNyAzLjcgMCAwIDEtMi42MjMtMS4wNzhBMy42NyAzLjY3IDAgMCAxIDkgNTYuMzEyVjQuNjg4YTMuNjcgMy42NyAwIDAgMSAxLjA4NC0yLjYxQTMuNyAzLjcgMCAwIDEgMTIuNzA3IDF6Ii8+PHBhdGggZmlsbD0iIzZBQ0U3QyIgZD0iTTM1LjY5IDEgNTIgMTcuMjI1SDM5LjM5N2MtMi4wNTQgMC0zLjcwNy0xLjgyOS0zLjcwNy0zLjg3MnoiLz48cGF0aCBmaWxsPSIjMjE5QjM4IiBkPSJNMzkuMjExIDE3LjIyNSA1MiAyMi40OHYtNS4yNTV6Ii8+PHBhdGggZmlsbD0iI0ZGRiIgZD0iTTIwLjEyIDMxLjk3NWMwLS44MTcuNjYyLTEuNDc1IDEuNDgzLTEuNDc1aDE3Ljc5NGMuODIxIDAgMS40ODIuNjU4IDEuNDgyIDEuNDc1djE1LjQ4N2MwIC44MTgtLjY2MSAxLjQ3NS0xLjQ4MiAxLjQ3NUgyMS42MDNhMS40NzYgMS40NzYgMCAwIDEtMS40ODItMS40NzRWMzEuOTc0em0yLjIyNSAxLjQ3NWg2LjY3MnYyLjIxMmgtNi42NzJ6bTAgNS4xNjJoNi42NzJ2Mi4yMTNoLTYuNjcyem0wIDUuMTYzaDYuNjcydjIuMjEyaC02LjY3MnptOS42MzgtMTAuMzI1aDYuNjcydjIuMjEyaC02LjY3MnptMCA1LjE2Mmg2LjY3MnYyLjIxM2gtNi42NzJ6bTAgNS4xNjNoNi42NzJ2Mi4yMTJoLTYuNjcyeiIvPjxwYXRoIGZpbGw9IiMyOEI0NDYiIGQ9Ik0zNC42OSAwIDUxIDE2LjIyNXYzOS4wODdhMy42NyAzLjY3IDAgMCAxLTEuMDg0IDIuNjFBMy43IDMuNyAwIDAgMSA0Ny4yOTMgNTlIMTEuNzA3YTMuNyAzLjcgMCAwIDEtMi42MjMtMS4wNzhBMy42NyAzLjY3IDAgMCAxIDggNTUuMzEyVjMuNjg4YTMuNjcgMy42NyAwIDAgMSAxLjA4NC0yLjYxQTMuNyAzLjcgMCAwIDEgMTEuNzA3IDB6Ii8+PHBhdGggZmlsbD0iIzZBQ0U3QyIgZD0iTTM0LjY5IDAgNTEgMTYuMjI1SDM4LjM5N2MtMi4wNTQgMC0zLjcwNy0xLjgyOS0zLjcwNy0zLjg3MnoiLz48cGF0aCBmaWxsPSIjMjE5QjM4IiBkPSJNMzguMjExIDE2LjIyNSA1MSAyMS40OHYtNS4yNTV6Ii8+PHBhdGggZmlsbD0iI0ZGRiIgZD0iTTE5LjEyIDMwLjk3NWMwLS44MTcuNjYyLTEuNDc1IDEuNDgzLTEuNDc1aDE3Ljc5NGMuODIxIDAgMS40ODIuNjU4IDEuNDgyIDEuNDc1djE1LjQ4N2MwIC44MTgtLjY2MSAxLjQ3NS0xLjQ4MiAxLjQ3NUgyMC42MDNhMS40NzYgMS40NzYgMCAwIDEtMS40ODItMS40NzRWMzAuOTc0em0yLjIyNSAxLjQ3NWg2LjY3MnYyLjIxMmgtNi42NzJ6bTAgNS4xNjJoNi42NzJ2Mi4yMTNoLTYuNjcyem0wIDUuMTYzaDYuNjcydjIuMjEyaC02LjY3MnptOS42MzgtMTAuMzI1aDYuNjcydjIuMjEyaC02LjY3MnptMCA1LjE2Mmg2LjY3MnYyLjIxM2gtNi42NzJ6bTAgNS4xNjNoNi42NzJ2Mi4yMTJoLTYuNjcyeiIvPjwvZz48L3N2Zz4="},"displayName":"Google Sheets","typeVersion":5,"nodeCategories":[{"id":3,"name":"Data & Storage"},{"id":4,"name":"Productivity"}]},{"id":20,"icon":"fa:map-signs","name":"n8n-nodes-base.if","codex":{"data":{"alias":["Router","Filter","Condition","Logic","Boolean","Branch"],"details":"The IF node can be used to implement binary conditional logic in your workflow. You can set up one-to-many conditions to evaluate each item of data being inputted into the node. That data will either evaluate to TRUE or FALSE and route out of the node accordingly.\n\nThis node has multiple types of conditions: Bool, String, Number, and Date & Time.","resources":{"generic":[{"url":"https://n8n.io/blog/learn-to-automate-your-factorys-incident-reporting-a-step-by-step-guide/","icon":"🏭","label":"Learn to Automate Your Factory's Incident Reporting: A Step by Step Guide"},{"url":"https://n8n.io/blog/2021-the-year-to-automate-the-new-you-with-n8n/","icon":"☀️","label":"2021: The Year to Automate the New You with n8n"},{"url":"https://n8n.io/blog/why-business-process-automation-with-n8n-can-change-your-daily-life/","icon":"🧬","label":"Why business process automation with n8n can change your daily life"},{"url":"https://n8n.io/blog/create-a-toxic-language-detector-for-telegram/","icon":"🤬","label":"Create a toxic language detector for Telegram in 4 step"},{"url":"https://n8n.io/blog/no-code-ecommerce-workflow-automations/","icon":"store","label":"6 e-commerce workflows to power up your Shopify s"},{"url":"https://n8n.io/blog/how-to-build-a-low-code-self-hosted-url-shortener/","icon":"🔗","label":"How to build a low-code, self-hosted URL shortener in 3 steps"},{"url":"https://n8n.io/blog/automate-your-data-processing-pipeline-in-9-steps-with-n8n/","icon":"⚙️","label":"Automate your data processing pipeline in 9 steps"},{"url":"https://n8n.io/blog/how-to-get-started-with-crm-automation-and-no-code-workflow-ideas/","icon":"👥","label":"How to get started with CRM automation (with 3 no-code workflow ideas"},{"url":"https://n8n.io/blog/5-tasks-you-can-automate-with-notion-api/","icon":"⚡️","label":"5 tasks you can automate with the new Notion API "},{"url":"https://n8n.io/blog/automate-google-apps-for-productivity/","icon":"💡","label":"15 Google apps you can combine and automate to increase productivity"},{"url":"https://n8n.io/blog/automation-for-maintainers-of-open-source-projects/","icon":"🏷️","label":"How to automatically manage contributions to open-source projects"},{"url":"https://n8n.io/blog/how-uproc-scraped-a-multi-page-website-with-a-low-code-workflow/","icon":" 🕸️","label":"How uProc scraped a multi-page website with a low-code workflow"},{"url":"https://n8n.io/blog/5-workflow-automations-for-mattermost-that-we-love-at-n8n/","icon":"🤖","label":"5 workflow automations for Mattermost that we love at n8n"},{"url":"https://n8n.io/blog/why-this-product-manager-loves-workflow-automation-with-n8n/","icon":"🧠","label":"Why this Product Manager loves workflow automation with n8n"},{"url":"https://n8n.io/blog/sending-automated-congratulations-with-google-sheets-twilio-and-n8n/","icon":"🙌","label":"Sending Automated Congratulations with Google Sheets, Twilio, and n8n "},{"url":"https://n8n.io/blog/how-to-set-up-a-ci-cd-pipeline-with-no-code/","icon":"🎡","label":"How to set up a no-code CI/CD pipeline with GitHub and TravisCI"},{"url":"https://n8n.io/blog/benefits-of-automation-and-n8n-an-interview-with-hubspots-hugh-durkin/","icon":"🎖","label":"Benefits of automation and n8n: An interview with HubSpot's Hugh Durkin"},{"url":"https://n8n.io/blog/aws-workflow-automation/","label":"7 no-code workflow automations for Amazon Web Services"}],"primaryDocumentation":[{"url":"https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.if/"}]},"categories":["Core Nodes"],"nodeVersion":"1.0","codexVersion":"1.0","subcategories":{"Core Nodes":["Flow"]}}},"group":"[\"transform\"]","defaults":{"name":"If","color":"#408000"},"iconData":{"icon":"map-signs","type":"icon"},"displayName":"If","typeVersion":2,"nodeCategories":[{"id":9,"name":"Core Nodes"}]},{"id":47,"icon":"file:webhook.svg","name":"n8n-nodes-base.webhook","codex":{"data":{"alias":["HTTP","API","Build","WH"],"resources":{"generic":[{"url":"https://n8n.io/blog/learn-how-to-automatically-cross-post-your-content-with-n8n/","icon":"✍️","label":"Learn how to automatically cross-post your content with n8n"},{"url":"https://n8n.io/blog/running-n8n-on-ships-an-interview-with-maranics/","icon":"🛳","label":"Running n8n on ships: An interview with Maranics"},{"url":"https://n8n.io/blog/how-to-build-a-low-code-self-hosted-url-shortener/","icon":"🔗","label":"How to build a low-code, self-hosted URL shortener in 3 steps"},{"url":"https://n8n.io/blog/what-are-apis-how-to-use-them-with-no-code/","icon":" 🪢","label":"What are APIs and how to use them with no code"},{"url":"https://n8n.io/blog/5-tasks-you-can-automate-with-notion-api/","icon":"⚡️","label":"5 tasks you can automate with the new Notion API "},{"url":"https://n8n.io/blog/how-a-digital-strategist-uses-n8n-for-online-marketing/","icon":"💻","label":"How a digital strategist uses n8n for online marketing"},{"url":"https://n8n.io/blog/the-ultimate-guide-to-automate-your-video-collaboration-with-whereby-mattermost-and-n8n/","icon":"📹","label":"The ultimate guide to automate your video collaboration with Whereby, Mattermost, and n8n"},{"url":"https://n8n.io/blog/how-to-automatically-give-kudos-to-contributors-with-github-slack-and-n8n/","icon":"👏","label":"How to automatically give kudos to contributors with GitHub, Slack, and n8n"},{"url":"https://n8n.io/blog/5-workflow-automations-for-mattermost-that-we-love-at-n8n/","icon":"🤖","label":"5 workflow automations for Mattermost that we love at n8n"},{"url":"https://n8n.io/blog/why-this-product-manager-loves-workflow-automation-with-n8n/","icon":"🧠","label":"Why this Product Manager loves workflow automation with n8n"},{"url":"https://n8n.io/blog/creating-custom-incident-response-workflows-with-n8n/","label":"How to automate every step of an incident response workflow"},{"url":"https://n8n.io/blog/learn-to-build-powerful-api-endpoints-using-webhooks/","icon":"🧰","label":"Learn to Build Powerful API Endpoints Using Webhooks"},{"url":"https://n8n.io/blog/learn-how-to-use-webhooks-with-mattermost-slash-commands/","icon":"🦄","label":"Learn how to use webhooks with Mattermost slash commands"},{"url":"https://n8n.io/blog/how-goomer-automated-their-operations-with-over-200-n8n-workflows/","icon":"🛵","label":"How Goomer automated their operations with over 200 n8n workflows"}],"primaryDocumentation":[{"url":"https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.webhook/"}]},"categories":["Development","Core Nodes"],"nodeVersion":"1.0","codexVersion":"1.0","subcategories":{"Core Nodes":["Helpers"]}}},"group":"[\"trigger\"]","defaults":{"name":"Webhook"},"iconData":{"type":"file","fileBuffer":"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0OCIgaGVpZ2h0PSI0OCI+PHBhdGggZmlsbD0iIzM3NDc0ZiIgZD0iTTM1IDM3Yy0yLjIgMC00LTEuOC00LTRzMS44LTQgNC00IDQgMS44IDQgNC0xLjggNC00IDQiLz48cGF0aCBmaWxsPSIjMzc0NzRmIiBkPSJNMzUgNDNjLTMgMC01LjktMS40LTcuOC0zLjdsMy4xLTIuNWMxLjEgMS40IDIuOSAyLjMgNC43IDIuMyAzLjMgMCA2LTIuNyA2LTZzLTIuNy02LTYtNmMtMSAwLTIgLjMtMi45LjdsLTEuNyAxTDIzLjMgMTZsMy41LTEuOSA1LjMgOS40YzEtLjMgMi0uNSAzLS41IDUuNSAwIDEwIDQuNSAxMCAxMFM0MC41IDQzIDM1IDQzIi8+PHBhdGggZmlsbD0iIzM3NDc0ZiIgZD0iTTE0IDQzQzguNSA0MyA0IDM4LjUgNCAzM2MwLTQuNiAzLjEtOC41IDcuNS05LjdsMSAzLjlDOS45IDI3LjkgOCAzMC4zIDggMzNjMCAzLjMgMi43IDYgNiA2czYtMi43IDYtNnYtMmgxNXY0SDIzLjhjLS45IDQuNi01IDgtOS44IDgiLz48cGF0aCBmaWxsPSIjZTkxZTYzIiBkPSJNMTQgMzdjLTIuMiAwLTQtMS44LTQtNHMxLjgtNCA0LTQgNCAxLjggNCA0LTEuOCA0LTQgNCIvPjxwYXRoIGZpbGw9IiMzNzQ3NGYiIGQ9Ik0yNSAxOWMtMi4yIDAtNC0xLjgtNC00czEuOC00IDQtNCA0IDEuOCA0IDQtMS44IDQtNCA0Ii8+PHBhdGggZmlsbD0iI2U5MWU2MyIgZD0ibTE1LjcgMzQtMy40LTIgNS45LTkuN2MtMi0xLjktMy4yLTQuNS0zLjItNy4zIDAtNS41IDQuNS0xMCAxMC0xMHMxMCA0LjUgMTAgMTBjMCAuOS0uMSAxLjctLjMgMi41bC0zLjktMWMuMS0uNS4yLTEgLjItMS41IDAtMy4zLTIuNy02LTYtNnMtNiAyLjctNiA2YzAgMi4xIDEuMSA0IDIuOSA1LjFsMS43IDF6Ii8+PC9zdmc+"},"displayName":"Webhook","typeVersion":2,"nodeCategories":[{"id":5,"name":"Development"},{"id":9,"name":"Core Nodes"}]},{"id":439,"icon":"file:sendGrid.svg","name":"n8n-nodes-base.sendGrid","codex":{"data":{"resources":{"primaryDocumentation":[{"url":"https://docs.n8n.io/integrations/builtin/app-nodes/n8n-nodes-base.sendgrid/"}],"credentialDocumentation":[{"url":"https://docs.n8n.io/integrations/builtin/credentials/sendgrid/"}]},"categories":["Marketing","Communication"],"nodeVersion":"1.0","codexVersion":"1.0"}},"group":"[\"transform\"]","defaults":{"name":"SendGrid"},"iconData":{"type":"file","fileBuffer":"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiBmaWxsPSIjZmZmIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiB2aWV3Qm94PSIwIDAgNjYgNjUiPjx1c2UgeGxpbms6aHJlZj0iI2EiIHg9Ii41IiB5PSIuNSIvPjxzeW1ib2wgaWQ9ImEiIG92ZXJmbG93PSJ2aXNpYmxlIj48ZyBmaWxsLXJ1bGU9Im5vbnplcm8iIHN0cm9rZT0ibm9uZSI+PHBhdGggZD0iTTAgMjEuMjVoMjEuMzc0djIxLjM3NEgweiIvPjxwYXRoIGZpbGw9IiM5OWUxZjQiIGQ9Ik0wIDIxLjI1aDIxLjM3NHYyMS4zNzRIMHoiLz48cGF0aCBkPSJNMjEuMzc0IDQyLjYyNmgyMS4yNXYyMS4yNWgtMjEuMjV6Ii8+PHBhdGggZmlsbD0iIzk5ZTFmNCIgZD0iTTIxLjM3NCA0Mi42MjZoMjEuMjV2MjEuMjVoLTIxLjI1eiIvPjxwYXRoIGZpbGw9IiMxYTgyZTIiIGQ9Ik0wIDYzLjg3N2gyMS4zNzRWNjRIMHptMC0yMS4yNWgyMS4zNzR2MjEuMjVIMHoiLz48cGF0aCBmaWxsPSIjMDBiM2UzIiBkPSJNMjEuMzc0IDBoMjEuMjV2MjEuMjVoLTIxLjI1em0yMS4yNTIgMjEuMzc0SDY0djIxLjI1SDQyLjYyNnoiLz48cGF0aCBmaWxsPSIjMDA5ZGQ5IiBkPSJNMjEuMzc0IDQyLjYyNmgyMS4yNVYyMS4yNWgtMjEuMjV6Ii8+PHBhdGggZmlsbD0iIzFhODJlMiIgZD0iTTQyLjYyNiAwSDY0djIxLjI1SDQyLjYyNnptMCAyMS4yNUg2NHYuMTIzSDQyLjYyNnoiLz48L2c+PC9zeW1ib2w+PC9zdmc+"},"displayName":"SendGrid","typeVersion":1,"nodeCategories":[{"id":6,"name":"Communication"},{"id":27,"name":"Marketing"}]},{"id":514,"icon":"fa:pause-circle","name":"n8n-nodes-base.wait","codex":{"data":{"alias":["pause","sleep","delay","timeout"],"resources":{"generic":[{"url":"https://n8n.io/blog/how-to-get-started-with-crm-automation-and-no-code-workflow-ideas/","icon":"👥","label":"How to get started with CRM automation (with 3 no-code workflow ideas"},{"url":"https://n8n.io/blog/aws-workflow-automation/","label":"7 no-code workflow automations for Amazon Web Services"}],"primaryDocumentation":[{"url":"https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.wait/"}]},"categories":["Core Nodes"],"nodeVersion":"1.0","codexVersion":"1.0","subcategories":{"Core Nodes":["Helpers","Flow"]}}},"group":"[\"organization\"]","defaults":{"name":"Wait","color":"#804050"},"iconData":{"icon":"pause-circle","type":"icon"},"displayName":"Wait","typeVersion":1,"nodeCategories":[{"id":9,"name":"Core Nodes"}]},{"id":535,"icon":"file:webhook.svg","name":"n8n-nodes-base.respondToWebhook","codex":{"data":{"resources":{"primaryDocumentation":[{"url":"https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.respondtowebhook/"}]},"categories":["Core Nodes","Utility"],"nodeVersion":"1.0","codexVersion":"1.0","subcategories":{"Core Nodes":["Helpers"]}}},"group":"[\"transform\"]","defaults":{"name":"Respond to Webhook"},"iconData":{"type":"file","fileBuffer":"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0OCIgaGVpZ2h0PSI0OCI+PHBhdGggZmlsbD0iIzM3NDc0ZiIgZD0iTTM1IDM3Yy0yLjIgMC00LTEuOC00LTRzMS44LTQgNC00IDQgMS44IDQgNC0xLjggNC00IDQiLz48cGF0aCBmaWxsPSIjMzc0NzRmIiBkPSJNMzUgNDNjLTMgMC01LjktMS40LTcuOC0zLjdsMy4xLTIuNWMxLjEgMS40IDIuOSAyLjMgNC43IDIuMyAzLjMgMCA2LTIuNyA2LTZzLTIuNy02LTYtNmMtMSAwLTIgLjMtMi45LjdsLTEuNyAxTDIzLjMgMTZsMy41LTEuOSA1LjMgOS40YzEtLjMgMi0uNSAzLS41IDUuNSAwIDEwIDQuNSAxMCAxMFM0MC41IDQzIDM1IDQzIi8+PHBhdGggZmlsbD0iIzM3NDc0ZiIgZD0iTTE0IDQzQzguNSA0MyA0IDM4LjUgNCAzM2MwLTQuNiAzLjEtOC41IDcuNS05LjdsMSAzLjlDOS45IDI3LjkgOCAzMC4zIDggMzNjMCAzLjMgMi43IDYgNiA2czYtMi43IDYtNnYtMmgxNXY0SDIzLjhjLS45IDQuNi01IDgtOS44IDgiLz48cGF0aCBmaWxsPSIjZTkxZTYzIiBkPSJNMTQgMzdjLTIuMiAwLTQtMS44LTQtNHMxLjgtNCA0LTQgNCAxLjggNCA0LTEuOCA0LTQgNCIvPjxwYXRoIGZpbGw9IiMzNzQ3NGYiIGQ9Ik0yNSAxOWMtMi4yIDAtNC0xLjgtNC00czEuOC00IDQtNCA0IDEuOCA0IDQtMS44IDQtNCA0Ii8+PHBhdGggZmlsbD0iI2U5MWU2MyIgZD0ibTE1LjcgMzQtMy40LTIgNS45LTkuN2MtMi0xLjktMy4yLTQuNS0zLjItNy4zIDAtNS41IDQuNS0xMCAxMC0xMHMxMCA0LjUgMTAgMTBjMCAuOS0uMSAxLjctLjMgMi41bC0zLjktMWMuMS0uNS4yLTEgLjItMS41IDAtMy4zLTIuNy02LTYtNnMtNiAyLjctNiA2YzAgMi4xIDEuMSA0IDIuOSA1LjFsMS43IDF6Ii8+PC9zdmc+"},"displayName":"Respond to Webhook","typeVersion":2,"nodeCategories":[{"id":7,"name":"Utility"},{"id":9,"name":"Core Nodes"}]},{"id":565,"icon":"fa:sticky-note","name":"n8n-nodes-base.stickyNote","codex":{"data":{"alias":["Comments","Notes","Sticky"],"categories":["Core Nodes"],"nodeVersion":"1.0","codexVersion":"1.0","subcategories":{"Core Nodes":["Helpers"]}}},"group":"[\"input\"]","defaults":{"name":"Sticky Note","color":"#FFD233"},"iconData":{"icon":"sticky-note","type":"icon"},"displayName":"Sticky Note","typeVersion":1,"nodeCategories":[{"id":9,"name":"Core Nodes"}]},{"id":834,"icon":"file:code.svg","name":"n8n-nodes-base.code","codex":{"data":{"alias":["cpde","Javascript","JS","Python","Script","Custom Code","Function"],"details":"The Code node allows you to execute JavaScript in your workflow.","resources":{"primaryDocumentation":[{"url":"https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.code/"}]},"categories":["Development","Core Nodes"],"nodeVersion":"1.0","codexVersion":"1.0","subcategories":{"Core Nodes":["Helpers","Data Transformation"]}}},"group":"[\"transform\"]","defaults":{"name":"Code"},"iconData":{"type":"file","fileBuffer":"data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTEyIiBoZWlnaHQ9IjUxMiIgdmlld0JveD0iMCAwIDUxMiA1MTIiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMF8xMTcxXzQ0MSkiPgo8cGF0aCBkPSJNMTcwLjI4MyA0OEgxOTYuNUMyMDMuMTI3IDQ4IDIwOC41IDQyLjYyNzQgMjA4LjUgMzZWMTJDMjA4LjUgNS4zNzI1OCAyMDMuMTI3IDAgMTk2LjUgMEgxNzAuMjgzQzEyNi4xIDAgOTAuMjgzIDM1LjgxNzIgOTAuMjgzIDgwVjE3NkM5MC4yODMgMjA2LjkyOCA2NS4yMTA5IDIzMiAzNC4yODMgMjMySDIzQzE2LjM3MjYgMjMyIDExIDIzNy4zNzIgMTEgMjQ0VjI2OEMxMSAyNzQuNjI3IDE2LjM3MjQgMjgwIDIyLjk5OTYgMjgwTDM0LjI4MyAyODBDNjUuMjEwOSAyODAgOTAuMjgzIDMwNS4wNzIgOTAuMjgzIDMzNlY0NDBDOTAuMjgzIDQ3OS43NjQgMTIyLjUxOCA1MTIgMTYyLjI4MyA1MTJIMTk2LjVDMjAzLjEyNyA1MTIgMjA4LjUgNTA2LjYyNyAyMDguNSA1MDBWNDc2QzIwOC41IDQ2OS4zNzMgMjAzLjEyNyA0NjQgMTk2LjUgNDY0SDE2Mi4yODNDMTQ5LjAyOCA0NjQgMTM4LjI4MyA0NTMuMjU1IDEzOC4yODMgNDQwVjMzNkMxMzguMjgzIDMwOS4wMjIgMTI4LjAxMSAyODQuNDQzIDExMS4xNjQgMjY1Ljk2MUMxMDYuMTA5IDI2MC40MTYgMTA2LjEwOSAyNTEuNTg0IDExMS4xNjQgMjQ2LjAzOUMxMjguMDExIDIyNy41NTcgMTM4LjI4MyAyMDIuOTc4IDEzOC4yODMgMTc2VjgwQzEzOC4yODMgNjIuMzI2OSAxNTIuNjEgNDggMTcwLjI4MyA0OFoiIGZpbGw9IiNGRjk5MjIiLz4KPHBhdGggZD0iTTMwNSAzNkMzMDUgNDIuNjI3NCAzMTAuMzczIDQ4IDMxNyA0OEgzNDIuOTc5QzM2MC42NTIgNDggMzc0Ljk3OCA2Mi4zMjY5IDM3NC45NzggODBWMTc2QzM3NC45NzggMjAyLjk3OCAzODUuMjUxIDIyNy41NTcgNDAyLjA5OCAyNDYuMDM5QzQwNy4xNTMgMjUxLjU4NCA0MDcuMTUzIDI2MC40MTYgNDAyLjA5OCAyNjUuOTYxQzM4NS4yNTEgMjg0LjQ0MyAzNzQuOTc4IDMwOS4wMjIgMzc0Ljk3OCAzMzZWNDMyQzM3NC45NzggNDQ5LjY3MyAzNjAuNjUyIDQ2NCAzNDIuOTc5IDQ2NEgzMTdDMzEwLjM3MyA0NjQgMzA1IDQ2OS4zNzMgMzA1IDQ3NlY1MDBDMzA1IDUwNi42MjcgMzEwLjM3MyA1MTIgMzE3IDUxMkgzNDIuOTc5QzM4Ny4xNjEgNTEyIDQyMi45NzggNDc2LjE4MyA0MjIuOTc4IDQzMlYzMzZDNDIyLjk3OCAzMDUuMDcyIDQ0OC4wNTEgMjgwIDQ3OC45NzkgMjgwSDQ5MEM0OTYuNjI3IDI4MCA1MDIgMjc0LjYyOCA1MDIgMjY4VjI0NEM1MDIgMjM3LjM3MyA0OTYuNjI4IDIzMiA0OTAgMjMyTDQ3OC45NzkgMjMyQzQ0OC4wNTEgMjMyIDQyMi45NzggMjA2LjkyOCA0MjIuOTc4IDE3NlY4MEM0MjIuOTc4IDM1LjgxNzIgMzg3LjE2MSAwIDM0Mi45NzkgMEgzMTdDMzEwLjM3MyAwIDMwNSA1LjM3MjU4IDMwNSAxMlYzNloiIGZpbGw9IiNGRjk5MjIiLz4KPC9nPgo8ZGVmcz4KPGNsaXBQYXRoIGlkPSJjbGlwMF8xMTcxXzQ0MSI+CjxyZWN0IHdpZHRoPSI1MTIiIGhlaWdodD0iNTEyIiBmaWxsPSJ3aGl0ZSIvPgo8L2NsaXBQYXRoPgo8L2RlZnM+Cjwvc3ZnPgo="},"displayName":"Code","typeVersion":2,"nodeCategories":[{"id":5,"name":"Development"},{"id":9,"name":"Core Nodes"}]}],"categories":[{"id":36,"name":"File Management"}],"image":[]}}