Status Alert

Monitoring websites and services is a common task for IT teams. RapidForge can be used to monitor websites and services and send alerts to Discord, Slack or other platforms.

Lets create periodic task that will check website every 5 minutes and send alert to Discord if website is down.

  • Go to a block or create a new one.
  • Create a new periodic task.
  • Set cron to */5 * * * *
  • Paste the following script into the script field.

Rudimentary page monitoring script

website_url="https://yourwebsite.com"
discord_webhook_url="https://discord.com/api/webhooks/your-webhook-id/your-webhook-token"

send_discord_alert() {
    curl -H "Content-Type: application/json" \
         -X POST \
         -d "{\"content\": \"🚨 Alert! The website $website_url is down!\"}" \
         $discord_webhook_url
}

http_status=$(curl -o /dev/null -s -w "%{http_code}\n" $website_url)

# If the HTTP status code is not 200 (OK), send an alert
if [ "$http_status" -ne 200 ]; then
    echo "Website $website_url is down. Status code: $http_status"
    send_discord_alert
else
    echo "Website $website_url is online. Status code: $http_status"
fi

So far so good. We can now create a status page that will show the status of the website. Lets update our script first to use sqlite3 as a key-value store.

website_url="https://yourwebsite.com"
discord_webhook_url="https://discord.com/api/webhooks/your-webhook-id/your-webhook-token"

send_discord_alert() {
    curl -H "Content-Type: application/json" \
         -X POST \
         -d "{\"content\": \"🚨 Alert! The website $website_url is down!\"}" \
         $discord_webhook_url
}

# If sqlite installed in your host machine
# RapidForge creates a db and table to store key-value pairs
# db can be accessible via RF_KV_URL environment variable
update_status() {
status=$1
name=$2
key="status_${name}"
QUERY="
INSERT INTO KV (key, value)
VALUES (${key}, ${status})
ON CONFLICT(key)
DO UPDATE SET value = ${status};"

sqlite3 "$RF_KV_URL" "$QUERY"
}

http_status=$(curl -o /dev/null -s -w "%{http_code}\n" $website_url)

# If the HTTP status code is not 200 (OK), send an alert
if [ "$http_status" -ne 200 ]; then
    echo "Website $website_url is down. Status code: $http_status"
    send_discord_alert
    update_status "offline" $website_url
else
    update_status "online" $website_url
fi

We can now create a status page that will show the status of the website. Lets create GET end point called status_pages inside of the block and add the following script.

website_url="https://yourwebsite.com"
status=$(sqlite3 "$RF_KV_URL" "Select value from KV where key='status_${website_url}'")

# Generate the HTML snippet with the counter value
echo "<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Status Page</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            background-color: #f4f4f4;
            color: #333;
            padding: 20px;
            max-width: 600px;
            margin: auto;
        }
        h1 {
            text-align: center;
            color: #4CAF50;
        }
        .service {
            padding: 10px;
            border-bottom: 1px solid #ddd;
        }
        .service:last-child {
            border-bottom: none;
        }
        .status {
            font-weight: bold;
            padding: 5px;
            border-radius: 3px;
            margin-left: 10px;
        }
        .ok {
            color: green;
        }
        .offline {
            color: red;
        }
    </style>
</head>
<body>

<h1>System Status</h1>

<div class="service">
    Website <span class="status ${status}">${status}</span>
</div>
</body>
</html>"

This endpoint reads the status from the key-value store and returns the status page. We can add many more features to this status page. For example, we can add a link to the website and a link to the API. We can also add a counter that will show historical data or alter script to work with multiple websites. Sky is the limit.