This workflow corresponds to n8n.io template #10595 — we link there as the canonical source.
This workflow follows the Agent → Emailsend 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": "hBay3VAWzhX0w5bU",
"meta": {
"templateCredsSetupCompleted": true
},
"name": "Cybersecurity phishing attack prevention tool",
"tags": [],
"nodes": [
{
"id": "578da4c5-64c8-48ba-b7fc-82eef7c49510",
"name": "Sticky Note Overview",
"type": "n8n-nodes-base.stickyNote",
"position": [
-720,
32
],
"parameters": {
"width": 460,
"height": 820,
"content": "## \ud83d\udee1\ufe0f Phishing Attack Prevention\n\nReal-time phishing detection pipeline. Ingests emails, extracts IOCs, analyzes with GPT-4, scores risk, then auto-quarantines, flags, or clears \u2014 with SOC alerts and audit logging.\n\n### Flow\n1. Webhook receives email\n2. Extract URLs, domains, keywords\n3. VirusTotal + GPT-4 analysis\n4. Risk score routing\n5. Quarantine / Flag / Allow\n6. Slack SOC alert + audit log\n\n### Risk Levels\n\ud83d\udd34 **HIGH (75\u2013100)** \u2192 Quarantine\n\ud83d\udfe1 **MEDIUM (40\u201374)** \u2192 Flag + warn\n\ud83d\udfe2 **LOW (0\u201339)** \u2192 Allow + log\n\n### Credentials\n- OpenAI API (GPT-4o)\n- VirusTotal API\n- Slack Webhook\n- Google Sheets\n- SMTP Email\n\n### Placeholders to Replace\n- `YOUR_OPENAI_CREDENTIAL_ID`\n- `YOUR_VIRUSTOTAL_API_KEY`\n- `YOUR_SLACK_WEBHOOK_PATH`\n- `YOUR_GOOGLE_SHEET_ID`\n- `YOUR_EMAIL_GATEWAY_TOKEN`"
},
"typeVersion": 1
},
{
"id": "77892aca-d0d7-48e3-8371-0cd4a67fd090",
"name": "Sticky Note S1",
"type": "n8n-nodes-base.stickyNote",
"position": [
-224,
288
],
"parameters": {
"color": 6,
"width": 620,
"height": 324,
"content": "## Step 1 \u2014 Ingest & Extract IOCs"
},
"typeVersion": 1
},
{
"id": "0007772b-b55e-476d-8959-5c492a05b0eb",
"name": "Sticky Note S2",
"type": "n8n-nodes-base.stickyNote",
"position": [
448,
112
],
"parameters": {
"color": 6,
"width": 524,
"height": 740,
"content": "## Step 2 \u2014 GPT-4 Threat Analysis"
},
"typeVersion": 1
},
{
"id": "ba55bc03-3b5b-4f0b-b39f-cf0da27a2bc0",
"name": "Sticky Note S3",
"type": "n8n-nodes-base.stickyNote",
"position": [
1104,
112
],
"parameters": {
"color": 6,
"width": 700,
"height": 740,
"content": "## Step 3 \u2014 Risk Routing & Actions"
},
"typeVersion": 1
},
{
"id": "0eded51c-c82f-4967-bcce-48b47bca8582",
"name": "Sticky Note S4",
"type": "n8n-nodes-base.stickyNote",
"position": [
1888,
112
],
"parameters": {
"color": 6,
"width": 492,
"height": 740,
"content": "## Step 4 \u2014 Alert, Log & Respond"
},
"typeVersion": 1
},
{
"id": "e3611d35-3fbe-4c2a-9652-1e01bda48b0d",
"name": "Receive Email via Webhook",
"type": "n8n-nodes-base.webhook",
"position": [
-192,
400
],
"parameters": {
"path": "phishing-check",
"options": {},
"httpMethod": "POST",
"responseMode": "responseNode"
},
"typeVersion": 2
},
{
"id": "d6a94b60-9ff5-4d58-bda0-dead2a4bc89f",
"name": "Extract IOCs & Normalize",
"type": "n8n-nodes-base.code",
"position": [
64,
400
],
"parameters": {
"mode": "runOnceForEachItem",
"jsCode": "const body = $input.item.json.body || $input.item.json;\n\nif (!body.subject && !body.emailBody) {\n throw new Error('Email subject or body is required');\n}\n\nconst emailText = `${body.subject || ''} ${body.emailBody || body.body || ''}`;\n\n// Extract URLs\nconst urlRegex = /https?:\\/\\/[^\\s<>\"']+/gi;\nconst extractedUrls = [...new Set(emailText.match(urlRegex) || [])].slice(0, 15);\n\n// Extract domains\nconst domains = [...new Set(extractedUrls.map(url => {\n try { return new URL(url).hostname; } catch(e) { return null; }\n}).filter(Boolean))];\n\n// Phishing keyword check\nconst phishKeywords = [\n 'urgent','verify your account','click here','update payment',\n 'suspended','confirm identity','act now','password expired',\n 'invoice attached','wire transfer','bitcoin','gift card',\n 'winner','free gift','limited offer','account compromised'\n];\nconst keywordsHit = phishKeywords.filter(kw =>\n emailText.toLowerCase().includes(kw)\n);\n\n// Sender vs reply-to mismatch\nconst senderEmail = (body.senderEmail || body.from || '').toLowerCase();\nconst replyTo = (body.replyTo || '').toLowerCase();\nconst senderDomain = senderEmail.split('@')[1] || '';\nconst replyDomain = replyTo.split('@')[1] || '';\nconst domainMismatch = !!(replyTo && senderDomain && replyDomain && senderDomain !== replyDomain);\n\n// Suspicious attachments\nconst dangerExts = /\\.(exe|js|vbs|ps1|bat|cmd|scr|jar|zip|rar|hta)$/i;\nconst suspAttachments = (body.attachments || []).filter(a => dangerExts.test(a.filename || ''));\n\nreturn {\n json: {\n emailRecord: {\n emailId: `PHISH-${Date.now()}-${Math.random().toString(36).substr(2,6).toUpperCase()}`,\n subject: body.subject || '(No Subject)',\n senderEmail,\n senderName: body.senderName || '',\n recipientEmail: body.recipientEmail || body.to || '',\n replyTo,\n emailBody: emailText.substring(0, 2500),\n extractedUrls,\n domains,\n keywordsHit,\n keywordCount: keywordsHit.length,\n domainMismatch,\n suspAttachmentCount: suspAttachments.length,\n suspAttachmentNames: suspAttachments.map(a => a.filename),\n receivedAt: body.receivedAt || new Date().toISOString()\n }\n }\n};"
},
"typeVersion": 2
},
{
"id": "4d93b988-ef17-4633-9828-35a8507f0b02",
"name": "VirusTotal URL Scan",
"type": "n8n-nodes-base.httpRequest",
"position": [
480,
304
],
"parameters": {
"url": "https://www.virustotal.com/api/v3/urls",
"method": "POST",
"options": {
"timeout": 12000
},
"sendBody": true,
"sendHeaders": true,
"specifyBody": "formUrlEncoded",
"headerParameters": {
"parameters": [
{
"name": "x-apikey",
"value": "YOUR_VIRUSTOTAL_API_KEY"
}
]
}
},
"typeVersion": 4.2,
"continueOnFail": true
},
{
"id": "3acafc2f-9982-4095-9e46-8dba8ac3a7d3",
"name": "GPT-4 Phishing Analysis",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
480,
496
],
"parameters": {
"text": "=You are an expert cybersecurity analyst specializing in phishing detection.\n\nAnalyze this email and return a structured phishing risk assessment.\n\n**Email:**\n- Subject: {{ $json.emailRecord.subject }}\n- From: {{ $json.emailRecord.senderEmail }}\n- Reply-To: {{ $json.emailRecord.replyTo || 'same as sender' }}\n- Domain Mismatch: {{ $json.emailRecord.domainMismatch }}\n- Keywords Triggered ({{ $json.emailRecord.keywordCount }}): {{ $json.emailRecord.keywordsHit.join(', ') || 'none' }}\n- URLs Found: {{ $json.emailRecord.extractedUrls.slice(0,5).join(', ') || 'none' }}\n- Suspicious Attachments: {{ $json.emailRecord.suspAttachmentCount }} \u2014 {{ $json.emailRecord.suspAttachmentNames.join(', ') || 'none' }}\n- Body: {{ $json.emailRecord.emailBody.substring(0, 1500) }}\n\n**Respond in JSON only:**\n{\n \"riskScore\": 85,\n \"riskLevel\": \"HIGH\",\n \"attackType\": \"credential_phishing\",\n \"confidenceLevel\": 91,\n \"isPhishing\": true,\n \"impersonatedBrand\": \"Microsoft\",\n \"socialEngineeringTactics\": [\"urgency\", \"fear\"],\n \"credentialHarvestingRisk\": true,\n \"recommendation\": \"QUARANTINE\",\n \"userWarningMessage\": \"Short plain-English warning for the recipient\",\n \"socSummary\": \"2-sentence technical summary for SOC team\"\n}",
"options": {
"systemMessage": "You are a phishing detection AI. Output valid JSON only \u2014 no markdown, no preamble. When in doubt, flag as suspicious."
},
"promptType": "define"
},
"typeVersion": 1.6
},
{
"id": "29042c2d-7a97-4776-a77c-9fb1b37f8ce9",
"name": "GPT-4o Model",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
"position": [
560,
704
],
"parameters": {
"model": "gpt-4o",
"options": {
"maxTokens": 800,
"temperature": 0.1
}
},
"typeVersion": 1
},
{
"id": "03ff8740-77ef-4664-9e45-c6e3ed281470",
"name": "Parse & Score Risk",
"type": "n8n-nodes-base.code",
"position": [
768,
400
],
"parameters": {
"mode": "runOnceForEachItem",
"jsCode": "const aiResp = $input.item.json;\nlet aiText = aiResp.response || aiResp.output || aiResp.text || '';\nif (aiResp.content && Array.isArray(aiResp.content)) {\n aiText = aiResp.content[0]?.text || '';\n}\nconst clean = aiText.replace(/```json\\s*/g,'').replace(/```\\s*/g,'').trim();\n\nlet analysis;\ntry { analysis = JSON.parse(clean); }\ncatch(e) { throw new Error(`Parse failed: ${e.message}. Raw: ${clean.substring(0,150)}`); }\n\nconst vtResult = $('VirusTotal URL Scan').item.json;\nconst vtMalicious = vtResult?.data?.attributes?.last_analysis_stats?.malicious || 0;\nconst vtSuspicious = vtResult?.data?.attributes?.last_analysis_stats?.suspicious || 0;\n\nlet score = analysis.riskScore || 0;\nif (vtMalicious > 0) score = Math.min(100, score + 20);\nif (vtSuspicious > 0) score = Math.min(100, score + 10);\n\nconst riskLevel = score >= 75 ? 'HIGH' : score >= 40 ? 'MEDIUM' : 'LOW';\nconst action = riskLevel === 'HIGH' ? 'QUARANTINE' : riskLevel === 'MEDIUM' ? 'FLAG' : 'ALLOW';\n\nconst emailRecord = $('Extract IOCs & Normalize').item.json.emailRecord;\n\nreturn {\n json: {\n emailRecord,\n analysis: { ...analysis, riskScore: score, riskLevel },\n vtMalicious,\n vtSuspicious,\n riskLevel,\n finalScore: score,\n action,\n analyzedAt: new Date().toISOString()\n }\n};"
},
"typeVersion": 2
},
{
"id": "e4ccf4d7-2295-4dac-b3b5-4194d07652f4",
"name": "Risk Level Switch",
"type": "n8n-nodes-base.switch",
"position": [
1200,
400
],
"parameters": {
"mode": "expression"
},
"typeVersion": 3
},
{
"id": "6b88bc07-8306-42a5-907e-dbe665011f7b",
"name": "Quarantine \u2014 HIGH",
"type": "n8n-nodes-base.httpRequest",
"position": [
1440,
256
],
"parameters": {
"url": "https://YOUR_EMAIL_GATEWAY_API/v1/emails/quarantine",
"method": "POST",
"options": {
"timeout": 10000
},
"jsonBody": "={\"emailId\":\"{{ $json.emailRecord.emailId }}\",\"action\":\"quarantine\",\"riskScore\":{{ $json.finalScore }},\"attackType\":\"{{ $json.analysis.attackType }}\",\"recipient\":\"{{ $json.emailRecord.recipientEmail }}\"}",
"sendBody": true,
"sendHeaders": true,
"specifyBody": "json",
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "Bearer YOUR_TOKEN_HERE"
},
{
"name": "Content-Type",
"value": "application/json"
}
]
}
},
"typeVersion": 4.2,
"continueOnFail": true
},
{
"id": "83b2a738-f67b-4837-a741-c63c72ac34cc",
"name": "Flag \u2014 MEDIUM",
"type": "n8n-nodes-base.httpRequest",
"position": [
1440,
416
],
"parameters": {
"url": "https://YOUR_EMAIL_GATEWAY_API/v1/emails/flag",
"method": "POST",
"options": {
"timeout": 10000
},
"jsonBody": "={\"emailId\":\"{{ $json.emailRecord.emailId }}\",\"action\":\"flag_suspicious\",\"riskScore\":{{ $json.finalScore }},\"recipient\":\"{{ $json.emailRecord.recipientEmail }}\"}",
"sendBody": true,
"sendHeaders": true,
"specifyBody": "json",
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "Bearer YOUR_TOKEN_HERE"
},
{
"name": "Content-Type",
"value": "application/json"
}
]
}
},
"typeVersion": 4.2,
"continueOnFail": true
},
{
"id": "bb2e3f3b-9e6f-46f6-9431-413620326381",
"name": "Allow \u2014 LOW",
"type": "n8n-nodes-base.set",
"position": [
1440,
576
],
"parameters": {
"options": {},
"includeOtherFields": true
},
"typeVersion": 3.4
},
{
"id": "983c2a98-b5f1-4bce-a38c-70664b919916",
"name": "Merge All Paths",
"type": "n8n-nodes-base.merge",
"position": [
1680,
416
],
"parameters": {
"mode": "mergeByPosition"
},
"typeVersion": 3
},
{
"id": "1d05e27f-e295-4ebe-be66-9576268d4a1e",
"name": "Slack SOC Alert",
"type": "n8n-nodes-base.httpRequest",
"position": [
1936,
272
],
"parameters": {
"url": "https://hooks.slack.com/services/YOUR_SLACK_WEBHOOK_PATH",
"method": "POST",
"options": {
"timeout": 8000
},
"jsonBody": "={\n \"channel\": \"#soc-phishing\",\n \"username\": \"PhishBot\",\n \"icon_emoji\": \":rotating_light:\",\n \"blocks\": [\n {\n \"type\": \"header\",\n \"text\": { \"type\": \"plain_text\", \"text\": \"{{ $json.riskLevel === 'HIGH' ? '\ud83d\udea8 PHISHING QUARANTINED' : '\u26a0\ufe0f SUSPICIOUS EMAIL FLAGGED' }}\", \"emoji\": true }\n },\n {\n \"type\": \"section\",\n \"fields\": [\n { \"type\": \"mrkdwn\", \"text\": \"*Risk Score:*\\n{{ $json.finalScore }}/100\" },\n { \"type\": \"mrkdwn\", \"text\": \"*Attack Type:*\\n{{ $json.analysis.attackType }}\" },\n { \"type\": \"mrkdwn\", \"text\": \"*Action:*\\n{{ $json.action }}\" },\n { \"type\": \"mrkdwn\", \"text\": \"*Sender:*\\n{{ $json.emailRecord.senderEmail }}\" },\n { \"type\": \"mrkdwn\", \"text\": \"*Impersonated:*\\n{{ $json.analysis.impersonatedBrand || 'None' }}\" },\n { \"type\": \"mrkdwn\", \"text\": \"*VT Hits:*\\n{{ $json.vtMalicious }} malicious\" }\n ]\n },\n {\n \"type\": \"section\",\n \"text\": { \"type\": \"mrkdwn\", \"text\": \"*SOC Summary:*\\n{{ $json.analysis.socSummary }}\" }\n }\n ]\n}",
"sendBody": true,
"sendHeaders": true,
"specifyBody": "json",
"headerParameters": {
"parameters": [
{
"name": "Content-Type",
"value": "application/json"
}
]
}
},
"typeVersion": 4.2,
"continueOnFail": true
},
{
"id": "c80d2b0e-71a2-4915-892e-8c6ce0fe7a67",
"name": "Warn User via Email",
"type": "n8n-nodes-base.emailSend",
"position": [
1936,
480
],
"parameters": {
"options": {},
"subject": "=[Security Alert] {{ $json.riskLevel === 'HIGH' ? 'Phishing email quarantined' : 'Suspicious email flagged' }} \u2014 {{ $json.emailRecord.subject }}",
"toEmail": "=",
"fromEmail": "="
},
"credentials": {
"smtp": {
"name": "<your credential>"
}
},
"typeVersion": 2.1,
"continueOnFail": true
},
{
"id": "2768a6ba-9a9a-4362-9533-0ae837567dc9",
"name": "Write Audit Log",
"type": "n8n-nodes-base.googleSheets",
"position": [
1936,
672
],
"parameters": {
"columns": {
"value": {},
"schema": [],
"mappingMode": "autoMapInputData",
"matchingColumns": [],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"operation": "append",
"sheetName": {
"__rl": true,
"mode": "id",
"value": "="
},
"documentId": {
"__rl": true,
"mode": "id",
"value": "="
},
"authentication": "serviceAccount"
},
"credentials": {
"googleApi": {
"name": "<your credential>"
}
},
"typeVersion": 4.5,
"continueOnFail": true
},
{
"id": "de5a742d-6eed-4a16-b39e-09a67b893b72",
"name": "Return Detection Result",
"type": "n8n-nodes-base.respondToWebhook",
"position": [
2208,
480
],
"parameters": {
"options": {
"responseHeaders": {
"entries": [
{
"name": "Content-Type",
"value": "application/json"
},
{
"name": "X-Risk-Level",
"value": "={{ $json.riskLevel }}"
},
{
"name": "X-Risk-Score",
"value": "={{ $json.finalScore }}"
}
]
}
},
"respondWith": "json",
"responseBody": "={{ JSON.stringify({ emailId: $json.emailRecord.emailId, riskLevel: $json.riskLevel, riskScore: $json.finalScore, action: $json.action, attackType: $json.analysis.attackType, isPhishing: $json.analysis.isPhishing, analyzedAt: $json.analyzedAt }) }}"
},
"typeVersion": 1
}
],
"active": false,
"settings": {
"executionOrder": "v1"
},
"versionId": "28a1307b-2b62-47ca-bb88-fcb27e166fc4",
"connections": {
"GPT-4o Model": {
"ai_languageModel": [
[
{
"node": "GPT-4 Phishing Analysis",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Allow \u2014 LOW": {
"main": [
[
{
"node": "Merge All Paths",
"type": "main",
"index": 1
}
]
]
},
"Flag \u2014 MEDIUM": {
"main": [
[
{
"node": "Merge All Paths",
"type": "main",
"index": 1
}
]
]
},
"Merge All Paths": {
"main": [
[
{
"node": "Slack SOC Alert",
"type": "main",
"index": 0
},
{
"node": "Warn User via Email",
"type": "main",
"index": 0
},
{
"node": "Write Audit Log",
"type": "main",
"index": 0
}
]
]
},
"Slack SOC Alert": {
"main": [
[
{
"node": "Return Detection Result",
"type": "main",
"index": 0
}
]
]
},
"Write Audit Log": {
"main": [
[
{
"node": "Return Detection Result",
"type": "main",
"index": 0
}
]
]
},
"Risk Level Switch": {
"main": [
[
{
"node": "Quarantine \u2014 HIGH",
"type": "main",
"index": 0
}
],
[
{
"node": "Flag \u2014 MEDIUM",
"type": "main",
"index": 0
}
],
[
{
"node": "Allow \u2014 LOW",
"type": "main",
"index": 0
}
]
]
},
"Parse & Score Risk": {
"main": [
[
{
"node": "Risk Level Switch",
"type": "main",
"index": 0
}
]
]
},
"Quarantine \u2014 HIGH": {
"main": [
[
{
"node": "Merge All Paths",
"type": "main",
"index": 0
}
]
]
},
"VirusTotal URL Scan": {
"main": [
[
{
"node": "Parse & Score Risk",
"type": "main",
"index": 0
}
]
]
},
"Warn User via Email": {
"main": [
[
{
"node": "Return Detection Result",
"type": "main",
"index": 0
}
]
]
},
"GPT-4 Phishing Analysis": {
"main": [
[
{
"node": "Parse & Score Risk",
"type": "main",
"index": 0
}
]
]
},
"Extract IOCs & Normalize": {
"main": [
[
{
"node": "VirusTotal URL Scan",
"type": "main",
"index": 0
},
{
"node": "GPT-4 Phishing Analysis",
"type": "main",
"index": 0
}
]
]
},
"Receive Email via Webhook": {
"main": [
[
{
"node": "Extract IOCs & Normalize",
"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.
googleApismtp
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
This n8n workflow automates real-time phishing detection by ingesting incoming emails, extracting indicators, analyzing content with AI (GPT-4), calculating risk scores, and taking immediate action—quarantining malicious emails, flagging suspicious ones, alerting users and SOC,…
Source: https://n8n.io/workflows/10595/ — 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 n8n workflow orchestrates a powerful suite of AI Agents and automations to manage and optimize various aspects of an e-commerce operation, particularly for platforms like Shopify. It leverages La
Converts raw sales call recordings into structured CRM intelligence. Uploads audio → transcribes via Whisper → GPT-4 extracts intent, sentiment, objections, next steps → updates CRM and sends a struct
Law firms in corporate, litigation, or family law needing streamlined case and contract management.
Automates fraud risk detection for financial transactions by analyzing real-time webhook events through AI-powered scoring. Target audience: fintech companies, payment processors, and banking teams pr
K&S-Media Downloadliste SQL. Uses httpRequest, agent, googleSheets, lmChatOpenAi. Event-driven trigger; 97 nodes.