ServiceNow → Google Chat Alert Bot
A serverless bridge that monitors a shared Gmail inbox for ServiceNow incident emails, parses the relevant fields with regex, and pushes interactive Google Chat V2 Cards via webhook. Event-driven, zero infrastructure, running unattended 24/7.
Successfully implemented and deployed at one of my employers — running quietly in the background of the IT support team's shared inbox, routing incidents into the channel where they're actually read.
ServiceNow alerts that nobody read.
The IT support team lived in Google Chat. ServiceNow sent incident notifications by email, into a shared Gmail inbox that nobody actively watched. High-priority incidents were sitting unread for hours because email had quietly become a write-only medium.
The team had Google Workspace, no budget for a paid integration platform, and no appetite for a piece of infrastructure to babysit. The right answer was something serverless, free, and trivially auditable.
The constraint: no servers, no paid SaaS, no credentials sitting anywhere outside Google Workspace.
A time-triggered Apps Script with regex glue.
Time-based trigger
Apps Script fires the handler once a minute. Cheap, native, no external scheduler. The function is idempotent — re-running on the same thread is a no-op.
Gmail search for unread alerts
A scoped Gmail query (from:servicenow is:unread label:incidents) returns only the threads that haven't been processed yet, keeping the script's work bounded.
Regex extraction
Three regexes pull the INC number, priority, and affected user out of the alert body. ServiceNow's email template is stable enough that this beats a heavier HTML parser.
V2 Card to webhook
Builds a Google Chat V2 Card with header, key/value rows, priority chip, and an "Open in ServiceNow" button, then POSTs it to the room's incoming webhook URL.
Mark-read on success
Only after a 200 OK from the webhook does the thread get marked read and labelled — so a transient network blip results in a retry, not a dropped alert.
Error reporting in-channel
A separate try/catch posts parse failures as a muted card into a side channel for the maintainer, with the offending message ID. No silent breakage.
The whole core, in < 30 lines.
A V2 Card in the right channel, ~30 seconds after the alert.
- Priority
- P1 — High
- Caller
- j.kowalski@example.com
- Service
- VPN Access
- Opened
- 2026-05-19 09:14
Footprint & surface.
| Runtime | Google Apps Script (V8) |
| Trigger | Time-driven, every 1 minute |
| Inputs | Gmail search query, regex set, webhook URL |
| Outputs | Google Chat V2 Card via incoming webhook |
| Secrets | Webhook URL stored in Script Properties |
| Infrastructure | None — fully managed by Google Workspace |
| Cost | $0 — within Workspace quota |
| Failure mode | Retry on next minute; parse errors reported in-channel |