AutomationFlowsEmail & Gmail › Refi-04 Sendgrid Event Tracking

Refi-04 Sendgrid Event Tracking

REFI-04 SendGrid Event Tracking. Uses httpRequest. Webhook trigger; 13 nodes.

Webhook trigger★★★★☆ complexity13 nodesHTTP Request
Email & Gmail Trigger: Webhook Nodes: 13 Complexity: ★★★★☆ Added:

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
{
  "name": "REFI-04 SendGrid Event Tracking",
  "nodes": [
    {
      "parameters": {
        "httpMethod": "POST",
        "path": "sendgrid-events",
        "options": {
          "rawBody": true
        }
      },
      "id": "webhook",
      "name": "SendGrid Webhook",
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 1,
      "position": [
        250,
        300
      ]
    },
    {
      "parameters": {
        "jsCode": "// Parse SendGrid events and extract contact info\nconst events = $input.all();\nconst results = [];\n\nfor (const item of events) {\n  const body = item.json.body || item.json;\n  \n  // SendGrid sends array of events\n  const eventList = Array.isArray(body) ? body : [body];\n  \n  for (const event of eventList) {\n    const contactId = event.contact_id || \n                     (event.custom_args && event.custom_args.contact_id);\n    const campaign = event.campaign || \n                    (event.custom_args && event.custom_args.campaign);\n    const emailId = event.email_id || \n                   (event.custom_args && event.custom_args.email_id);\n    \n    if (!contactId) continue;\n    \n    let scoreChange = 0;\n    let tag = null;\n    let urgency = 'normal';\n    \n    switch(event.event) {\n      case 'open':\n        scoreChange = 5;\n        tag = 'refi-email-opened';\n        break;\n      case 'click':\n        scoreChange = 10;\n        tag = 'refi-email-clicked';\n        \n        // Check for intent in URL\n        const url = event.url || '';\n        if (url.includes('intent=lower-rate')) {\n          tag = 'interested-lower-rate';\n          scoreChange = 25;\n          urgency = 'high';\n        } else if (url.includes('intent=cash-out')) {\n          tag = 'interested-cash-out';\n          scoreChange = 25;\n          urgency = 'high';\n        } else if (url.includes('intent=debt-consol')) {\n          tag = 'interested-debt-consol';\n          scoreChange = 25;\n          urgency = 'high';\n        }\n        break;\n      case 'delivered':\n        scoreChange = 0;\n        break;\n      case 'bounce':\n      case 'dropped':\n        tag = 'refi-email-failed';\n        break;\n      case 'unsubscribe':\n        tag = 'unsubscribed';\n        break;\n    }\n    \n    if (contactId && (scoreChange > 0 || tag)) {\n      results.push({\n        contact_id: contactId,\n        event_type: event.event,\n        score_change: scoreChange,\n        tag: tag,\n        urgency: urgency,\n        campaign: campaign,\n        email_id: emailId,\n        url: event.url,\n        timestamp: event.timestamp || new Date().toISOString()\n      });\n    }\n  }\n}\n\nreturn results.map(r => ({ json: r }));"
      },
      "id": "parse-events",
      "name": "Parse SendGrid Events",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        450,
        300
      ]
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict"
          },
          "conditions": [
            {
              "id": "has-tag",
              "leftValue": "={{ $json.tag }}",
              "rightValue": "",
              "operator": {
                "type": "string",
                "operation": "isNotEmpty"
              }
            }
          ],
          "combinator": "and"
        }
      },
      "id": "has-tag",
      "name": "Has Tag to Add?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2,
      "position": [
        650,
        300
      ]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "=https://services.leadconnectorhq.com/contacts/{{ $json.contact_id }}/tags",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Bearer {{ $env.GHL_API_KEY }}"
            },
            {
              "name": "Version",
              "value": "2021-07-28"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        },
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={ \"tags\": [\"{{ $json.tag }}\"] }"
      },
      "id": "add-tag-ghl",
      "name": "Add Tag to GHL Contact",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4,
      "position": [
        850,
        200
      ]
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict"
          },
          "conditions": [
            {
              "id": "is-intent",
              "leftValue": "={{ $json.urgency }}",
              "rightValue": "high",
              "operator": {
                "type": "string",
                "operation": "equals"
              }
            }
          ],
          "combinator": "and"
        }
      },
      "id": "is-intent-click",
      "name": "Is Intent Click?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2,
      "position": [
        850,
        400
      ]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://api.telegram.org/bot{{ $env.TELEGRAM_BOT_TOKEN }}/sendMessage",
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={\n  \"chat_id\": \"{{ $env.TELEGRAM_CHAT_ID }}\",\n  \"text\": \"\ud83d\udd25 REFI INTENT CLICK\\n\\nContact: {{ $json.contact_id }}\\nIntent: {{ $json.tag }}\\nScore: +{{ $json.score_change }} pts\\n\\nFollow up ASAP!\",\n  \"parse_mode\": \"HTML\"\n}"
      },
      "id": "telegram-alert",
      "name": "Send Telegram Alert",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4,
      "position": [
        1050,
        350
      ]
    },
    {
      "parameters": {
        "method": "GET",
        "url": "=https://services.leadconnectorhq.com/contacts/{{ $json.contact_id }}",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Bearer {{ $env.GHL_API_KEY }}"
            },
            {
              "name": "Version",
              "value": "2021-07-28"
            }
          ]
        }
      },
      "id": "get-contact-for-email",
      "name": "Get Contact for Email Alert",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4,
      "position": [
        1050,
        450
      ]
    },
    {
      "parameters": {
        "jsCode": "// Build email alert for team\nconst contact = $input.first().json.contact;\nconst eventData = $('Has Tag to Add?').first().json;\n\nconst intentLabels = {\n  'interested-lower-rate': 'Lower Monthly Payment',\n  'interested-cash-out': 'Cash Out / Home Equity',\n  'interested-debt-consol': 'Debt Consolidation'\n};\n\nconst intentLabel = intentLabels[eventData.tag] || eventData.tag;\n\nconst htmlBody = `\n<div style=\"font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto;\">\n  <div style=\"background: #8E4585; color: white; padding: 20px; text-align: center;\">\n    <h1 style=\"margin: 0;\">\ud83d\udd25 HOT LEAD ALERT</h1>\n  </div>\n  <div style=\"padding: 20px; background: #f9f9f9;\">\n    <table style=\"width: 100%; border-collapse: collapse;\">\n      <tr>\n        <td style=\"padding: 10px; border-bottom: 1px solid #ddd;\"><strong>Contact:</strong></td>\n        <td style=\"padding: 10px; border-bottom: 1px solid #ddd;\">${contact.firstName || ''} ${contact.lastName || ''}</td>\n      </tr>\n      <tr>\n        <td style=\"padding: 10px; border-bottom: 1px solid #ddd;\"><strong>Email:</strong></td>\n        <td style=\"padding: 10px; border-bottom: 1px solid #ddd;\">${contact.email || 'N/A'}</td>\n      </tr>\n      <tr>\n        <td style=\"padding: 10px; border-bottom: 1px solid #ddd;\"><strong>Phone:</strong></td>\n        <td style=\"padding: 10px; border-bottom: 1px solid #ddd;\">${contact.phone || contact.mobilePhone || 'N/A'}</td>\n      </tr>\n      <tr style=\"background: #FFF3CD;\">\n        <td style=\"padding: 10px; border-bottom: 1px solid #ddd;\"><strong>Intent:</strong></td>\n        <td style=\"padding: 10px; border-bottom: 1px solid #ddd; font-weight: bold; color: #8E4585;\">${intentLabel}</td>\n      </tr>\n      <tr>\n        <td style=\"padding: 10px; border-bottom: 1px solid #ddd;\"><strong>Lead Score:</strong></td>\n        <td style=\"padding: 10px; border-bottom: 1px solid #ddd;\">+${eventData.score_change} points</td>\n      </tr>\n      <tr>\n        <td style=\"padding: 10px;\"><strong>Campaign:</strong></td>\n        <td style=\"padding: 10px;\">refi-jan26</td>\n      </tr>\n    </table>\n    \n    <div style=\"background: #8E4585; color: white; padding: 15px; margin-top: 20px; text-align: center;\">\n      <strong>\u23f0 CALL WITHIN 1 HOUR</strong>\n    </div>\n    \n    <p style=\"margin-top: 20px; font-size: 12px; color: #666;\">\n      This lead clicked an intent link in the refinance campaign email.<br>\n      They have shown HIGH INTEREST and should be contacted immediately.\n    </p>\n  </div>\n  <div style=\"padding: 10px; text-align: center; font-size: 11px; color: #999;\">\n    Sent via MortgageArchitect AI\n  </div>\n</div>\n`;\n\nreturn [{\n  json: {\n    contact_id: contact.id,\n    contact_name: `${contact.firstName || ''} ${contact.lastName || ''}`.trim(),\n    contact_email: contact.email,\n    contact_phone: contact.phone || contact.mobilePhone,\n    intent: intentLabel,\n    email_html: htmlBody,\n    email_subject: `\ud83d\udd25 HOT LEAD: ${contact.firstName || 'Contact'} interested in ${intentLabel}`\n  }\n}];"
      },
      "id": "build-email-alert",
      "name": "Build Email Alert",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1250,
        450
      ]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://api.sendgrid.com/v3/mail/send",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Bearer {{ $env.SENDGRID_API_KEY }}"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        },
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={\n  \"personalizations\": [{\n    \"to\": [{\"email\": \"rmgsales@ccm.com\", \"name\": \"ROC Sales Team\"}]\n  }],\n  \"from\": {\"email\": \"info@rochomeloans.com\", \"name\": \"ROC Home Loans\"},\n  \"reply_to\": {\"email\": \"roc@ccm.com\"},\n  \"subject\": \"{{ $json.email_subject }}\",\n  \"content\": [{\"type\": \"text/html\", \"value\": {{ JSON.stringify($json.email_html) }}}]\n}"
      },
      "id": "send-email-alert",
      "name": "Send Email Alert to Team",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4,
      "position": [
        1450,
        450
      ]
    },
    {
      "parameters": {
        "jsCode": "// Build SMS message for Zapier-RingCentral\nconst data = $('Has Tag to Add?').first().json;\n\nconst smsTemplates = {\n  'interested-lower-rate': `Hey! Saw you're interested in lowering your rate. Many clients are saving $200-500/month. Text me a photo of your mortgage statement for a quick quote OR reply CALL ME. - Yauvan (617) 595-2500`,\n  'interested-cash-out': `Hey! Looking to tap into your home equity? Your home has likely gained value. Text me your statement for a same-day quote OR reply CALL ME. - Yauvan (617) 595-2500`,\n  'interested-debt-consol': `Hey! Consolidating debt into your mortgage can save thousands. Text your statement OR credit card statements. Reply CALL ME for analysis. - Yauvan (617) 595-2500`\n};\n\nreturn [{\n  json: {\n    contact_id: data.contact_id,\n    sms_message: smsTemplates[data.tag] || 'Thanks for your interest! Reply CALL ME to chat. - Yauvan',\n    tag: data.tag,\n    intent_type: data.tag.replace('interested-', ''),\n    campaign: 'refi-jan26'\n  }\n}];"
      },
      "id": "build-sms",
      "name": "Build SMS Message",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1050,
        550
      ]
    },
    {
      "parameters": {
        "method": "GET",
        "url": "=https://services.leadconnectorhq.com/contacts/{{ $json.contact_id }}",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Bearer {{ $env.GHL_API_KEY }}"
            },
            {
              "name": "Version",
              "value": "2021-07-28"
            }
          ]
        }
      },
      "id": "get-contact-phone",
      "name": "Get Contact Phone from GHL",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4,
      "position": [
        1250,
        550
      ]
    },
    {
      "parameters": {
        "jsCode": "// Merge contact phone with SMS message\nconst contact = $input.first().json.contact;\nconst smsData = $('Build SMS Message').first().json;\n\nreturn [{\n  json: {\n    to_phone: contact.phone || contact.mobilePhone,\n    to_name: contact.firstName || 'Friend',\n    message: smsData.sms_message,\n    contact_id: smsData.contact_id,\n    intent_type: smsData.intent_type,\n    campaign: smsData.campaign\n  }\n}];"
      },
      "id": "merge-phone-sms",
      "name": "Merge Phone with SMS",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1450,
        550
      ]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "={{ $env.ZAPIER_RINGCENTRAL_SMS_WEBHOOK }}",
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={\n  \"to_phone\": \"{{ $json.to_phone }}\",\n  \"to_name\": \"{{ $json.to_name }}\",\n  \"message\": \"{{ $json.message }}\",\n  \"contact_id\": \"{{ $json.contact_id }}\",\n  \"campaign\": \"{{ $json.campaign }}\",\n  \"intent_type\": \"{{ $json.intent_type }}\"\n}"
      },
      "id": "send-sms-zapier",
      "name": "Send SMS via Zapier-RingCentral",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4,
      "position": [
        1650,
        550
      ]
    }
  ],
  "connections": {
    "SendGrid Webhook": {
      "main": [
        [
          {
            "node": "Parse SendGrid Events",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse SendGrid Events": {
      "main": [
        [
          {
            "node": "Has Tag to Add?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Has Tag to Add?": {
      "main": [
        [
          {
            "node": "Add Tag to GHL Contact",
            "type": "main",
            "index": 0
          }
        ],
        []
      ]
    },
    "Add Tag to GHL Contact": {
      "main": [
        [
          {
            "node": "Is Intent Click?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Is Intent Click?": {
      "main": [
        [
          {
            "node": "Send Telegram Alert",
            "type": "main",
            "index": 0
          },
          {
            "node": "Get Contact for Email Alert",
            "type": "main",
            "index": 0
          },
          {
            "node": "Build SMS Message",
            "type": "main",
            "index": 0
          }
        ],
        []
      ]
    },
    "Get Contact for Email Alert": {
      "main": [
        [
          {
            "node": "Build Email Alert",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Build Email Alert": {
      "main": [
        [
          {
            "node": "Send Email Alert to Team",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Build SMS Message": {
      "main": [
        [
          {
            "node": "Get Contact Phone from GHL",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Contact Phone from GHL": {
      "main": [
        [
          {
            "node": "Merge Phone with SMS",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge Phone with SMS": {
      "main": [
        [
          {
            "node": "Send SMS via Zapier-RingCentral",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {
    "executionOrder": "v1"
  },
  "staticData": null,
  "tags": [
    {
      "name": "refi-campaign"
    },
    {
      "name": "sendgrid"
    }
  ]
}
Pro

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

About this workflow

REFI-04 SendGrid Event Tracking. Uses httpRequest. Webhook trigger; 13 nodes.

Source: https://gist.github.com/TheArchitectAI/aef16ca117799ffe877d0423cb22abb5 — 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

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

Hectelion | Evaluation d'entreprise. Uses googleDrive, httpRequest, microsoftOutlook, googleSheets. Webhook trigger; 64 nodes.

Google Drive, HTTP Request, Microsoft Outlook +1
Email & Gmail

Hectelion | NDA. Uses googleSheets, googleDrive, httpRequest, microsoftOutlook. Webhook trigger; 50 nodes.

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

This template turns Podium's conversation inbox into a full sales CRM with a custom funnel, AI message classification, automated drip follow-ups, daily admin reports, and a live Kanban dashboard. Six

HTTP Request, Google Sheets, Gmail
Email & Gmail

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

Postgres, HTTP Request, Gmail +1