بناء أداة تنبيه (Alert System) على Telegram عند حدوث مشكلة في الموقع

دقائق القراءة: 3

بناء أداة تنبيه (Alert System) على Telegram عند حدوث مشكلة في الموقع

الاعتماد على فحص الموقع يدوياً لم يعد مناسباً لأي مشروع جاد. في بيئات النشر الحديثة، قد يتوقف الموقع، أو يرتفع زمن الاستجابة، أو تظهر أخطاء 500 و403 وtimeout في أي لحظة، ما ينعكس مباشرة على تجربة المستخدم، الزحف، والتحويلات.

هنا تظهر قيمة بناء نظام تنبيه ذكي يرسل إشعاراً فورياً إلى Telegram عند اكتشاف خلل. هذا النوع من الأتمتة لا يخدم الإدارة التقنية فقط، بل يخدم أيضاً فرق السيو التي تريد الاستجابة السريعة للمشكلات التي قد تؤثر على الفهرسة والأداء العضوي.

إذا كنت تتابع مسار الأتمتة من البداية، فهذه الفكرة امتداد عملي لما تم شرحه في مدخل إلى عالم أتمتة الـ SEO: لماذا الآن؟، كما أنها تعتمد على تجهيز بيئة برمجية نظيفة كما في تهيئة بيئة العمل: تثبيت Python والمكتبات الأساسية.

لماذا يعتبر Telegram خياراً ممتازاً للتنبيهات؟

من الناحية العملية، يوفر Telegram Bot API واجهة بسيطة، سريعة، ومجانية تقريباً لمعظم الاستخدامات الصغيرة والمتوسطة. كما أن الرسائل تصل فوراً إلى الهاتف أو سطح المكتب، ويمكن توجيهها إلى شخص واحد أو مجموعة عمل كاملة.

ميزة أخرى مهمة هي أن الإشعار يمكن أن يحمل سياقاً مفيداً: عنوان الصفحة المتأثرة، كود الاستجابة، مدة التأخير، وقت الفحص، وعدد مرات الفشل المتتالية. هذا يعني أن التنبيه لا يكون مجرد إنذار، بل تقريراً مختصراً قابلاً للتصرف السريع.

البنية المنطقية للنظام

قبل كتابة أي سطر برمجي، من الأفضل تصور النظام على شكل مهام صغيرة. هذا الأسلوب قريب من منطق البرمجة المعتمد على المهام (Task-Oriented Programming) لأنه يجعل الكود أبسط في الاختبار والصيانة.

مكونات أداة التنبيه

  • قائمة روابط أو صفحات حرجة نريد مراقبتها.
  • دالة ترسل طلب HTTP GET لكل رابط.
  • منطق يحدد ما إذا كانت النتيجة طبيعية أو مشكلة.
  • دالة لإرسال رسالة إلى Telegram.
  • آلية تمنع تكرار التنبيه بشكل مزعج عند استمرار نفس العطل.
  • جدولة دورية عبر جدولة المهام (Cron Jobs) لتعمل الأدوات أثناء نومك.

إنشاء البوت والحصول على بيانات الاتصال

ابدأ بإنشاء بوت عبر @BotFather داخل تيليجرام. بعد الإنشاء ستحصل على BOT_TOKEN. بعد ذلك أرسل رسالة إلى البوت أو أضفه إلى مجموعة، ثم استخرج CHAT_ID.

لا تضع المفاتيح الحساسة مباشرة داخل المستودع البرمجي. الأفضل تخزينها في متغيرات بيئة Environment Variables وفق ممارسات الحماية والأمان: كيف تخفي مفاتيحك السرية في الكود؟.

سكربت Python كامل لفحص الموقع وإرسال التنبيه

السكربت التالي يبني نسخة عملية قابلة للتشغيل فوراً. يقوم بفحص عدة روابط، ويتعامل مع الأخطاء الشبكية، ويسجل حالات الفشل، ويرسل رسالة إلى تيليجرام فقط عند حدوث انتقال فعلي من حالة سليمة إلى حالة معطلة، أو عند عودة الموقع للعمل.

import os
import json
import time
from datetime import datetime
import requests

BOT_TOKEN = os.getenv("TELEGRAM_BOT_TOKEN")
CHAT_ID = os.getenv("TELEGRAM_CHAT_ID")

URLS_TO_CHECK = [
    "https://example.com",
    "https://example.com/blog",
    "https://example.com/contact"
]

TIMEOUT_SECONDS = 12
STATE_FILE = "monitor_state.json"


def load_state():
    if os.path.exists(STATE_FILE):
        with open(STATE_FILE, "r", encoding="utf-8") as f:
            return json.load(f)
    return {}


def save_state(state):
    with open(STATE_FILE, "w", encoding="utf-8") as f:
        json.dump(state, f, ensure_ascii=False, indent=2)


def send_telegram_message(text):
    api_url = f"https://api.telegram.org/bot{BOT_TOKEN}/sendMessage"
    payload = {
        "chat_id": CHAT_ID,
        "text": text,
        "parse_mode": "HTML"
    }
    response = requests.post(api_url, data=payload, timeout=15)
    response.raise_for_status()


def check_url(url):
    start = time.time()
    try:
        response = requests.get(url, timeout=TIMEOUT_SECONDS, allow_redirects=True)
        elapsed = round(time.time() - start, 2)
        status_code = response.status_code

        if 200 <= status_code < 400:
            return {
                "ok": True,
                "status_code": status_code,
                "response_time": elapsed,
                "error": None
            }

        return {
            "ok": False,
            "status_code": status_code,
            "response_time": elapsed,
            "error": f"Unexpected status code: {status_code}"
        }

    except requests.RequestException as e:
        elapsed = round(time.time() - start, 2)
        return {
            "ok": False,
            "status_code": None,
            "response_time": elapsed,
            "error": str(e)
        }


