Alert when a label hits a backlog threshold
Warn the Northwind team in Slack when a Gmail label has more than N unread threads.
Published Mar 31, 2026
A shared Gmail label only works if someone is watching it. Northwind routes support requests, new leads, and overdue invoices into labels with a filter, but the labels themselves are quiet — nobody sees a backlog building until a customer chases for the second time.
This script puts a number on the backlog. It counts the unread threads in each label you care about, and if a label has crept past its threshold it posts a warning into Slack where the team will actually see it. The labels stay tidy because someone gets nudged the moment one starts to fill up.
What you’ll need
- The Gmail labels you want to watch, already in use — for example
support,leads/new, andinvoices/overdue. - An incoming webhook URL for the Slack channel that should receive the alerts. Create one in Slack’s app settings under Incoming Webhooks.
- The webhook URL stored as
SLACK_WEBHOOKin Script Properties, so it never sits in the code — see Store API keys and secrets securely.
The script
// Each label and the unread count that counts as a backlog.
const THRESHOLDS = {
'support': 20,
'leads/new': 10,
'invoices/overdue': 5,
};
/**
* Counts the unread threads in each watched label and posts a Slack
* warning for any label that has gone past its threshold.
*/
function checkBacklogs() {
// 1. Pull the Slack webhook from Script Properties.
const webhook = PropertiesService.getScriptProperties().getProperty('SLACK_WEBHOOK');
if (!webhook) {
Logger.log('No SLACK_WEBHOOK set — cannot send alerts.');
return;
}
// 2. Check each label against its own limit.
for (const [labelName, limit] of Object.entries(THRESHOLDS)) {
// Count the unread threads carrying this label.
const count = GmailApp.search(`label:${labelName} is:unread`).length;
// Within the limit — nothing to report for this label.
if (count <= limit) continue;
// 3. Over the limit: post a warning into Slack.
UrlFetchApp.fetch(webhook, {
method: 'post',
contentType: 'application/json',
payload: JSON.stringify({
text: `:warning: *${labelName}* has ${count} unread (limit ${limit}).`,
}),
});
Logger.log(`Alerted: ${labelName} at ${count} (limit ${limit}).`);
}
}
How it works
checkBacklogsreads the Slack webhook URL from Script Properties. If it is not set, it logs a message and stops rather than failing mid-run.- It loops over each entry in
THRESHOLDS— a label name paired with the unread count that counts as a backlog. - For each label it runs a Gmail search for unread threads carrying that label and takes the length of the result as the count.
- If the count is at or below the limit, it moves straight on to the next label — no message.
- If the count is over the limit, it posts a formatted warning to the Slack webhook naming the label, the current count, and the limit.
Example run
Say the labels currently hold these unread counts when the script runs:
| Label | Unread | Limit | Result |
|---|---|---|---|
| support | 24 | 20 | over — alert |
| leads/new | 6 | 10 | under — quiet |
| invoices/overdue | 9 | 5 | over — alert |
Slack receives two messages:
:warning: support has 24 unread (limit 20).
:warning: invoices/overdue has 9 unread (limit 5).
Trigger it
Run this on a timer so the team gets a steady read on the backlog:
- In the Apps Script editor open Triggers and click Add Trigger.
- Choose
checkBacklogs, set the event source to Time-driven, and pick an Hour timer of every hour. - To keep it to business hours, leave it hourly and accept the off-hours runs — they cost nothing — or split into two triggers if you prefer.
Watch out for
- This alerts on every run while a label stays over its limit. An hourly
trigger on a label stuck at 25 unread will post every hour. To send one
alert per breach, store a
lastAlertedAttimestamp in Script Properties keyed by label and skip the post if you alerted recently. GmailApp.searchcounts whole threads, not individual messages — a thread with five unread replies counts as one.- Nested labels need their full path: use
leads/new, notnew. A typo in a label name silently returns a count of zero and never alerts. - Gmail search has daily usage limits. A handful of labels checked hourly is well within them, but do not point this at dozens of labels on a frequent timer.
Related
Convert long email threads into a summary note
Collapse a thread's history into a Doc for handover — perfect for client transitions or vacation cover.
Updated Jun 6, 2026
Pull event RSVPs from emails into a Sheet
Parse yes/no replies to event invites and tally attendance automatically.
Updated Jun 2, 2026
Turn forwarded emails into project tasks
Forward to [email protected] and a row lands in the Projects sheet under the right client.
Updated May 30, 2026
Turn starred emails into a task list
Sync every starred thread into the Northwind Tasks sheet automatically.
Updated May 26, 2026
Rank email templates by reply rate
Log every templated send and compute which subject lines and bodies actually earn replies.
Updated Mar 24, 2026