I needed a way to monitor critical emails that should arrive regularly however, when they do not, I need to be notified. Rather than paying for expensive monitoring services, I built my own solution using Google Apps Script that runs 24/7 in the cloud and sends professional alerts when expected emails go missing.
What was the mission?
I have several automated systems that send me important emails:
- Daily email confirmations from lee@bythepowerofskeyskull.com
- Server status reports with subjects starting with "Automated Email Check"
- System health notifications that arrive every 15 minutes
If emails were not being delivered I would like to get a notification, but this needed to come from outside the company (I already have an internal one)
What I needed was a monitoring system that would:
- Check Gmail every 15 minutes for expected emails
- Stay completely silent when emails arrive normally
- Send immediate alerts when emails don't arrive
- Run automatically without any infrastructure on my end
Houston "we have a problem" Notification
This is a visual of the notification that is sent when the mail is not detected as per the script configuration, it needed to be very cleat and easy to read:
Core Monitoring Logic
Here's the heart of the monitoring system:
function checkForExpectedEmails() {
// Calculate time range (last 15 minutes)
const now = new Date();
const checkTime = new Date(now.getTime() - (CONFIG.checkWindow * 60 * 1000));
// Build Gmail search query
const searchDate = Utilities.formatDate(checkTime, Session.getScriptTimeZone(), 'yyyy/MM/dd');
const fullSearchQuery = `${CONFIG.searchQuery} after:${searchDate}`;
// Search for emails matching criteria
const threads = GmailApp.search(fullSearchQuery, 0, 10);
// Only alert if NO emails found
if (threads.length === 0) {
console.log('No expected emails found - sending alert');
sendAlert();
} else {
console.log(`Found ${threads.length} expected email(s) - no alert needed`);
}
}
Configuration Setup
I made the system configurable so I could easily monitor different email types, this was looking for the email being sent into the Google Mail from a certain sender and with a certain subject.
const CONFIG = {
// Email to send alerts to
alertEmail: 'lee@bythepowerofskeyskull.com',
// Search criteria for emails you're expecting
searchQuery: 'from:manager@idobeleiveinfaries.co.uk subject:"Automated Email Check"',
// Time window to check (in minutes)
checkWindow: 15,
// Alert details
alertSubject: 'Email Alert: Automated Email Check not received',
alertFromName: 'Email Monitor'
};
This searches for emails from a specific sender with subjects containing "Automated Email Check". Gmail automatically matches partial subjects, so it catches emails like:
- "Automated Email Check - Daily Report"
- "Automated Email Check: System Status"
- "Automated Email Check (July 19)"
When something goes wrong, I want clear, actionable alerts. I built professional HTML email templates that look like enterprise monitoring systems:
function sendAlert() {
const htmlBody = `
<!DOCTYPE html>
<html>
<body style="font-family: 'Segoe UI', sans-serif; margin: 0; padding: 0;">
<div style="max-width: 600px; margin: 0 auto; background-color: #ffffff;">
<!-- Alert Header -->
<div style="background: linear-gradient(135deg, #ff6b6b, #ee5a24); color: white; padding: 30px 20px; text-align: center;">
<div style="font-size: 48px; margin-bottom: 10px;">⚠️</div>
<h1 style="margin: 0; font-size: 24px;">Email Monitoring Alert</h1>
<p style="margin: 5px 0 0 0; opacity: 0.9;">Expected email not received</p>
</div>
<!-- Alert Details Table -->
<div style="padding: 30px 20px;">
<table style="width: 100%; border-collapse: collapse;">
<tr>
<td style="padding: 12px 15px; font-weight: 600;">Search Criteria:</td>
<td style="padding: 12px 15px; font-family: monospace;">${CONFIG.searchQuery}</td>
</tr>
<tr>
<td style="padding: 12px 15px; font-weight: 600;">Status:</td>
<td style="padding: 12px 15px;">
<span style="background-color: #dc3545; color: white; padding: 4px 12px; border-radius: 20px;">MISSING</span>
</td>
</tr>
</table>
</div>
</div>
</body>
</html>
`;
GmailApp.sendEmail(CONFIG.alertEmail, CONFIG.alertSubject, textBody, { htmlBody: htmlBody });
}
These alerts include gradient headers, status badges, detailed tables, and recommended actions - much more professional than basic text emails.
Alert Strategy: Silence is Golden
I made a crucial design decision: the system only sends emails when there's a problem. There are no "everything is fine" notifications.
This prevents alert fatigue - when people receive too many routine notifications, they stop paying attention to alerts entirely. With this system:
- Silence means everything is working
- An email means immediate attention required
This approach ensures that when I do receive an email, I know it's genuinely important.
Step-by-Step Installation Guide
Here's how to set up the email monitoring system:
1. Create the Google Apps Script
- Go to script.google.com
- Click "New project"
- Delete the defauly myFunction() code:
- Paste the data (when requested from the link)
- Save the project with a meaningful name like "Email Monitor"
2. Configure Your Settings
Update the "config" object at the top of the script:
SetalertEmail
to where you want alerts sentSet
searchQuery
to match your expected emailsAdjust
checkWindow
if you want different timing Save the script (Ctrl+S)
3. Set Up Automatic Triggers (not optional)
The script will NOT work without this step - triggers are mandatory for automatic operation.
Manual trigger creation:
Click on the Project
Click the clock icon (⏰) in the left sidebar
Click "+ Add Trigger" with the options below:
Check the "Executions" tab to see automatic runs
Look for entries with "Time-driven" type (not "Editor")
Monitor logs to ensure the system runs without errors, if you click on the logs you will see the outcome:
5. Monitor and Maintain
Check execution logs periodically for any errors which can be done from the Overview option:
Gmail API Limits and Scalability
I was initially concerned about hitting Google's API limits, but the usage is actually very light:
For Reading Emails (Monitoring):
- Each Gmail search uses ~1-5 quota units
- Running every 15 minutes = 96 daily executions
- Total daily usage: ~500 quota units
- Daily limit: 1 billion quota units
The key insight is that Google's limits are designed to prevent abuse, not restrict legitimate monitoring applications.