مقاله

ربات ضداسپم پیشرفته: تشخیص رفتار مشکوک، نه فقط کلمه (قسمت ۲)

فیلتر کلمه‌ای به‌تنهایی اسپمرهای حرفه‌ای رو نمی‌گیره. قسمت دوم سری ربات مدیریت گروه: چطور با تحلیل رفتار (سرعت ارسال، پیام تکراری، سیل رسانه) اسپم واقعی رو تشخ…

ربات ضداسپم پیشرفته: تشخیص رفتار مشکوک، نه فقط کلمه (قسمت ۲)

در قسمت اول این سری دیدیم چرا هر گروه فعال به ربات مدیریت نیاز داره. حالا می‌ریم سراغ بخش سخت‌تر: ضداسپم واقعی. اکثر ربات‌های ساده فقط دنبال چند کلمه‌ی خاص می‌گردن — ولی اسپمرهای حرفه‌ای به‌راحتی با تغییر یک حرف یا استفاده از ایموجی از این فیلترها رد می‌شن. راه‌حل واقعی، نگاه‌کردن به رفتار کاربره، نه فقط متن پیامش.

فهرست مطالب

چرا فیلتر کلمه‌ای به‌تنهایی کافی نیست

یک فیلتر ساده دنبال کلمه‌ی «تخفیف» یا لینک می‌گرده. اما اسپمر حرفه‌ای می‌نویسه «ت.خ.فیف» یا از فاصله‌ی مخفی (نیم‌فاصله‌ی نامرئی) استفاده می‌کنه تا فیلتر رد بشه. مشکل اصلی اینه که فیلتر کلمه‌ای به چیه پیام نگاه می‌کنه، نه به چطور ارسال شده — و همین «چطور» معمولاً الگوی قابل‌تشخیص‌تری داره.

چهار الگوی رفتاری که اسپم رو لو می‌ده

  • سرعت ارسال غیرطبیعی: کاربر واقعی معمولاً بین پیام‌هاش چند ثانیه فاصله می‌ذاره؛ اسپمر (یا ربات) در عرض چند ثانیه چندین پیام می‌فرسته.
  • پیام تکراری: ارسال عین همون متن، چند بار پشت‌سرهم — الگوی کلاسیک اسپم تبلیغاتی.
  • سیل رسانه: ارسال ناگهانی و پی‌درپی چند عکس یا استیکر.
  • فعالیت فوری بعد از پیوستن: کاربری که تازه به گروه اضافه شده و بلافاصله (نه بعد از چند دقیقه مشاهده) شروع به ارسال محتوای تبلیغاتی می‌کنه.

پیاده‌سازی ۱: تشخیص بر پایه‌ی فرکانس ارسال

این کد روی همون حلقه‌ی دریافت پیام که در آموزش ساخت ربات روبیکا ساختیم سوار می‌شه. برای هر کاربر، زمان پیام‌های اخیرش رو نگه می‌داریم:

import time
from collections import defaultdict

user_message_log = defaultdict(list)
SPAM_THRESHOLD = 5    # حداکثر پیام مجاز
TIME_WINDOW = 10       # در این بازه، به ثانیه

def is_spamming(user_id):
    now = time.time()
    # فقط پیام‌های داخل بازه‌ی زمانی اخیر رو نگه دار
    user_message_log[user_id] = [
        t for t in user_message_log[user_id] if now - t < TIME_WINDOW
    ]
    user_message_log[user_id].append(now)
    return len(user_message_log[user_id]) > SPAM_THRESHOLD

یعنی اگه کاربری بیش از ۵ پیام در ۱۰ ثانیه بفرسته، is_spamming مقدار True برمی‌گردونه.

پیاده‌سازی ۲: تشخیص پیام تکراری

last_messages = defaultdict(str)

def is_duplicate(user_id, text):
    is_dup = (last_messages[user_id] == text)
    last_messages[user_id] = text
    return is_dup

نسخه‌ی ساده فقط با پیام قبلی مقایسه می‌کنه؛ برای تشخیص قوی‌تر (مثلاً تکرار در بازه‌ی چند دقیقه‌ای، نه فقط پیام بلافصل قبلی)، می‌تونید به‌جای یک رشته، یک لیست از چند پیام اخیر هر کاربر نگه دارید.

پیاده‌سازی ۳: ترکیب با اقدام خودکار

حالا این دو تابع رو داخل حلقه‌ی اصلی ربات صدا می‌زنیم:

def handle_message(message):
    user_id = message["author_object_id"]
    text = message.get("text", "")
    chat_id = message["chat_id"]

    if is_spamming(user_id) or is_duplicate(user_id, text):
        # اقدام سبک: حذف پیام + اخطار
        send_message(chat_id, "⚠️ لطفاً از ارسال پی‌درپی پیام خودداری کنید.")
        # برای اقدام سخت‌گیرانه‌تر (مثل سکوت موقت)، از متدهای مدیریتی
        # مستندشده در بخش «متدهای پرکاربرد» آموزش ساخت ربات روبیکا استفاده کنید
    else:
        # پردازش عادی پیام
        pass

جدول آستانه‌های پیشنهادی

نوع گروهپیام مجازبازه‌ی زمانی
گروه پشتیبانی آروم۳ پیام۱۰ ثانیه
گروه عمومی/بحث فعال۶-۸ پیام۱۰ ثانیه
گروه با فعالیت بسیار بالا۱۰+ پیام۱۰ ثانیه

اشتباهات رایج

  • آستانه‌ی خیلی سخت‌گیرانه: کاربر واقعی که هیجان‌زده پشت‌سرهم پیام می‌ده رو هم اسپمر حساب می‌کنه — با یک گروه تست، آستانه رو تنظیم کنید.
  • نادیده‌گرفتن ادمین‌ها: همیشه چک کنید کاربر ادمین نیست قبل از اعمال محدودیت.
  • ذخیره‌ی نامحدود لاگ در حافظه: برای گروه‌های خیلی بزرگ، پاک‌سازی دوره‌ای user_message_log رو فراموش نکنید تا مصرف حافظه بالا نره.

سوالات متداول

آیا این روش، نیاز به فیلتر کلمه‌ای رو کاملاً حذف می‌کنه؟

نه؛ بهترین نتیجه از ترکیب هر دوست — فیلتر کلمه برای موارد واضح (لینک، کلمات ممنوعه)، تحلیل رفتاری برای الگوهای پیچیده‌تر.

چرا به‌جای حذف فوری، فقط اخطار می‌دیم؟

برای جلوگیری از مسدودکردن اشتباهی کاربر واقعی؛ می‌تونید منطق رو طوری تغییر بدید که بعد از چندمین اخطار، اقدام سخت‌گیرانه‌تر (سکوت یا حذف) اعمال بشه.

آیا این کد روی بله هم کار می‌کنه؟

بله، منطق تشخیص کاملاً مستقل از پلتفرمه؛ فقط کافیه send_message رو با تابع معادلش در آموزش ساخت ربات بله جایگزین کنید.

جمع‌بندی

حالا یک سیستم ضداسپم واقعی دارید که فراتر از یک لیست کلمه‌ی ممنوعه عمل می‌کنه. در قسمت ۳، سراغ خوش‌آمدگویی هوشمند و مدیریت ورود/خروج اعضا می‌ریم. اگه نمی‌خواید این منطق رو خودتون پیاده‌سازی کنید، سورس آماده‌ی ربات ضدلینک و مدیریت گروه رو ببینید.

نظرات کاربران

فقط نظرات تاییدشده مدیر نمایش داده می‌شود.

0 نظر تاییدشده
هنوز نظری برای این مطلب منتشر نشده است.