Just built an uptime monitor

jasonleow  •  10 Jan 2026   •    
Screenshot

Freshping is going to be discontinued in March. :(

I use it to monitor uptime for Lifelog, my plugins site and a bunch of other important URLs for my projects. I guess this is the risk of being free.

No problemo. Vibecoding to the rescue!

I used perplexity.ai to vibecode a Google Apps Script to ping my sites every 10 minutes, and send an email to respective emails if there’s downtime. This took all like 15min. And another 10min to set it up. No server, no cron, no repo. Just plain Javascript mixed with Google Apps Scripts syntax.

I name it Daily Ping:

// Full Google Apps Script - Multiple sites + per-site emails
// SETUP
// Tl;dr - Paste into script.google.com → New project → Save → Add Trigger (every X minutes)
//
// 1. script.google.com → New project
// 2. Replace SITES array with your sites/emails above
// 3. Save (Ctrl+S)
// 4. Run setupTrigger (select from dropdown → big play button → authorize)
// 5. Done! Every X minute(s) checks + custom emails automatically
// 6. Check triggers manually: Click Triggers icon (clock) in left sidebar. Should see: checkAllSites → "Every 10 minutes" → Status: green
// 7. Check logs: Executions tab (left sidebar). See recent runs? → ✅ Working perfectly

const SITES = [
  {
    name: 'Main Site',
    url: 'https://yoursite.com',
    email: 'main-admin@gmail.com',
    expectedStatus: 200
  },
  {
    name: 'API',
    url: 'https://api.yoursite.com',
    email: 'api-team@gmail.com', 
    expectedStatus: 200
  },
  {
    name: 'Dashboard',
    url: 'https://dashboard.yoursite.com',
    email: 'you@gmail.com',
    expectedStatus: 200
  }
  // Add more sites here ↓
];

function checkAllSites() {
  const timestamp = new Date().toLocaleString();
  
  SITES.forEach((site, index) => {
    checkSingleSite(site, timestamp, index);
  });
}

function checkSingleSite(site, timestamp, siteIndex) {
  try {
    const response = UrlFetchApp.fetch(site.url, {
      muteHttpExceptions: true,
      timeout: 10
    });
    
    const status = response.getResponseCode();
    
    if (status !== site.expectedStatus) {
      const subject = `🚨 ${site.name} DOWN`;
      const body = `
Site: ${site.name}
URL: ${site.url}
Status: ${status} (expected ${site.expectedStatus})
Time: ${timestamp}
      `.trim();
      
      MailApp.sendEmail(site.email, subject, body);
      console.log(`❌ ${site.name}: ${status}`);
    } else {
      console.log(`✅ ${site.name}: ${status}`);
    }
    
  } catch (error) {
    const subject = `🚨 ${site.name} ERROR`;
    const body = `
Site: ${site.name}
URL: ${site.url}
Error: ${error.toString()}
Time: ${timestamp}
    `.trim();
    
    MailApp.sendEmail(site.email, subject, body);
    console.log(`💥 ${site.name}: ERROR`);
  }
}

// One-click setup trigger (run this once)
function setupTrigger() {
  // Delete existing triggers
  ScriptApp.getProjectTriggers().forEach(trigger => {
    if (trigger.getHandlerFunction() === 'checkAllSites') {
      ScriptApp.deleteTrigger(trigger);
    }
  });
  
  // Create new one (every 1 minute)
  ScriptApp.newTrigger('checkAllSites')
    .timeBased()
    .everyMinutes(1)
    .create();
    
  console.log('✅ Trigger set: Runs every 1 minute');
}

It’s crazy how easy it is now to create your own simple tools with AI!
And I didn’t even need to have a server and mess with deployment and shit!

The code is really the easy part now.

Comments


Discover more

Sourced from other writers across Lifelog

Ooops we couldn't find any related post...