You don't need a paid uptime monitoring service for simple projects. With Apps Script and a time-based trigger, you can check your site every few minutes and get alerted the moment it goes down.
Basic uptime check
functioncheckUptime(){const url ='https://yourwebsite.com';try{const response =UrlFetchApp.fetch(url,{muteHttpExceptions:true});const statusCode = response.getResponseCode();if(statusCode >=200&& statusCode <300){Logger.log(`✅ ${url} is UP (${statusCode})`);}else{Logger.log(`❌ ${url} returned status ${statusCode}`);sendDownAlert(url, statusCode);}}catch(e){Logger.log(`❌ ${url} is unreachable: ${e.message}`);sendDownAlert(url,'Unreachable');}}functionsendDownAlert(url, status){GmailApp.sendEmail('[email protected]',`⚠️ Site Down: ${url}`,`Your site ${url} appears to be down.\nStatus: ${status}\nTime: ${newDate()}`);}
Log response times to a Google Sheet
functioncheckUptimeAndLog(){const sites =['https://yourwebsite.com','https://api.yourwebsite.com/health',];const sheet =SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();// Add header row if sheet is emptyif(sheet.getLastRow()===0){ sheet.appendRow(['Timestamp','URL','Status Code','Response Time (ms)','Status']);} sites.forEach(url=>{const start =Date.now();let statusCode ='Error';let status ='DOWN';try{const response =UrlFetchApp.fetch(url,{muteHttpExceptions:true}); statusCode = response.getResponseCode(); status = statusCode >=200&& statusCode <300?'UP':'DOWN';}catch(e){ statusCode = e.message;}const responseTime =Date.now()- start; sheet.appendRow([newDate(), url, statusCode, responseTime, status]);if(status ==='DOWN'){sendDownAlert(url, statusCode);}});}
Avoid alert spam with cooldown tracking
Without a cooldown, you'll get an email every 5 minutes while your site is down. Use PropertiesService to track when the last alert was sent:
functioncheckWithCooldown(){const url ='https://yourwebsite.com';const cooldownMinutes =30;const lastAlertKey ='LAST_ALERT_TIME';let statusCode;try{const response =UrlFetchApp.fetch(url,{muteHttpExceptions:true}); statusCode = response.getResponseCode();}catch(e){ statusCode =0;}const isDown = statusCode <200|| statusCode >=300;if(isDown){const props =PropertiesService.getScriptProperties();const lastAlert = props.getProperty(lastAlertKey);const now =Date.now();if(!lastAlert ||(now -parseInt(lastAlert))> cooldownMinutes *60*1000){GmailApp.sendEmail('[email protected]',`⚠️ Site Down: ${url}`,`Status: ${statusCode ||'Unreachable'}\nTime: ${newDate()}`); props.setProperty(lastAlertKey,String(now));Logger.log('Alert sent.');}else{Logger.log('Site down, but within cooldown period. No alert sent.');}}else{// Reset cooldown when site is back upPropertiesService.getScriptProperties().deleteProperty(lastAlertKey);Logger.log(`✅ ${url} is UP (${statusCode})`);}}