def format_down_message(url, result):
    now = datetime.utcnow().strftime("%Y-%m-%d %H:%M:%S UTC")
    return (
        f"🚨 Website Alert\n"
        f"URL: {url}\n"
        f"Status: DOWN\n"
        f"Code: {result['status_code']}\n"
        f"Time: {result['response_time']}s\n"
        f"Error: {result['error']}\n"
        f"Checked at: {now}"
    )


def format_recovery_message(url, result):
    now = datetime.utcnow().strftime("%Y-%m-%d %H:%M:%S UTC")
    return (
        f"✅ Website Recovery\n"
        f"URL: {url}\n"
        f"Status: UP\n"
        f"Code: {result['status_code']}\n"
        f"Time: {result['response_time']}s\n"
        f"Checked at: {now}"
    )


def main():
    state = load_state()

    for url in URLS_TO_CHECK:
        result = check_url(url)
        previous_status = state.get(url, {}).get("ok")

        if result["ok"] is False and previous_status is not False:
            send_telegram_message(format_down_message(url, result))

        elif result["ok"] is True and previous_status is False:
            send_telegram_message(format_recovery_message(url, result))

        state[url] = result

    save_state(state)


if __name__ == "__main__":
    main()

كيف يعمل هذا السكربت عملياً؟

1) فحص الرابط

تعتمد الأداة على مكتبة requests لإرسال الطلب. إذا عاد كود بين 200 و399 نعتبر الحالة سليمة. أما أخطاء الخادم أو فشل الاتصال فتتحول إلى حالة عطل.

2) حفظ الحالة السابقة

استخدام ملف JSON بسيط يمنع الإزعاج. فبدلاً من إرسال تنبيه كل دقيقة أثناء استمرار المشكلة، يتم إرسال رسالة واحدة عند السقوط، ورسالة ثانية عند التعافي. وإذا أردت فهم التعامل مع هذا النوع من البيانات أكثر، راجع أساسيات التعامل مع ملفات JSON (لغة التفاهم بين الأنظمة).

3) الإرسال إلى Telegram

الإرسال يتم عبر نقطة النهاية sendMessage في واجهة Telegram Bot API. هذا النموذج قابل للتوسعة بسهولة لإرسال صور أو ملفات سجل أو حتى روابط إلى لوحة متابعة داخلية.

تحسينات احترافية تجعل الأداة أكثر ذكاءً

النسخة الأساسية جيدة، لكن بيئات الإنتاج تحتاج عادة إلى طبقات إضافية من الحماية والمنطق.

  • إضافة شرط retry قبل إعلان العطل لتجنب التنبيه بسبب انقطاع لحظي.
  • فحص محتوى الصفحة وليس فقط كود الحالة، لأن بعض الصفحات تُرجع 200 مع صفحة خطأ فعلية.
  • مراقبة زمن الاستجابة، وإرسال إنذار عند تجاوز حد مثل 3.5s.
  • ربط النتائج مع Google Sheets أو قاعدة بيانات للاحتفاظ بسجل زمني.
  • إضافة صفحات سيو حساسة مثل /sitemap.xml و/robots.txt.

إذا كنت تبني منظومة فحص أوسع، فمن المفيد دمج هذه الأداة مع تقنيات مراقبة الروابط والأداء مثل استخدام Python لفحص الروابط المعطلة (404) في المواقع الكبيرة وفحص سرعة الصفحات (PageSpeed Insights API) لجميع روابط الموقع آلياً.

جدولة التشغيل التلقائي

لكي تعمل الأداة فعلاً كنظام مراقبة، يجب تشغيلها دورياً كل عدة دقائق. في خادم Linux يمكن استخدام crontab لتشغيل الملف مثلاً كل خمس دقائق. بذلك تتحول الفكرة من سكربت يدوي إلى خدمة مراقبة عملية.

احرص على تسجيل مخرجات التشغيل والأخطاء في ملف log مستقل، لأن غياب التنبيه أحياناً لا يعني سلامة الموقع، بل قد يعني أن السكربت نفسه توقف عن العمل.

البعد السيوي والتشغيلي للأداة

هذه الأداة ليست مجرد رفاهية تقنية. في مشاريع المحتوى، أي تعطل في صفحات مهمة قد يؤدي إلى خسارة زيارات، تعطيل حملات، وتأخر في اكتشاف مشكلات الفهرسة. لهذا فإن الربط بين الأتمتة والمراقبة يصنع طبقة استجابة سريعة تحمي الأداء العضوي وتقلل مدة الانقطاع.

كما يمكن لاحقاً تطوير النظام ليرسل تنبيهات مخصّصة عند فشل صفحات بعينها، أو عند تغير عناصر حساسة في الصفحة مثل title وmeta robots، وهو ما يفتح الباب لبناء منظومة إنذار سيو متقدمة مرتبطة بمهام تحليل أكبر.

خاتمة

بناء نظام تنبيه على Telegram عند حدوث مشكلة في الموقع هو مشروع صغير في الحجم، لكنه كبير في الأثر. فهو يجمع بين البساطة البرمجية، القيمة التشغيلية، والاستجابة الفورية للمشكلات قبل أن تتحول إلى خسائر حقيقية.

وعندما تتبنى هذا النموذج كجزء من منظومة الأتمتة لديك، ستجد أنك لا تبني مجرد سكربت، بل طبقة مراقبة ذكية قابلة للتوسع، والربط مع واجهات أخرى، والتكامل مع أدوات السيو والتحليلات في مشروع واحد أكثر نضجاً واعتمادية.

اترك تعليقاً

لن يتم نشر عنوان بريدك الإلكتروني. الحقول الإلزامية مشار إليها بـ *