Pavel SkvortsovPavel Skvortsov
← Назад
03

WP Block - Hot Offers

Блок Gutenberg, подгружающий последние посты из Telegram-канала и отображающий их как горячие предложения

WordPressGutenbergReactTelegram APIPHP

"Менеджер постит прайс в Telegram. Каталог обновляется сам."

CSS
marquee - без JS анимации, чистые keyframes
webhook
Telegram - WordPress REST API - обновление ACF
2%
допуск совпадения хешрейта при поиске слота
4
состояния: обновлено - новый хешрейт - слоты заняты - не найдено
Как это работает
Пост в Telegram-канале
Webhook - /wp-json/ms/v1/tg-webhook
Валидация секрет-токена
Парсинг строк прайса (regex)
Нормализация названий
Совпадение - update_field()
Отчёт обратно в Telegram
Структура проекта
parts/hot-deals.phpзапрос майнеров, оценка по суточному доходу, выбор топ-4, утроение массива для CSS петли
inc/tg-channel.phpобработчик REST webhook, парсер прайса, нормализатор, матчер слотов, отправка отчёта
POST /wp-json/ms/v1/tg-webhookпринимает channel_post от Telegram, валидирует токен, маршрутизирует: прайс vs обычный пост
GET /wp-json/ms/v1/tg-postsвозвращает 5 последних постов канала из transient, fallback - парсинг t.me/s/channel
опция ms2026_pending_pricesхранит несовпавшие строки прайса - новые варианты хешрейта и неизвестные модели
Важная деталь

Когда строка прайса не совпадает - новый вариант хешрейта или товар не в каталоге - она сохраняется в опцию pending_prices для ручной проверки. Менеджер получает подробный Telegram-отчёт: что обновлено, что требует внимания, и у каких товаров цены не обновлялись 14+ дней.

Код
// Определение прайса + парсер строк
  function ms2026_is_price_message(string $text): bool {
      return mb_strpos($text, '🔵') === 0
          && mb_strpos($text, 'в наличии РФ') !== false;
  }
  
  // Каждая строка:  НазваниеМодели 100TH  1500 USDT
  preg_match(
      '/\s*(бу\s+)?(.+?)\s+([\d,\.]+)\s*(Mh|Th|TH|GH|kSol)\s*[-]\s*([\d\s,\.]+)\s*USDT/iu',
      $line, $m
  );
  
  // Нормализация названия для нечёткого совпадения
  function ms2026_normalize_name(string $name): string {
      $name = mb_strtolower(trim($name));
      $name = preg_replace('/^бу\s+/u', '', $name);
      $name = str_replace('+', 'plus', $name);
      foreach (['hydro','pro','mini','home','plus'] as $suffix) {
          $name = preg_replace('/\s*'.$suffix.'\s*/u', ' '.$suffix.' ', $name);
      }
      return trim(preg_replace('/\s+/', ' ', $name));
  }
  
  // Совпадение хешрейта с допуском 2% по слотам H1H4
  for ($i = 1; $i <= 4; $i++) {
      $slot_th = get_field('h'.$i.'_th', $pid);
      $diff = abs((float)$slot_th - $parsed['hashrate']);
      if ($diff <= $parsed['hashrate'] * 0.02) {
          update_field('h'.$i.'_price', $parsed['price'], $pid);
          break;
      }
  }
Функции
  • Карусель Hot Deals: выбирает топ-майнеры по суточному доходу - до 2 с плашкой "Новинка" + топ по ROI
  • Карточки утраиваются в PHP для бесшовной CSS-петли - клонирование через JS не требуется
  • Скорость анимации считается динамически: кол-во карточек - (280px + 24px gap) - 60px/с
  • Пауза при hover через CSS animation-play-state, учитывает prefers-reduced-motion
  • Telegram webhook принимает channel_post через REST API эндпоинт
  • Секрет-токен проверяется через hash_equals() - защита от timing-атак
  • Определение прайса: начинается с 🔵, содержит "в наличии РФ"
  • Regex-парсер извлекает название, хешрейт (TH/GH/kSol/MH нормализуется в TH), цену в USDT
  • Нормализация названий: нижний регистр, убрать "бу", развернуть "+", пробелы перед суффиксами
  • Совпадение слота хешрейта с допуском 2% - находит правильный H1H4 слот товара
  • Несовпавшие цены сохраняются в опцию ms2026_pending_prices для ручной проверки
  • Отчёт отправляется обратно в Telegram: обновлено / новый вариант / слоты заняты / не найдено
  • Fallback: если transient пуст, парсит HTML t.me/s/channel и берёт последние 5 постов