Monitor Website Uptime With Node.js and Discord Alerts
Ensuring your website stays up and available is a critical part of maintaining a reliable user experience. While there are many third-party tools for uptime monitoring, building your own uptime checker with Node.js provides flexibility, customization, and cost-efficiency. In this tutorial, we’ll walk through creating a Node.js uptime monitor that pings one or more endpoints and sends alerts to a Discord channel using webhooks whenever downtime is detected.
1. Setting Up the Project
First, initialize a new Node.js project and install the dependencies. We’ll use node-fetch or the native https module for HTTP requests and dotenv for managing environment variables securely.
mkdir website-uptime-ping
cd website-uptime-ping
npm init -y
npm install node-fetch dotenv
Now create the following file structure:
.
├── .env
├── index.js
Inside your .env file, store your Discord webhook URL securely:
DISCORD_WEBHOOK_URL=https://discord.com/api/webhooks/your_webhook_id
2. Writing the Uptime Check Logic
We want our script to check a list of websites at regular intervals and detect if any are down. Here’s a simple version using node-fetch:
// index.js
require('dotenv').config();
const fetch = require('node-fetch');
const websitesToMonitor = [
{ name: "MyBlog", url: "https://myblog.com" },
{ name: "MyAPI", url: "https://api.myservice.com" }
];
async function checkWebsite(website) {
try {
const res = await fetch(website.url, { timeout: 5000 });
if (!res.ok) throw new Error(`Status code: ${res.status}`);
console.log(`[UP] ${website.name} is online.`);
} catch (err) {
console.error(`[DOWN] ${website.name} is not reachable.`);
sendDiscordAlert(website, err.message);
}
}
In this example, we use fetch with a short timeout to quickly determine whether a site is responsive. If the response isn’t OK (anything other than HTTP 2xx), we consider the site down.
3. Sending Discord Alerts via Webhooks
Discord webhooks allow you to send rich messages into channels via simple HTTP POST requests. Let’s create a function to send a nicely formatted embed alert:
async function sendDiscordAlert(website, reason) {
const webhookUrl = process.env.DISCORD_WEBHOOK_URL;
const payload = {
username: "Uptime Bot",
embeds: [
{
title: `⚠️ ${website.name} is DOWN!`,
description: `URL: ${website.url}\nReason: ${reason}`,
color: 15158332, // red
timestamp: new Date().toISOString(),
footer: {
text: "Website Uptime Monitor"
}
}
]
};
try {
await fetch(webhookUrl, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
});
console.log(`Alert sent for ${website.name}`);
} catch (err) {
console.error("Failed to send Discord alert", err);
}
}
This function constructs a rich embed with a red color and sends it to your Discord channel. You can further customize the alert with fields like thumbnails, author fields, or links.
4. Scheduling Website Checks
Now, we’ll tie it together in a scheduler that checks the sites at set intervals (e.g., every 5 minutes):
function monitorWebsites() {
websitesToMonitor.forEach(site => checkWebsite(site));
}
// Run immediately, then set interval
monitorWebsites();
setInterval(monitorWebsites, 5 * 60 * 1000);
This will ensure the monitor runs on launch and continues checking every 5 minutes thereafter. You could use setTimeout with recursive logic for more control if desired.
5. Performance, Reliability & Deployment Tips
1. Keep it light: Avoid too many requests—monitor only critical sites. For large-scale use, consider rate limits and performance constraints.
2. Handle false positives: Integrate basic retry logic to avoid alerts from momentary glitches:
async function checkWithRetry(website, retries = 2) {
for (let i = 0; i <= retries; i++) {
try {
await checkWebsite(website);
break;
} catch (e) {
if (i === retries) {
sendDiscordAlert(website, "Multiple failed attempts.");
} else {
await new Promise(res => setTimeout(res, 1000));
}
}
}
}
3. Run it 24/7: Deploy the script on a cloud VM (like AWS EC2, or Railway.app) or a container platform. Use process managers like PM2 to ensure resilience and automatic restarts.
4. Logging: Use a lightweight logging library or logging service integration (e.g., Logtail, Loggly) for visibility into uptime performance.
Conclusion
With just Node.js and a Discord webhook, you can build a practical and extensible website uptime monitor that meets many real-world requirements. It’s a great starting point for more complex monitors—perhaps even adding status dashboards, SMS alerts, or incident tracking in the future. Happy coding and stay online!
Useful links:


