How to Build Your Very Own “Website Monitor”
Ever been caught mashing the
F5
key on your keyboard, refreshing your website like it’s part of a cardio workout? We've all been there. The good news? Modern technology has made that frantic refreshing obsolete. Enter the
“Website Monitor”—an automation flow that checks if your favorite sites are up, running, and showing that oh-so-important piece of content you need. It even sends you notifications if anything goes awry. Think of it as your personal digital butler, minus the sarcastic remarks.
This tutorial contains both Lumnar Flow automation flow and a complete PHP script that does the same thing. You can easily adapt the logic to any other automation tool you prefer, such as Make.com or n8n.com.
Go PRO and build this in raw code
You can of course follow the same logic in this tutorial and build your own custom script that does all this efficiently and without any limitations or cost.
We have prepared a complete code version that you can use on your own hosting, but most of all you could further customize it to fit your particular needs. This is what we at Lumnar Creations normally do for our customers.

1. Collecting the Addresses (No Snail Mail Required ;P)
First, create a Text Block to hold all your websites—one per line. For each line, you’ll separate the site’s URL from the string-to-check with
||
. Here’s a quick example:
https://site.tld||Some Very Specific String https://another-site.tld||An Exclusive Keyword
- Avoid using obvious words like your site’s name or “Welcome.” Error pages love those words too.
- The key is to pick something that only appears on the actual, valid page.
Why This Matters: This ensures you know the site is not just alive but actually showing the correct content.
2. The Grand Loop: Repeating the Process for Each Site
Add a for_each block. This block acts like your personal “repeat button,” taking each line from your text list and running it through the rest of the flow:
- It isolates each line from your text list.
- It processes them one by one, letting you check multiple sites in one go.
3. Parsing the Data: Splitting the URL from the String
For each line, we need to separate the URL from the string. Enter our dynamic duo, the Data Block and Text Block:
- The Text Block uses
||
to split the line. - The Data Block stores these pieces in variables, like
site_url
andtarget_string
.
Why This Matters: Think of it as giving a treasure hunter the coordinates—they’ll know exactly where to look (the site URL) and what to look for (the target string).
4. Making Sure We Have Valid Data
Add a Branch Block to check if
site_url
and
target_string
are both valid. If one is missing, we gracefully skip that line instead of throwing the entire flow into chaos.
5. Making the Call: Checking the Website
Time to see if the website is in tip-top shape. The HTTP_Request block does the job:
- Sends a GET request to
site_url
. - Times out after 5 seconds (because who wants to wait forever?).
- Retrieves the site’s response and any content served.
Outcome Possibilities:
– Success (200 OK): The site responded!
– Error: The site took too long or returned something sad like 404 or 503.
6. Checking Past Behavior
Next, let’s give our flow some memory. The
Data_Retrieve block looks up previously saved data for this
site_url
.
If data is found, we compare it against the latest check to see if anything changed—like the string was there before, but is gone now. If there’s no previously saved data, we’ll store whatever we get now for future reference.
7. Was the Site Online, and Did We Find the String?
Another Branch Block steps in to handle this newfound knowledge:
- Check Site Status: Did our response come back with a
200
status? - Check Target String: Is our cherished
target_string
present in the page content? - Compare with Past Data: Has something changed since the last check?
Depending on these checks, the flow branches in different directions: a happy path if it’s all good, or a worried path if something’s off.
8. Ringing the Alarm
So, what happens if something changes or breaks? We bring in our Telegram Block for notifications.
- If the site is online and the string is present, we might send a joyful “Everything’s looking good!” message.
- If the site is online but the string is missing, we can send a “Heads up, your site responded, but the magic string isn’t there!” alert.
- If the site isn’t responding, it’s time for a “Big trouble—your site’s down!” message.
Remember to set up your Telegram bot or channel beforehand. Sending notifications by carrier pigeon might be romantic, but it’s not exactly efficient.
9. Scheduling the Big Show
Lastly, a scheduled_event block ensures the flow runs automatically every 5 minutes (or on your chosen schedule) from the “start” branch. That way, it can quietly monitor your sites, repeating the cycle infinitely—until it finds something worth telling you about.
The End Result
With these steps in place, you’ve built a friendly automation that systematically checks each site, confirms it’s online, looks for that crucial string, compares results to past data, and notifies you if anything changes.
Key Takeaways:
- Preparation is everything: Storing each site and string in a text block makes updates painless.
- Smart branching: Use Branch Blocks to keep the flow calm, cool, and collected.
- Effortless repetition: The combination of
for_each
andscheduled_event
blocks keeps the checks going without any manual intervention.
So go forth, dear friend, and let your “Website Monitor” do the heavy lifting while you sip your morning coffee. Enjoy fewer frantic refreshes and more peace of mind!
Complete PHP Script
Automation flows done with some sort of interface are useful when you want to have a clear overview of the entire process, and easy edit the logic later without messing with code. Here’s the full script that follows the same logic and achieves same results as the described flow in this article (just copy & paste into your server file):
Full Code Snippet
Code Example: Building Your Own Website Monitor
Below is a sample PHP script that demonstrates how you can build your own website monitor directly in PHP code. This script checks if a list of websites are up and if they contain a specific string. It also sends you a Telegram notification if anything changes.
<?php
/**
* Website Checker Script
*
* This script reads a list of URLs and search strings from a text file.
* For each URL, it performs a short timeout cURL request, checks if the
* response code is 200 (online) and if the page content contains the specified string.
* It then compares the current status to a previously stored status (in a file named by md5(url).txt).
* If the status has changed, it updates the file and sends a Telegram notification.
*/
// -------------------------
// Telegram Credentials
// -------------------------
$telegramBotToken = 'YOUR_TELEGRAM_BOT_TOKEN';
$telegramChatId = 'YOUR_TELEGRAM_CHAT_ID';
// -------------------------
// Configuration
// -------------------------
$listFile = 'urls.txt'; // The file containing URL and search string pairs (format: url||searchString)
$curlTimeout = 10; // cURL timeout in seconds
// -------------------------
// Check if the list file exists
// -------------------------
if (!file_exists($listFile)) {
die("List file not found: $listFile");
}
// -------------------------
// Read and process each line from the list file
// -------------------------
$lines = file($listFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
foreach ($lines as $line) {
$line = trim($line);
if (empty($line)) {
continue; // Skip empty lines
}
// Expecting format: url||searchString
$parts = explode('||', $line);
if (count($parts) !== 2) {
// Skip lines that don't have exactly 2 parts
continue;
}
$url = trim($parts[0]);
$searchString = trim($parts[1]);
if (empty($url) || empty($searchString)) {
continue; // Skip if either part is missing
}
// -------------------------
// Step 3: Perform a short timeout cURL call to fetch content
// -------------------------
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, $curlTimeout);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
$content = curl_exec($ch);
$curlError = curl_errno($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
// -------------------------
// Step 5: Determine the current status
// -------------------------
$currentStatus = [
'site_online' => ($httpCode === 200 && !$curlError) ? 'yes' : 'no',
'matched_content' => (strpos($content, $searchString) !== false) ? 'yes' : 'no'
];
// -------------------------
// Step 4: Load previous status from file (or initialize if missing)
// -------------------------
$statusFile = md5($url) . '.txt';
$previousStatus = null;
if (file_exists($statusFile)) {
$previousStatus = json_decode(file_get_contents($statusFile), true);
}
// -------------------------
// Step 6: Compare current status with previous status
// -------------------------
$statusChanged = false;
if (
!$previousStatus ||
$previousStatus['site_online'] !== $currentStatus['site_online'] ||
$previousStatus['matched_content'] !== $currentStatus['matched_content']
) {
$statusChanged = true;
// Save the new status (overwrite previous data)
file_put_contents($statusFile, json_encode($currentStatus));
}
// -------------------------
// Step 7: If there is a change, send a Telegram notification
// -------------------------
if ($statusChanged) {
$message = "Status change for URL: $url\n";
$message .= "Site Online: " . $currentStatus['site_online'] . "\n";
$message .= "Matched Content: " . $currentStatus['matched_content'];
$telegramUrl = "https://api.telegram.org/bot{$telegramBotToken}/sendMessage?chat_id={$telegramChatId}&text=" . urlencode($message);
// Using file_get_contents to send the API call.
file_get_contents($telegramUrl);
echo "<pre><code>";
echo $message;
echo "</code></pre>";
}
}
?>
Now all you need to do is prepare your Telegram token and get your chat ID, and you are ready to go. Add this script in a cron, or make it run periodically in any other way you prefer (could just add a refresh meta at the end, so it refreshes every 5min, if you don't have access to set your own cron jobs).
Written by Max Lumnar
Building custom webs since '98, Max is a full-stack developer, AI enthusiast and founder of Lumnar Creations.