← Все статьи
Кейс

Как агентство из двух человек мониторит DM и упоминания в X для четырёх клиентов — без оплаты за каждое чтение API — UnifyPort

В январе 2026 года небольшое SMM-агентство из двух человек в Лиссабоне вело аккаунты X (Twitter) четырёх клиентов — два e-commerce бренда, SaaS-стартап и сеть местных ресторанов. Задача была простой: отслеживать входящие DM и упоминания на каждом аккаунте, отвечать в течение нескольких часов, эскалировать то, что требует участия клиента. Техническая реализация тоже была несложной: сервис на Node.js опрашивал API X каждые 30 секунд по каждому аккаунту, проверяя новые сообщения, и перенаправлял их в общий Slack-канал для сортировки.

При старой тарификации X — фиксированные месячные планы, действовавшие с 2023 года — эта конфигурация обходилась в $100/мес на тарифе Basic. Предсказуемо, удобно для бюджета, полностью покрывалось ретейнером клиентов без необходимости объяснять отдельную строку расходов.

А потом наступил февраль.

Счётчик включился

3 февраля 2026 года X заменил фиксированные тарифы на оплату за каждый вызов. Каждое обращение к API — чтение и запись — получило свою цену за запрос. Месячного потолка больше не было. Архитектура опроса, рассчитанная на мир с безлимитными вызовами внутри тарифа, в одночасье начала крутить счётчик.

Арифметика нехитрая. Четыре клиентских аккаунта, каждый опрашивается раз в 30 секунд на предмет DM и упоминаний. Это 8 чтений в минуту (2 эндпоинта на аккаунт × 4 аккаунта), 11 520 чтений в сутки, примерно 345 600 чтений в месяц — и это только мониторинг, ни одного полученного сообщения.

20 апреля X пересмотрел тарифы: чтение собственных ресурсов снизилось до $0,001 за вызов — месячные расходы на мониторинг упали примерно до $346. Но тот же пересмотр поднял стоимость записи (ответы) с $0,010 до $0,015. Агентство отправляло 400–600 ответов в месяц по всем четырём аккаунтам; по $0,015 — дополнительные $6–$9. Само по себе немного, но тренд настораживал: каждый новый клиентский аккаунт — ещё один цикл опроса, каждый дополнительный ответ — давление на счёт с обеих сторон.

Дорого стоит не тариф, а архитектура

Основатель агентства прикинул расходы на гипотетический Q3: при подключении ещё двух клиентов (вполне реальный сценарий по текущей воронке) чтения только от опроса примерно удвоились бы. Цена за отдельный вызов действительно низкая, но объём — структурный: он определяется частотой проверки, а не количеством реально поступивших сообщений. В тихое воскресенье без единого DM цикл опроса работает ровно с той же скоростью и стоит ровно столько же, сколько в день запуска продукта.

Именно эту деталь модели X «оплата за вызов» не показывают обзоры тарифов: стоимость ожидания сообщений не равна нулю, и она масштабируется вместе с архитектурой мониторинга, а не с реальным объёмом входящих. Четыре аккаунта с опросом каждые 30 секунд — это 345 600 чтений в месяц, независимо от того, пришло 10 сообщений или 10 000.

Замедление интервала опроса — очевидное решение. Агентство попробовало 2-минутный интервал в течение недели. Время отклика заметно ухудшилось: DM мог оставаться непрочитанным до 4 минут в худшем случае, а два клиента прописали в контракте SLA «ответ в течение 2 часов». Формально SLA не нарушался, но ощущение от сервиса сменилось с «почти в реальном времени» на «когда-нибудь увидим». Через три дня вернулись к прежнему интервалу.

С pull на push

Правильное решение было не в оптимизации опроса, а в его устранении. Агентство подключило все четыре клиентских аккаунта X к UnifyPort — DM и упоминания стали приходить в webhook в момент поступления. Никакого цикла опроса, никакой оплаты за чтение, никаких расходов, растущих с частотой проверки.

Изменение архитектуры выглядело так:

До (опрос):
  Сервис ──► X API (чтение DM)       ×4 аккаунта ×2/мин = 345 600 чтений/мес
  Сервис ──► X API (чтение упоминаний) ×4 аккаунта ×2/мин = 345 600 чтений/мес
  Итого: ~691 200 тарифицируемых API-чтений/мес

После (webhook push):
  X аккаунт ──► UnifyPort ──► POST /webhook ──► Slack  (клиент A)
  X аккаунт ──► UnifyPort ──► POST /webhook ──► Slack  (клиент B)
  X аккаунт ──► UnifyPort ──► POST /webhook ──► Slack  (клиент C)
  X аккаунт ──► UnifyPort ──► POST /webhook ──► Slack  (клиент D)
  Итого: 0 чтений X API

Входящие сообщения каждого аккаунта доставляются как событие message.received — в том же нормализованном формате, который агентство получит, если позже подключит для тех же клиентов WhatsApp или Telegram:

{
  "event": "message.received",
  "account_id": "acct_client_a",
  "provider": "twitter",
  "from": "user_7d2e1f",
  "text": "Hey, is the summer sale still on? Saw a post but the link was broken",
  "timestamp": 1750320000,
  "message_id": "x_msg_8a3b2c"
}

Обработчик webhook верифицирует каждую доставку с помощью HMAC-SHA256, затем маршрутизирует по account_id в нужный Slack-канал клиента:

app.post("/webhook", (req, res) => {
  if (!verifySignature(req)) return res.sendStatus(401);

  const evt = req.body;
  if (evt.event === "message.received") {
    const channel = clientChannelMap[evt.account_id];
    slack.postMessage(channel, {
      text: `[${evt.provider}] ${evt.from}: ${evt.text}`,
      metadata: { messageId: evt.message_id },
    });
  }
  res.sendStatus(200);
});

Четыре аккаунта, один эндпоинт, один ключ подписи. Сервис опроса выключен полностью.

Что изменилось

Расходы агентства на X API снизились с ~$350/мес (с тенденцией к росту при каждом новом клиенте) до нуля тарифицируемых чтений. Задержка ответа даже улучшилась — события приходят в течение секунд после отправки сообщения, а не в ожидании следующего цикла опроса. Подключение нового клиентского аккаунта — это теперь не добавление цикла опроса в счёт, а одна новая строка в clientChannelMap.

Команда из двух человек по-прежнему отвечает на DM и упоминания в X тем же способом — из Slack, через эндпоинт ответов UnifyPort. Изменилось то, что «мониторинг четырёх аккаунтов X» больше не является статьёй расходов на API, которую нужно моделировать, объяснять клиентам и переживать о масштабировании. Если в Q3 воронка принесёт ещё два аккаунта, webhook будет получать шесть вместо четырёх. Счёт разницы не увидит.

Для агентств и команд, управляющих несколькими аккаунтами X — особенно тех, у кого расходы на X API масштабируются с частотой опроса, а не с объёмом сообщений — архитектурный вопрос не в том, «какой интервал опроса самый дешёвый». А в том, нужна ли модель pull вообще, когда push-webhook может доставить те же сообщения, не крутя счётчик.