Да, я победил спам! Не «в основном», а «полностью и окончательно». Без всяких «почти». По крайней мере, на 99.9% победил. Причем этот 0.1% — не спам, прорвавшийся через фильтры, а false positives, которые не «вытащил» обратно в Inbox.

Eсли интересно — читайте под катом.

Программы и методы этой статьи могут быть адаптированны к любому из трех типов почтовых сервисов:

  • Gmail (используется Google Script)

  • Hotmail, Outlook.com, Live.com (почтовый сервис Майкрософта, используется Graph API)

  • Любой email сервис, поддерживающий IMAP через Basic Authentication (Login‑Password)


Собственно, false positives была проблема #1. В принципе, Gmail and Outlook.com хорошо справляются со спамом. Они отправляют его в Spam фолдер. В обоих сервисах у меня в этом фолдере в сутки было около 30 сообщений, но были случаи, когда это число доходило до 70.

В принципе ничего страшного, но ведь периодически (раз в неделю) надо заглядывать в Спам фолдер чтобы проверить, нет ли там false positive. А сделать это среди сотен спамовых сообщений не совсем тривиально.

В случае с Gmail‑ом можно настроить фильтры и применять их к сообщениям таким образом, чтобы проблемый email отправлялся миную Спам сразу в Корзину. А вот Hotmail это не позволяет: если сервис решил, что сообщение — спам, к нему не применяются фильтры (созданные в веб интерфейсе).

Вторая проблема: оба сервиса не позволяют «уничтожать» сообщения сразу, минуя Корзину. Через фильтры можно только переместить спам‑сообщение в Корзину, но не «прибить» его (кстати, mail.ru позволяет это сделать). Таким образом, даже при иделальной сортировке фильтрами в корзине скапливаются тысячи сообщений. Номинально оба сервиса говорят, что сообщения остаются в Корзине и Спаме 30 дней, но фактически это минимальный срок. В некоторых ситуациях они там могут сидеть месяцами (а то и годами), если их не вытирать вручную. Баг это или такой дизайн — я не знаю. А иметь сотни или тысячи стертых сообщений в Корзине — это вредно по разным причинам (Privacy, производительность, проблемы с поиском).

Третья проблема: имя и фамилия моей жены полностью совпадают с именем и фамилией нью‑йоркского врача (женщины). Соответственно, жена получала кучу медицинского спама и не совсем спама (рассылки медицинских журналов и реклама вполне легитимных медицинских препаратов и лекарств для применения врачами). От чего‑то удалось отписаться, но спам не прекращался.

Четвертая проблема: на аккаунт жены идут рассылки (судя по всему, медицинские) из европейских стран. Но мы не читаем по‑венгерски, по‑испански и по‑французски!

После того, как жена заявила «или я или спам», мне пришлось действовать.

Самым простым решением было бы написать простой сервис для доступа к емайлам через IMAP и делать фильтрацию программным путем в случаях, когда это невозможно сделать фильтрами. Естетственно, фильтрация будет производиться уже после получения письма, но если запускать cron job каждые 15 минут, то особой проблемы нет.

Иногда я получаю спам (на мой aol.com аккаунт), где английский Sender Name или Subject хитро закодирован и спам фильтры его не отлавливают, но с точки зрения человека все читается. Этот метод применяется если в теме письма, например, есть текст на английском и русском языке одновременно, но в случае с AOL спамом идет кодирование исключительно английского текста. Этот аккаунт в принципе не должен получать email‑ы на зыках, отличных от английского.

В качестве тестирования IMAP кода я взял мой aol.com аккаунт и вот что получилось (спасибо Claude.ai за помощьв фильтрации). Я убрал некоторые элементы из кода для этой статьи, но принцип, думаю, понятен.

Вот код:
https://github.com/comrade‑ogilvy/email‑antispam‑scripts/blob/main/imap/purge_aol_spam.py

Код по ссылке позволяет фильтровать символ «\u00ad» который используется в Subject‑e исключительно спаммерами. Именно этот символ в моем случае для моего аккаунта в aol.com является гарантированным 100%‑ым индикатором спама. Мало того, 99% спама были с этим символом.

