Главное правило : каждое исходящее сообщение от бота должно быть ответом на входящее в последние 24 часа. Иначе — нужен MESSAGE_TAG с одной из утверждённых причин, и Meta его очень не любит на объёме. Rate limit : 200 calls/hour на page, реально — ставить bucket на 180. Voice messages приходят как audio-attachment, нужен STT pipeline. Бан-триггеры : одинаковые ответы >5 пользователям подряд, исходящий без входящего, чужие phone numbers в тексте.
Самая дорогая ошибка в IG-агенте : думать что у вас «бот, который пишет клиентам». На самом деле : бот, который имеет право ответить в течение 24 часов на входящее. После 24 часов окно закрывается, и ваше «привет, мы вам не дозвонились» вернёт (#10) Application does not have permission for this action. На объёме — страйк к аккаунту.
24-часовое окно — главное
Что разрешено внутри 24h :
- Любые ответы, включая promotional.
- Quick replies, media, voice notes от бота.
- Передача на живого оператора через
handover_protocol.
Что разрешено после 24h только с MESSAGE_TAG :
HUMAN_AGENT: ответ от живого человека в течение 7 дней. Самый частый кейс. Требует чтобы агент был верифицирован как human в Business Manager.ACCOUNT_UPDATE: обновление статуса заказа, бронирования, доставки. Жёстко контролируется — Meta делает sampling и банит если шлёшь маркетинг под этим тегом.
В production : храним timestamp последнего входящего сообщения от каждого user_id. Перед отправкой — проверка now - last_inbound < 23h 30min (полчаса буфера на clock skew). Если нет — очередь, ждём пока пользователь напишет, или эскалируем на оператора.
Rate limits Graph API
Документация Meta заявляет 200 calls/hour на page. Реальный лимит на нашем потоке :
- Bursts до 15 calls/sec Meta терпит, дальше — 30 сек throttle и
(#4) Application request limit reached. - 200 calls/hour — номинал, но на 188-й Meta начинает возвращать 429 sporadically. Безопасный потолок : 180.
- Voice send — отдельный bucket, ~60/hour. Стримить голос всем подряд не вариант.
Архитектура : один Redis-counter на page, sliding window 60 минут. Когда занято >160 — приоритезация : сначала отвечаем на входящие <30 мин назад, потом всё остальное. Outbound-кампании ставим в отдельную очередь с throttle 50/hour.
Voice messages : что делать
~18% входящих в наших IG-проектах — voice notes. Игнорировать нельзя — конверсия падает в два раза, потому что человек ждал ответа и не получил.
Pipeline :
- Webhook приходит с
message.attachments[0].type=audioи URL. - Качаем файл (URL живёт 60 минут, потом 404). MP4-audio container, ~AAC inside.
- STT : для UA — Whisper-large-v3 (self-hosted) или Deepgram nova-2 (UA support не идеальный, но живёт). p95 на 30-сек войсе : 1.4 сек (self-hosted L4) или 800 мс (Deepgram).
- Transcript идёт в LLM как обычный текст user message, с префиксом
[voice]: ...чтобы LLM знал контекст.
Тонкость : войс может прийти из шумного места и Whisper галлюцинирует фразами на других языках. Ставим language=uk жёстко и добавляем фильтр : если confidence <0.7 — отвечаем «не розчув повністю, продублюйте, будь ласка, текстом» вместо угадайки.
IG-агент под ваш sales-процесс
Полная архитектура, prod-ready. Webhook → DM-handler → LLM → CRM. Первый рабочий build — за 3 недели.
За что банят молча
Meta не шлёт письмо «вас забанили». Просто : webhook-и перестают приходить, отправка возвращает (#200) Permissions error, page disappears из Business Manager. Восстановление — через апелляцию, 2–6 недель.
Что точно триггерит бан на объёме :
- Одинаковые ответы >5 разным юзерам подряд. Spam-классификатор. Если бот шлёт «дякую за звернення, наш менеджер з вами зв'яжеться» — добавляем variation (3–5 шаблонов в ротации) или генерируем через LLM с
temperature=0.8. - Outbound без входящего в истории. Если в БД нет ни одного inbound от user_id за всё время — нельзя писать. Точка. Даже с
MESSAGE_TAG. - Phone numbers и ссылки на Telegram в тексте. «Передаю вас на Telegram оператора @manager» — страйк. Лучше : сначала собрать у клиента телефон в DM, потом async-уведомить оператора через свою систему.
- Слишком быстрые ответы. Меньше 600 мс между inbound и outbound — spam-сигнал. Ставим минимум 1.2 сек random delay перед отправкой, даже если LLM ответил за 400 мс.
Наш production-стек
- Webhook receiver : Next.js API route, Vercel или self-hosted. Verify signature по
X-Hub-Signature-256. - Очередь : BullMQ (Redis) для rate-limiting и retry. Один воркер на тип задачи (inbound, outbound, voice-STT).
- LLM : Claude Sonnet 4 для диалога, GPT-4o-mini для intent-классификации (дешевле в 3×, на intent точность сопоставима).
- STT : Whisper-large-v3 self-hosted (UA-проекты, приватность) или Deepgram (когда latency критична).
- CRM : KeyCRM webhook на каждое новое сообщение + создание deal на первом intent «продажа».
- Monitoring : Sentry для exceptions, Grafana dashboard с двумя метриками — calls/hour vs limit и p95 ответа inbound→outbound.
7 месяцев на 3 IG-аккаунтах : 0 банов, 1 страйк (recovered через Business Help в 3 дня). 200–400 диалогов/день/аккаунт, ~12 000 минут voice transcribed.