Checks every site listed in a spreadsheet on a schedule and alerts you in Slack or by email when one goes down or recovers.
Uses
Gmail
Google Sheets
Slack
Watch your websites for downtime
sitesSheetUrl to blank.Set sitesSheetUrl to blank.sitesTabName to Sites.Set sitesTabName to Sites.statusTabName to Status log.Set statusTabName to Status log.alertSlackChannelId to blank.Set alertSlackChannelId to blank.alertEmailAddress to blank.Set alertEmailAddress to blank.maxSites to 25.Set maxSites to 25.checkedAt.Get the current date and time and save it as checkedAt.siteRows to an empty list.Set siteRows to an empty list.siteListErrorIf a step below fails, save the error as siteListErrorTry
sitesSheetUrl. Save it as siteList.Read the rows of sitesSheetUrl. Save it as siteList.siteRows to siteList.rows.Change siteRows to siteList.rows.On error
siteListError.message).Stop and report a problem: Could not read the site list, so nothing was checked. Check that the spreadsheet in 'sitesSheetUrl' has a tab named as in 'sitesTabName'. (siteListError.message).logRows to an empty list.Set logRows to an empty list.logHasHeader to false.Set logHasHeader to false.logReadErrorIf a step below fails, save the error as logReadErrorTry
sitesSheetUrl. Save it as storedLog.Read the rows of sitesSheetUrl. Save it as storedLog.logRows to storedLog.rows.Change logRows to storedLog.rows.logHasHeader to the length of storedLog.headers is greater than 0.Change logHasHeader to the length of storedLog.headers is greater than 0.On error
logReadError.message).Show in the output: There is no status log yet, so this run creates it and records what it finds as the starting point. (logReadError.message).createTabErrorIf a step below fails, save the error as createTabErrorTry
statusTabName in sitesSheetUrl.Create the tab statusTabName in sitesSheetUrl.On error
createTabError.message).Show in the output: Could not create the status log tab; carrying on in case it already exists. (createTabError.message).logHasHeader is noIf logHasHeader is noYes
headerErrorIf a step below fails, save the error as headerErrorTry
statusTabName in sitesSheetUrl.Add a row to statusTabName in sitesSheetUrl.On error
headerError.message).Show in the output: Could not write the status log header row. (headerError.message).No
No steps
sitesChecked to 0.Set sitesChecked to 0.sitesDown to 0.Set sitesDown to 0.site in siteRows:For each site in siteRows:siteUrl to blank.Set siteUrl to blank.urlErrorIf a step below fails, save the error as urlErrorTry
site.URL and save it as siteUrl.Trim site.URL and save it as siteUrl.On error
A row in the site list has no 'URL' column, so it was skipped. Check that the first row of the sites tab has a column headed URL..Show in the output: A row in the site list has no 'URL' column, so it was skipped. Check that the first row of the sites tab has a column headed URL..siteUrl is emptyIf siteUrl is emptyYes
No
No steps
sitesChecked.Add 1 to sitesChecked.isUp to false.Set isUp to false.detail to blank.Set detail to blank.checkErrorIf a step below fails, save the error as checkErrorTry
siteUrl and save it as response.Fetch siteUrl and save it as response.isUp to response.ok.Change isUp to response.ok.detail to Answered with HTTP response.status as text.Change detail to Answered with HTTP response.status as text.On error
isUp to false.Change isUp to false.detail to Could not be reached. checkError.message.Change detail to Could not be reached. checkError.message.currentStatus to Down.Set currentStatus to Down.isUp is yesIf isUp is yesYes
currentStatus to Up.Change currentStatus to Up.No
sitesDown.Add 1 to sitesDown.lastStatus to blank.Set lastStatus to blank.lastChangedAt to blank.Set lastChangedAt to blank.entry in logRows:For each entry in logRows:logRowErrorIf a step below fails, save the error as logRowErrorTry
entry.URL and save it as entryUrl.Trim entry.URL and save it as entryUrl.entry.Status and save it as entryStatus.Trim entry.Status and save it as entryStatus.entry.Time and save it as entryTime.Trim entry.Time and save it as entryTime.entryUrl is siteUrlIf entryUrl is siteUrlYes
lastStatus to entryStatus.Change lastStatus to entryStatus.lastChangedAt to entryTime.Change lastChangedAt to entryTime.No
No steps
On error
logRowError.message).Show in the output: Ignored a status log row that is missing a column. (logRowError.message).currentStatus is not lastStatusIf currentStatus is not lastStatusYes
logWriteErrorIf a step below fails, save the error as logWriteErrorTry
statusTabName in sitesSheetUrl.Add a row to statusTabName in sitesSheetUrl.On error
siteUrl in the status log. (logWriteError.message).Show in the output: Could not record the change for siteUrl in the status log. (logWriteError.message).alertSubject to blank.Set alertSubject to blank.alertBody to blank.Set alertBody to blank.currentStatus is DownIf currentStatus is DownYes
alertSubject to Site down: siteUrl.Change alertSubject to Site down: siteUrl.alertBody to siteUrl did not answer as expected.Change alertBody to siteUrl did not answer as expected.
detail
First seen at checkedAt.Else if @lastStatus isn't empty
alertSubject to Site back up: siteUrl.Change alertSubject to Site back up: siteUrl.alertBody to siteUrl is answering again.Change alertBody to siteUrl is answering again.
detail
It had been down since lastChangedAt.Otherwise
No steps
alertSubject isn't emptyIf alertSubject isn't emptyYes
alertSlackChannelId isn't emptyIf alertSlackChannelId isn't emptyYes
slackErrorIf a step below fails, save the error as slackErrorTry
alertSlackChannelId.Send a message to alertSlackChannelId.alertSubject
alertBodyOn error
siteUrl to Slack. (slackError.message).Show in the output: Could not post the alert for siteUrl to Slack. (slackError.message).No
No steps
alertEmailAddress isn't emptyIf alertEmailAddress isn't emptyYes
emailErrorIf a step below fails, save the error as emailErrorTry
alertEmailAddress.Send an email to alertEmailAddress.
Subject: alertSubjectalertBodyOn error
siteUrl. (emailError.message).Show in the output: Could not email the alert for siteUrl. (emailError.message).No
No steps
No
No steps
No
No steps
sitesChecked as text site(s); sitesDown as text not answering.Show in the output: Checked sitesChecked as text site(s); sitesDown as text not answering.