Кроме того, теперь я могу полностью стереть сообщения с темой вроде «Привет, asmirnov» когда ваш email asmirnov@domain.tld, а вас зовут Александр Смирнов. Им не то что в Спам‑фолдере делать нечего, их, по‑хорошему, надо вообще не давать «приземлиться» в mailbox‑e

BLOCKED_NAME_KEYWORDS    = ["mylogin"]  # matched against decoded display name (user's login)
BLOCKED_SUBJECT_KEYWORDS = ["mylogin"]  # matched against decoded subject
BLOCKED_DOMAINS          = ["comms.aol.net", "ankerdc.com"] # e.g. ["spam.com", malicious.net"]

SOFT_HYPHEN = "\u00ad"

При желании, можно полностью стереть сообщение или переместить его в Корзину.

Но у этого метода есть свои недостатки: нужен сервер, на котором в том или ином виде будут находится логин‑пароль, что не есть хорошо.

К счастью, у Гугла есть облачный сервис Google Script, который очень хорошо умеет работать с электронной почтой.

Логика кода та же, но не нужен отдельный VPS плюс не нужно писать пароль от вашего аккаунта в коде или где‑то хранить его.

Пример кода https://github.com/comrade‑ogilvy/email‑antispam‑scripts/blob/main/gmail/gmail_purge_gmail_trash_and_spam_folders.js

который очищает мой Спам фолдер от гарантированного спама (он несколько отличается от реально работающего лода, связано со спецификой моих email‑ов, я убрал элементы, которые наверняка не будут интересны читателям Хабра). В большинстве случаев — навсегда, даже без перемещения в корзину. Например, если у sender domain отсутствуют MX и A records (From: ghsdjfadjfdjgfd@iuwadjkrei.com), то я сразу стираю это сообщение. Это правило уничтожило где‑то 90–95% спама

Есть и другие критерии:

Если сообщение в Спаме не от домена в моем (не РКН) белом списке, то переместить в Корзину.

Вот список:

var ALLOWED_TLDS = [
  ".com",
  ".net",
  ".org",
  ".il",
  ".uа",
  ".ru",
  ".ca",
  ".cz",  
];

Я, конечно получаю изредка легитимные сообщения из.uk или.es, но ни разу не было случая, что легитимное сообщение из.uk или.es было помечено Гуглом как спам (код по ссылке очищает именно Спам фолдер, а не Inbox). Пусть сразу идет в Корзину,

Eсли сообщение в моем (не РКН) черном списке, то отправить его в Корзину (хотя, надо наверное, стереть без следа)

Я точно знаю, что, к примеру, емайлы от veganinfo.com мне не нужны ни в каком варианте и никогда не будут нужны. Я не хочу их видеть и себя в mailbox‑e. Но... в данном примере, я все‑же решил не стирать немедленно такие сообщения. Их относительно мало и оно не являются проблемой. Пусть 3 дня поживут в Корзине.

Пример черного списка

var BLOCKED_DOMAINS = [
  ".tk",
  "onlinecrm.marketing",
  "veganinfo.com",
];

После установки триггера скрипта на https://script.google.com на «запускать каждые 15 минут» в Спам фолдере остались, фактически только false positives. Их мало — максимум 5 в месяц, обычно меньше, но зато я их сейчас вижу без проблем.

Остальной спам сразу переходит в Корзину. Kорзина очищается этим же скриптом: остаются сообщения за последние 3 дня, мне так спокойнее.

function purgeDeletedFolder() {
  console.log("purgeDeletedFolder() started");

  var threads = GmailApp.search('in:trash older_than:3d');

  threads.forEach(function(thread) {
    Gmail.Users.Threads.remove('me', thread.getId());
  });

  console.log("purgeDeletedFolder() ended");
}

На каждое выполнение скрипта мне приходит отчет в Телеграм (на всякий случай).

