Как WhatsApp вычисляет рассылку через Baileys и whatsapp-web.js
AndySendy academy
← Все посты

🔗 Не WebSocket вас выдаёт. Выдаёт то, что вокруг него

«Library воспроизводит протокол напрямую - WhatsApp не отличит её от настоящего клиента» - удобное допущение, которое разваливается при первом серьёзном разборе. Baileys и whatsapp-web.js действительно работают без браузера и телефона, но это не значит, что они невидимы. Разберём, что в детекте подтверждено, а что - реконструкция сообщества разработчиков.


Почему путаница вокруг темы такая стойкая

Исходный тезис называет два конкретных фактора: поведение и версию протокола. Поведенческий слой подтверждён добротно - это задокументированная практика индустрии. А вот версионирование протокола как механизм детекта официально нигде не подтверждено - это правдоподобная техническая гипотеза, не факт из документации Meta. Параллель на веб-стороне - расширения и isTrusted: браузер даёт сигнал, использование WhatsApp - гипотеза.


Было / Стало: что нужно поправить в исходном тезисе

Было:

Ловят по двум факторам: поведение (скорость отправки без пауз, отсутствие статуса «печатает») и версия протокола (несовпадение версий фиксируется).

Стало:

Подтверждённый и хорошо задокументированный риск - поведенческие сигналы: скорость отправки, идеально ровные интервалы, массовая рассылка одинаковых сообщений. Версия протокола как отдельный, специально проверяемый фактор детекта официально не подтверждена - это техническая гипотеза сообщества, основанная на том, что reverse-engineered библиотеки объективно отстают от обновлений Meta и поэтому статистически чаще ломаются или банятся.

Было:

Отсутствие статуса «печатает» перед сообщением - один из двух главных факторов детекта.

Стало:

Отсутствие presence-событий (composing, paused) - это правдоподобный поведенческий маркер, который активно обсуждается практиками. Но прямого подтверждения, что Meta специально проверяет наличие этого конкретного события перед каждым сообщением, нет - подтверждена только более широкая категория: неестественно идеальные тайминги вообще - см. поведенческий антиспам.


Baileys и whatsapp-web.js - разная архитектура, разные риски

Параметр Baileys whatsapp-web.js
Принцип работы Reverse-engineered WebSocket-клиент, без браузера [✓] Управляет реальным WhatsApp Web через Puppeteer/Chromium [✓]
Основной слой риска Сетевой протокол + поведение Браузерные фингерпринты + поведение
Маркеры автоматизации Структура Protobuf-пакетов, TLS-отпечаток navigator.webdriver = true, аномалии Canvas/WebGL, isTrusted = false
Presence-события (typing/paused) Доступны через sendPresenceUpdate(), требуют ручной реализации [✓] Управляются через эмуляцию реального интерфейса

Важный нюанс: ни один из двух подходов не безопаснее другого по умолчанию. Headless-браузер не «выглядит легитимнее» только потому, что физически открывает Chromium - headless-режим без графического окружения сам генерирует десятки технических признаков автоматизации.


Что подтверждено официально и широко


Мини-кейс: 4 номера за 20 минут на whatsapp-web.js

Маркетолог развернул скрипт на whatsapp-web.js в Docker-контейнере на Ubuntu-сервере для рассылки по тёплой базе. Несмотря на качество базы, 4 номера улетели в бан за 20 минут. В логах команда зафиксировала, что Chromium внутри контейнера выдавал navigator.webdriver = true и не генерировал событий движения курсора.

Что доказывает кейс: браузерная автоматизация на сервере без графического окружения создаёт заметные технические аномалии - это наблюдаемый факт самой команды. Чего кейс не доказывает: что именно webdriver-флаг стал единственной причиной бана, а не сочетание этого флага со скоростью рассылки или другими сигналами одновременно. Это форумное наблюдение, не препарированный алгоритм Meta.

Второй кейс показывает обратную сторону: B2B-компания на Baileys принудительно добавила в код отправку sendPresenceUpdate('composing') перед каждым сообщением с паузой из расчёта 50 мс на символ. Это снизило частоту автоматических банов и позволило довести объём отправки до 150 сообщений в сутки на прогретом номере. Это говорит о корреляции улучшения с добавлением presence-логики, но не доказывает её как единственный решающий фактор - могла сыграть роль и сама пауза перед отправкой, независимо от presence-статуса.


Спор сообщества: stealth-плагины против сетевого отпечатка

Среди JS-разработчиков есть разногласие. Часть утверждает, что puppeteer-extra-plugin-stealth решает проблему детекции whatsapp-web.js, маскируя webdriver и подменяя Canvas/Codecs. Другие возражают: антиспам Meta может оценивать не отдельные браузерные переменные, а сетевые тайминги и TCP/IP-отпечаток, поэтому запуск на серверах в дата-центрах всё равно заметен независимо от stealth-настроек браузера.

Подтверждений ни одной из сторон нет - это область реконструкций без проверяемых данных от Meta, как в серых схемах инфраструктуры.


Цифры, которые называет практика автоматизации

Официальной статистики Meta по проценту банов Node.js библиотек не существует. Из практических источников по поведенческим лимитам:

Последние три блока цифр - форумные наблюдения, не подтверждённые Meta пороги.


Дополнительный риск: вредоносные форки

Здесь стоит сделать паузу отдельно от темы детекта. В экосистеме npm зафиксированы случаи вредоносных пакетов, маскирующихся под Baileys: один из форков незаметно похищал переписки, контакты и токены сессии. Это не про антибан, а про прямую компрометацию аккаунта - практическая причина проверять происхождение библиотеки и список связанных устройств в самом WhatsApp.


Частые заблуждения

«Раз протокол официальный, Meta считает библиотеку легитимным клиентом» Неверно. Протокол используется неофициально через реверс-инжиниринг - это прямо запрещено условиями обслуживания независимо от технической точности воспроизведения.

«whatsapp-web.js безопаснее, потому что физически открывает браузер» Неверно. Headless Chromium без графического окружения генерирует собственный набор фингерпринтов автоматизации - это не менее заметно, чем прямой WebSocket.

«Если QR-код отсканирован успешно, аккаунт уже в безопасности» Неверно. Авторизация проверяет только валидность ключей шифрования - поведенческий и сетевой анализ продолжается непрерывно после открытия сессии.

«Stealth-плагин полностью решает проблему детекции» Не подтверждено. Плагин закрывает часть браузерных переменных, но не обязательно сетевые тайминги или TCP/IP-отпечаток сервера.


Практические выводы


🎯 Следующий шаг

Если рассылка на Baileys или whatsapp-web.js уже падает, сначала проверьте поведенческий профиль - скорость и регулярность интервалов - это самый задокументированный фактор риска. Версию библиотеки стоит держать актуальной не потому, что несовпадение «детектируется», а потому что устаревший протокол объективно увеличивает шанс некорректной работы сессии.

Вывод

Практическое правило:

Библиотека без браузера не значит библиотека без следов - следы просто переезжают на другой уровень.