2026-04-14 22:14:08 -07:00
2026-04-14 22:14:08 -07:00
2026-04-12 21:28:07 -07:00
2026-04-12 19:07:08 -07:00
2026-04-14 22:14:08 -07:00

Voter-Uptime-Bot

A Discord bot that monitors the availability of web services and reports uptime statistics directly in your server. Built with discord.py, aiohttp, and pydantic-settings, it goes beyond simple HTTP checks — detecting Cloudflare intercept pages and validating real page content so you know your sites are genuinely reachable, not just returning a 200.


Features

  • Periodic polling — checks all configured sites every 15 minutes
  • Cloudflare intercept detection — identifies challenge/block pages that return HTTP 200 but serve no real content
  • Keyword content validation — confirms expected strings are present on the loaded page
  • Retry logic — re-attempts checks on transient CF intercepts before marking a site degraded
  • Uptime history — stores all check results in a local SQLite database
  • Discord slash commands — view live status, 24-hour bars, and monthly summaries per site

Commands

Command Description
/uptime now Current status of all monitored sites
/uptime day <site> 24-hour bar chart (🟩🟨🟥) with uptime %
/uptime month <site> Current month summary, one square per day
/uptime summarize Monthly uptime % for all sites at once

Project Structure

app/
├── __init__.py
├── bot.py          # Discord client, slash commands, polling task
├── checker.py      # SiteChecker — HTTP, CF detection, keyword validation
├── config.py       # Pydantic Settings — loads all config from .env
├── db.py           # SQLite init, insert, and fetch helpers
└── utils.py        # check_site wrapper, bar rendering, uptime maths

Configuration

All configuration is managed via a .env file using pydantic-settings. Copy .env.example to .env and fill in your values.

DISCORD_SECRET_KEY=your-bot-token-here
DISCORD_CLIENT_ID=123456789
DATABASE_PATH=uptime.db

# How often to poll all sites, in minutes (default: 15)
POLL_INTERVAL_MINUTES=15

# Discord channel ID to post alerts in. Set to 0 to disable alerts entirely.
ALERT_CHANNEL_ID=1493840872146600036

# Minimum minutes between repeat incident alerts for the same site.
# Recoveries always bypass this cooldown.
ALERT_COOLDOWN_MINUTES=30

MONITORED_SITES='[
  {
    "name": "MySite",
    "url": "https://example.com",
    "timeout_seconds": 10,
    "expected_keywords": ["Login", "Vote"],
    "max_retries": 1
  }
]'

Site config fields

Field Required Default Description
name Display name used in Discord
url Full URL to check
timeout_seconds 10 Request timeout
expected_status 200 Expected HTTP status code
expected_keywords [] Strings that must appear in the page body
max_retries 1 Extra attempts on CF intercept before marking degraded

How Checks Work

Each poll goes through three layers:

  1. HTTP status — non-2xx/3xx responses are marked degraded or down
  2. Cloudflare detection — response body is scanned for CF challenge fingerprints; a match is marked degraded even if status was 200
  3. Keyword validation — any expected_keywords that are missing from the body mark the site degraded

Results are stored with a detection_reason (cf_intercept, missing_keywords, http_503, timeout, etc.) so you can query historical failure causes.


Result States

State Emoji Meaning
up 🟩 HTTP OK, no CF intercept, all keywords present, latency < 3s
degraded 🟨 Reachable but CF intercept, missing content, slow, or 5xx
down 🟥 Timeout, connection failure, SSL error, or unexpected status

Installation

pip install -r requirements.txt

Run the bot:

python -m app.bot

Requirements

  • Python 3.11+
  • A Discord bot token with the applications.commands scope and bot scope enabled
  • The bot must be invited to your server with slash command permissions
Description
A Discord bot that monitors the availability of web services and reports uptime statistics directly in your server.
Readme MIT 50 KiB
Languages
Python 100%