function sendToTelegram() {

  var BOT_TOKEN = "xxxxxxxxx:zzzzzzzzzzz-wwwwwwwwwww";
  var CHAT_ID = "-yyyyyyyyyyy";

  var deleteRate = stats.processed > 0
    ? ((stats.deleted / stats.processed) * 100).toFixed(2)
    : 0;

 
  var text =
    "Spam Cleanup Report\n\n" +
    "Processed: " + stats.processed + "\n" +
    "Deleted: " + stats.deleted + " (" + deleteRate + "%)\n" +
    "Permanently deleted: " + stats.permanently_deleted + "\n\n" +

    "SPF misaligned: " + stats.spf_misaligned + "\n" +
    "Infra abuse: " + stats.infra_abuse + "\n\n" +

    "Cache hits: " + stats.cache_hit;

  if (stats.permanently_deleted_list.length > 0) {
    text += "\n\n Permanently deleted:\n";

    stats.permanently_deleted_list.slice(0, 20).forEach(function(e) {
      text += "• " + e + "\n";
    });

    if (stats.permanently_deleted_list.length > 20) {
      text += "...and more (" + stats.permanently_deleted_list.length + ")";
    }
  }

  var url = "https://api.telegram.org/bot" + BOT_TOKEN + "/sendMessage";

  UrlFetchApp.fetch(url, {
    method: "post",
    payload: {
      chat_id: CHAT_ID,
      text: text
    }
  });
}

Теперь займемся медицинским спамом.

Как я уже писал, жена получала много медицинского спама и спама с национальных европейских доменов. Фильтрация стандартными фильтрами по домену в Гугле проблематична. Например, если вы сделате фильтр для.de (Германия), то он отсеет также abc.de@domain.tld, что, очевидно, плохо. Фильтрация по медицинским терминам может отсеять легитимную переписку с врачем или родственником.

Поэтому, я скормил спам‑сообщения жены Claude.ai и он выдал свои рекоммендации и сразу же их и реализовал. Идея в том, что медицинский спам рассылается ограниченным колличеством mass mailing сервисов, которые я с радостью заблокировал. Заодно заблокировал (как и в моем случае) спам, где отправитель — несуществующий домен. По какой‑то причине, на аккаунте жены эти сообщения иногда прорывались сквозь фильтры. Теперь они идут в корзину каждые 15 минут. Опять‑таки, по идее их надо уничтожать на месте, но мне не хотелось делать такие резкие движения не на моем аккаунте.

Код очистки Inbox‑a жены:

https://github.com/comrade‑ogilvy/email‑antispam‑scripts/blob/main/gmail/purge_gmail_inbox_example.gs

