Auto-triage phishing reports with VirusTotal and Slack

Every 15 minutes, phishing emails your staff forward in get checked against 70+ security engines and summarised in Slack, with a compliance log kept automatically.

Agentic Task
VirusTotalGmailSlack BotGoogle SheetsEngineeringOperationsNotifications & AlertsEmail AutomationResearch & Monitoring
PromptCreate

Every 15 minutes, triage the phishing reports our staff forward into our shared security mailbox. Use the Gmail List Messages operation to find unread messages carrying the "Phishing Reports" label. Process at most five messages per run, oldest first, so a backlog drains steadily across runs instead of exhausting our VirusTotal quota in one burst.

For each message, use Gmail Get a Message at full detail to read the sender address, the subject, the date received, and the body. Extract every link in the body, including links hidden behind display text, and note who forwarded the report. Note every attachment, and use Gmail Get Attachment to retrieve each one so you can compute its SHA-256 hash.

Check each extracted link with VirusTotal. Submit it with Scan a URL, which returns an analysis id, then poll Get an Analysis until the status comes back as completed. VirusTotal scans are not always immediately available, so wait roughly fifteen seconds between polls and give up after about five attempts rather than looping forever. For links VirusTotal already knows about, and whenever polling is exhausted, fall back to Get a URL Report to read the stored verdict. Deduplicate links so the same URL is only checked once per email.

For each attachment, look up its hash with VirusTotal Get a File Report. A not-found response means VirusTotal has never seen that file, which is worth reporting as unknown rather than treating it as clean.

Weigh the per-engine detection counts from each report. Treat an indicator as malicious when three or more engines flag it, suspicious when one or two engines flag it or when the file is unknown, and clean when nothing is flagged. The verdict for the whole email is the worst result across all of its links and attachments. Include a one-line explanation of why you landed on that verdict.

Post a short summary to our security channel using Slack Bot Send a Message. Include the verdict, the sender, the subject, who reported it, and one line per link and attachment showing the detection count out of the total engines checked. Defang every URL and every domain so nobody clicks one by accident while reading the alert: write hxxp:// or hxxps:// in place of http:// or https://, and wrap each dot in square brackets, so example.com becomes example[.]com. Apply this to sender domains too. Lead with a clear visual marker when the verdict is malicious so it stands out in the channel.

Log one row per reported email to our compliance spreadsheet with Google Sheets Append Values, capturing the date triaged, the sender, the subject, who reported it, the number of links and attachments checked, the highest detection count seen, and the final verdict. Keep URLs defanged in the sheet as well.

Finally, relabel the message with Gmail Modify Message Labels: add our "Triaged" label and remove the "Phishing Reports" label along with the unread marker, so the same email is never picked up twice.

Pace the work against VirusTotal rate limits. A free key allows only four requests per minute and five hundred per day, so space the lookups out rather than fanning out all at once, and stop early if VirusTotal starts returning quota errors, leaving the remaining emails unread for the next run. If a single email fails to process, log the failure, leave it unread so it retries later, and carry on with the rest.

Example output

🚨 Phishing verdict: MALICIOUS From: billing@acme-invoices[.]net Subject: Urgent: unpaid invoice #4417 Reported by: dana@ourcompany.com Links (1) • hxxps://acme-invoices[.]net/secure-login 9 of 72 engines flagged malicious Attachments (1) • invoice_4417.pdf 14 of 68 engines flagged malicious Logged to the compliance sheet and relabelled Triaged.

What does this prompt do?

  • Checks your shared phishing mailbox every 15 minutes and picks up anything staff have forwarded in under your phishing label.
  • Pulls out the sender, subject, links and attachments, then checks each one against a large bank of antivirus and URL scanning engines.
  • Posts a short verdict to your security channel (malicious, suspicious or clean) with every link rewritten so nobody can click it by accident.
  • Records one row per reported email in a spreadsheet for compliance, then relabels the message so it is never triaged twice.

What do I need to use this?

  • A Gmail account for the shared mailbox staff forward phishing to, with a "Phishing Reports" label and a "Triaged" label already set up.
  • A VirusTotal account. The free plan works fine, though it caps how many checks can run each day.
  • A Slack workspace and the channel where security alerts should land.
  • A Google Sheets spreadsheet to hold the running compliance log.

How can I customize it?

  • Change how often it runs, from every few minutes to once an hour, and cap how many reports it works through per run.
  • Adjust how many flagged engines it takes before something counts as malicious rather than just suspicious.
  • Point it at a different alert channel, spreadsheet or pair of labels to match how your team already works.

FAQs

Do I need a paid VirusTotal account?
No. The free plan works and is what most teams start on. It does limit you to a few hundred checks a day, so the workflow deliberately paces its lookups and only works through a handful of reported emails per run, letting any backlog drain steadily across later runs.
Will this click the links inside reported phishing emails?
No. Links are only ever submitted for a reputation check, never opened or followed. On top of that, every link in the Slack alert and the spreadsheet is written in a defanged form, so a teammate reading the alert cannot accidentally click through to a live phishing page.
What happens if a security check takes a while to come back?
Scans are not always ready instantly, so the workflow waits and re-checks a few times. If the result still is not ready, it falls back to any report already on file for that link rather than hanging or failing the whole run.
Can I use this with a shared reporting inbox instead of a personal one?
Yes, that is exactly what it is built for. It is designed around a shared mailbox where staff forward anything suspicious, and it works from a label rather than from individual recipients.
Does it delete or move the reported emails?
No. Nothing is deleted. Each message is simply relabelled as triaged once it has been processed, which both keeps a record in the mailbox and stops the same email being picked up twice.

Related templates

Build a credential rotation checklist when someone leaves

When someone leaves, we check which shared passwords they used in their final months and post a ranked rotation list to your security channel.

1Password
Rippling
Slack Bot
+1
Agentic Task
Trace phishing emails to the sending IP and report abuse

Every 15 minutes, forwarded phishing reports get traced back to the server that really sent them, with a verdict in Slack and the worst senders reported.

AbuseIPDB
Gmail
Slack
Agentic Task
Weekly Amazon S3 bucket security audit posted to Slack

Every Monday, check every S3 bucket for public exposure, missing encryption and weak backup settings, then get the risks ranked in Slack.

Amazon S3
Slack Bot
Google Sheets
Agentic Task
Log Agorapulse social conversations to HubSpot contacts

Twice every weekday, the conversations from your social inbox land on the right HubSpot contact timelines, with a Slack recap for sales.

Agorapulse
HubSpot
Slack Bot
Agentic Task
Turn procurement portal tenders into CRM deals each morning

Every weekday at 7am, sign in to the tender portals you track, filter new notices against your bid criteria, and open a deal for the ones worth chasing.

Anchor Browser
Google Sheets
HubSpot
+1
Agentic Task
Clean up HubSpot contacts from your Amazon SES suppression list

Every morning, find the addresses that hard bounced or filed a spam complaint, update the matching HubSpot contacts, and post a short Slack recap.

Amazon SES
HubSpot
Slack Bot
Agentic Task

Stop hand-checking every phishing report.

Let every forwarded email get checked, scored and logged automatically, so your team only spends time on the ones that turn out to be real.