A production localization pipeline built entirely on the OpenAI API: one English source of truth, SEO-aware translation prompts, cross-model verification with
Open-source Python tool that discovers URLs from sitemap.xml, validates each in desktop and mobile modes with parallel checks, monitors domain registrations via WHOIS, and delivers instant Telegram alerts.
Key Results

Any website with a non-trivial number of pages faces the same monitoring gap: you can ping a homepage, but you can't manually check every URL that sitemap.xml knows about — especially across both desktop and mobile. Add domain registrations across multiple TLDs to the mix and the surface area grows fast. Missed renewals, silent nameserver changes, and pages that return 200 with an empty body are all failure modes that standard uptime monitors miss entirely — and the paid ones that do catch them charge a monthly subscription per site.
Site Pulse is an open-source tool I built to close that gap: it watches your whole site and your domains, runs unattended on a cron schedule, and pings your Telegram the second something looks wrong. It is MIT-licensed and self-hostable, so there's no per-site subscription and nothing leaves your own server.
It has three jobs. First, it reads your sitemap.xml directly, so monitoring always reflects the site as it actually is today — add a page, and it's covered automatically. Second, it checks every one of those pages in both desktop and mobile modes, retrying on failure and flagging pages that return "OK" but come back suspiciously empty — the kind of silent breakage a basic uptime ping sails right past. Third, it watches your domain registrations across any number of extensions, warning you a full 90 days before one expires and flagging if the nameservers ever quietly change.
When it finds a problem — a down page, a slow response, an expiring domain — it sends an instant Telegram alert, with per-type controls so you only hear about what you care about. A companion log analyser then groups the results and surfaces your slowest, least stable, and heaviest pages.
| Metric | Value |
|---|---|
| Codebase | ~757 lines Python |
| Parallel workers | 10 (ThreadPoolExecutor) |
| Device modes | Desktop + Mobile per URL |
| Domain monitoring | Any number of TLDs via WHOIS |
| Expiry warning | 90 days before expiration |
| Scheduling | Cron-based, fully automated |
The system runs unattended via cron, dynamically adapting to sitemap changes and delivering Telegram alerts within seconds of detecting an issue — whether it's a down page, a slow response, or an expiring domain.
For the technically curious, here is how the core pieces are built.
Parallel URL validation using ThreadPoolExecutor with session reuse and conditional Telegram notifications:
# website_monitor.py
def check_pages() -> None:
"""Check all websites from the list"""
timestamp = datetime.now().strftime("%d.%m.%Y %H:%M:%S")
messages_to_send = []
with requests.Session() as session:
def check_with_session(url):
return check_single_page(url, session)
with ThreadPoolExecutor(max_workers=MAX_WORKERS) as executor:
future_to_url = {
executor.submit(check_with_session, url): url
for url in URLS_TO_CHECK
}
for future in concurrent.futures.as_completed(future_to_url):
message, is_success, is_warning, is_error = future.result()
if (is_success and NOTIFY_SUCCESS) or \
(is_warning and NOTIFY_WARNING) or \
(is_error and NOTIFY_ERROR):
messages_to_send.append(message)
if messages_to_send:
message = f"📅 {timestamp}\n\n" + "\n\n".join(messages_to_send)
send_telegram_message(message)Result: 10 parallel workers with session reuse, configurable notification granularity, automatic message aggregation.
Each URL is checked in both device modes with automatic retry on failure and response size validation:
# website_monitor.py
def check_single_page(url: str, session: requests.Session) -> tuple:
def try_request(headers, device_type):
start_time = time.time()
response = session.get(
url,
timeout=(CONNECT_TIMEOUT, READ_TIMEOUT),
headers=headers
)
content_length = len(response.content)
elapsed_time = time.time() - start_time
if response.status_code == 200 and content_length >= MIN_RESPONSE_SIZE:
return response, content_length, elapsed_time, None
else:
if response.status_code != 200:
raise Exception(f"Response code: {response.status_code}")
else:
raise Exception(f"Response size too small: {content_length} bytes")
# Desktop check with retry
try:
try:
response, content_length, elapsed_time, _ = try_request(
DESKTOP_HEADERS, "Desktop"
)
except Exception:
time.sleep(5)
response, content_length, elapsed_time, _ = try_request(
DESKTOP_HEADERS, "Desktop"
)Result: Catches both HTTP errors and suspiciously small responses (e.g. empty pages returning 200), with a 5-second retry delay.
WHOIS-based domain check that validates expiration dates and verifies nameservers match expected configuration:
# website_monitor.py
def check_domain(domain: str) -> tuple[str, bool]:
"""Check domain registration expiry and nameservers"""
w = whois.whois(domain)
if isinstance(w.expiration_date, list):
expiry_date = min(w.expiration_date)
else:
expiry_date = w.expiration_date
days_until_expiry = (expiry_date - datetime.now()).days
domain_ns = [ns.lower() for ns in w.name_servers]
our_ns = [ns.lower() for ns in OUR_NAMESERVERS]
using_our_ns = any(ns in domain_ns for ns in our_ns)
messages = []
has_warning = False
if days_until_expiry <= EXPIRY_WARNING_DAYS:
messages.append(f"⚠️ Domain will expire in {days_until_expiry} days")
has_warning = True
if not using_our_ns:
messages.append(f"⚠️ Domain is using external nameservers")
has_warning = TrueResult: Handles WHOIS quirks (some registrars return lists instead of single dates), monitors both expiration and DNS configuration drift.
AvailableNeed something similar?
I build custom solutions — from APIs to full products. Let's talk about your project.
A production localization pipeline built entirely on the OpenAI API: one English source of truth, SEO-aware translation prompts, cross-model verification with
Production algorithmic trading system for perpetual futures — multi-account, event-driven architecture with dynamic progressive grid and 10-level risk
Bybit grid trading bot in Python: event-driven architecture, ATR-based grid steps, 10-level risk management, atomic state persistence, and pytest test suite
How to publish one dataset to npm, PyPI, Go Module, RubyGems, and Packagist automatically with GitHub Actions — architecture, versioning, and per-ecosystem