Интересный факт: вот эти «товарищи» ответственны за 75% спама в ящике жены (почти весь «легитимный» медицинский спам идет от них:

var MEDICAL_SPAM_DOMAINS = [
  "info.haymarketmedicalnetwork.com",
  "haymarketmedicalnetwork.com",
  "haymarketmedia.com",
  "en25.com",          // Oracle Eloqua marketing platform
  "mdedge.com",
  "healio.com",
  "medscape.com",
  "givingsight.org",        // <-- add: Optometry Giving Sight
  "bloomerang-mail.com",     // <-- add: their sending platform
  "nejm.org",          // add/remove based on what she receives
  "aao.org"
];

Также отправил в Корзину все сообщения не из белого списка (жены, не РКН).

Вот этот белый список:

var ALLOWED_TLDS = [
  ".com",
  ".net",
  ".org",
  ".gov",
  ".il",
  ".ua",
  ".ru",
  ".ca",
  ".cz",
  ".de",
];

А вот это —

var KNOWN_GOOD_DOMAINS = {
  "gmail.com": true,
  "googlemail.com": true,
  "outlook.com": true,
  "hotmail.com": true,
  "live.com": true,
  "outlook.co.il": true,
  "hotmail.co.il": true,
  "mail.com": true,
  "fastmail.com": true,
  "yahoo.com": true,
  "icloud.com": true,
  "aol.com": true,
  "walla.com": true,
  "walla.co.il": true,
  "ukr.net": true,
  "i.ua": true,
  "mail.ru": true,
  "yandex.com": true,
  "yandex.ru": true,
  "ceznum.cz": true,
};

список почтовых сервисов, на которые не надо выполнять DNS запросы на A и MX записи. Используется, чтобы минимизировать колличество сетевого трафика из скрипта. Иначе можно и бан получить от Гугла в какой‑то ситуации. Это не значит, что вся почта с этих доменов — легитимная. Это всего‑лишь означает, что сами домены — легитимные.

Фильтрация спама на почтовом сервисе Майкрософта (Hotmail, outlook.com, live.com)

Третий пример: фильтрация спама на Hotmail‑овском Спам фолдерe с целью его очистки для быстрого поиска false positives. Для этого используется Graph API, так как стандартная аутентификация по логину‑паролю для IMAP‑a больше не работает на сервисах Майкрософта.

Основная проблема Hotmail‑a в том, что если Майкрософт решил, что сообщение — спам, то на него не действуют пользовательские фильтры, что не позволяет сразу удалять сообщения в Корзину в момент получения. Плюс относительно большое колличество false positives, которые надо перемещать в Inbox как минимум, вручную, а как максимум — программным путем.

Пример кода (я убрал из реального кода специфические моменты, которые неинтересны 99% хабраюзеров)

https://github.com/comrade‑ogilvy/email‑antispam‑scripts/blob/main/hotmail‑outlook/purge_hotmail_spam_folder.py

Я получал десятки спам‑сообщений в день. После беседы с Claude выяснилось, что 90% спама идут с 6 доменов, еще 3–4% — от какого‑то mailer‑a который использует 4 дефиса «‑--» в поле From.
Что‑то вроде abcde@‑--‑mail.xyz.com
Такие email‑ы сразу стираются, остальные (максимум 1–2 в день) заканчивают свою жизнь в Корзине. Фактически, на этом этапе в Спам фолдере остаются исключительно false positives.

В реальном коде (не в этом примере) гарантированно false positives сразу перемещаются в Inbox.

Отдельный вопрос: почему Майкрософт ничего не делает с этой spam farm? Она «работает» уже несколько лет, что стоит отфильтровать эти несчасные 6 или 7 доменов на своих серверах еще до того, как сообщение оказывается в почтовом ящике?

Ради интереса, я пересылю статистику по очищенным сообщениям на сервис временной почты yopmail.com. У него есть RSS интерфейс, что очень удобно для беглого просмотра статистики

Это — веб интерфейс

A это — RSS интерфейс моего RSS reader‑a

Вроде всё. Если есть вопросы — пишите в комментарии или ЛС.

Отдельное спасибо Claude.de за анализ нескольких тысяч спам сообщений и рекоммендации и правки кода для программной фильтрации спама.

Автор выражает благодарность СhatGPT за генерацию изображения для обложки, Кириллу и Мефодию за буквы русского алфавита, а этрускам — за буквы латинского алфавита.

Весь код в репозитории по ссылкам опубликован по лицензии MIT. Делайте, что хотите, но я не несу ответсвенность за бесследно уничтоженные email‑ы при использовании этого кода и за любые другие последствия его использования включая, но не ограничиваясь, сбои в работе компьютера, поломки жесткого диска, потерю работы, неназначение интервью и так далее

Комментарии (11)


  1. KEugene
    24.05.2026 06:03

    Белый список фильтра... ну так себе.


    1. Kiborg777 Автор
      24.05.2026 06:03

      Если белый список не навязан извне, легко отлключается или модифицируется конечным пользователем, покрывает 100% легитимных входящих писем и убивает 30% спама, то почему бы и нет.

      var ENABLE_TLDS_VALIDATION = true;
      
      var ALLOWED_TLDS = [
        ".com",
        ".net",
        ".org",
        ".gov",
        ".co.il",
        ".org.il",
        ".net.il",
        ".gov.il",
        ".ua",
        ".ru",
        ".ca",
        ".cz",
        ".de",
      ];

      Вот эта строчка
      var ENABLE_TLDS_VALIDATION = true;

      его отключает при замене на false. И да, иногда я отключаю его совсем или модифицирую его. Например, при поездке в Испанию я добавлял в список домены .es и .pt, а после поездки убрал их.


      1. KEugene
        24.05.2026 06:03

        Ну это примерно как на телефоне включить "принимать звонки только от контактов". Можно и так. Хотя почему бы уже просто не ограничить списком допустимых имейлов? А то какая-то непонятная мне логика: .co.il есть, а .co нет, .com есть, а .com.il нет ну и так далее, в том числе .net - oк, а .biz - не ок. Я уже молчу про национальные домены. Насколько я понимаю, получить .com и тем более .net может любой, а вот национальный домен - не факт. Например , в Австралии для получения .au надо быть зарегистрированным бизнесом (и доказать это регистратору).


        1. Kiborg777 Автор
          24.05.2026 06:03

          В принципе, список

          ".co.il", ".org.il", ".net.il", ".gov.il",

          можно заменить на .il

          Просто хотел протестировать ситуацию с доменами 3-го уровня. В некоторых странах (UK, IL) регистрация доменов второго уровня не производится.

          com.il - не существует
          Домен .co: легитимную почту из Колумбии жена не получает.
          Это же относится и к .biz. Никогда еще не была получен легитимный email из домена .biz ни мной ни женой.

          Этот список означает: "я получаю легитимную почту только из com, net, org, gov, Израиля, России, Украины, Канады, Чехии, Германии (точнее, из их национальных доменов). Из остальных доменов - на 99.9% спам. Стирать бесследно эту почту не надо, но ей место в Корзине".

          В случае с аккаунтом жены - это на 100% верно. Письма из другиг доменов сразу идут в Корзину. Есть минимальный риск потерять сообщение при заказе гостиницы, например, в Англии с доменом .uk. Поэтому в коде есть возможность отключить этот фильтр или добавить домен .uk.

          В реальности, гостиницы заказываю я, поэтому эта проблема не существует. Тем не менее, перед поездкаму за границу я иногда отключаю этот фильтр в аккаунте жены или добавляю в него соотвествующие домены.

          Какие еще есть варианы отсеивать спам из национальных доменов на национальных языках и спамовых доменов типа xyz, biz, info?

          Наверное, если будет много false positives из-за этого списка, но его продется заменить на стоп-лист или серьезно обновить. Но пока все работает, как надо.

          В случае с моим аккаунтом это не верно, я реально получаю легитимную почту из других доменов (домен .co используется некоторыми компаниями как замена com, иногда идут письма из .dev, .me, .ai). Поэтому, этот белый список существует, но он срабатывает только для тех писем, которые уже определены как спам при очистке Спам фолдера.

          В вашем случае этот спсок может быть совсем другим (например, включать национальные домены стран СНГ) или вообще быть отключен, еслиу для вас спам из "нестандартных" доменов не проблема.

          Ну это примерно как на телефоне включить "принимать звонки только от контактов".

          На телефоне моей мамы и тестя так и сделано. На самом телефоне и на Whatsapp.
          Мошенники не дремлют.

          Но с телефоном это более рисковано, понятно, что всегда будут легитимные звонки от неконтактов. А белый список жены покрывает практически 100% ее обычных (не спам) писем. Ну не было у нее за последние пару лет ни одного легитимного письма из других доменов.


  1. akakoychenko
    24.05.2026 06:03

    Кажется, не стоило доверять клоду KNOWN_GOOD_DOMAINS составлять


    1. Kiborg777 Автор
      24.05.2026 06:03

      Это как раз моя опечатка (должно быть seznum.cz), Клод такие ошибки не делает. На самом деле, ничего страшного. Это ведь не белый список доменов, а список доменов, на которые не надо спрашивать есть ли DNS records MХ и А. Значит раз в году (мы переписываемся с родственниками из Чехии по мессенджерам, но изредка приходит email) будет лишний запрос.


      1. akakoychenko
        24.05.2026 06:03


  1. alex09102026
    24.05.2026 06:03

    - Openclaw удали весь мусор из почты.
    - Сделано Милорд!
    - Сделай это cron заданием каждые 2 часа.
    - Сделано Милорд!

    удаление спама и подбор свежих значимых новостей в мире (без политики) обходится примерно 1-4 рубля в сутки при использовании модели deepseek v4 flash


    1. Kiborg777 Автор
      24.05.2026 06:03

      Не самый лучший совет. Кто сказал, что он это сделает лучше, чем сам Гугл? Скорее всего, нет. Тогда зачем дублировать действия Гугла с тем же результатом. Как минимум, он удалит из Спама false positives вместе со спамом.

      Отдельный вопрос, насколько я хочу давать доступ AI агентам к моей электронной почте. Точно могу сказать - не хочу. Как минимум, по причинам приватности и безопасности (privacy and security).


  1. Fopusyk
    24.05.2026 06:03

    Неужели кому то эта параша нужна больше чем для регистрации сайтов?


    1. akakoychenko
      24.05.2026 06:03

      Ну, может ещё че-то с визового центра прийти или банка, и жизнь испортить, если не отреагируешь