Files
core/Техническое задание №4 Модуль публикации по расписанию.md
2026-02-22 16:43:55 +00:00

7.7 KiB
Raw Permalink Blame History

Техническое задание №4: Модуль публикации по расписанию

Цель: Реализовать автоматизированный механизм, который будет публиковать согласованный контент в социальные сети в точно запланированное время. Также необходимо предоставить возможность ручной, принудительной публикации для экстренных случаев.


1. Интеграция с API социальных сетей

Необходимо создать сервисы-клиенты для взаимодействия с API каждого поддерживаемого канала.

TelegramApiClient.java

  • Задача: Инкапсулировать логику отправки сообщений в Telegram.
  • Методы:
    • TelegramPostResponse postMessage(String apiToken, String chatId, String text, String imagePath): Принимает токен, ID чата и контент, отправляет пост в Telegram. Возвращает объект с externalId и url опубликованного поста.
  • Реализация: Использовать библиотеку, например, java-telegram-bot-api, или прямые HTTP-запросы к Telegram Bot API.

(По аналогии создаются клиенты для других соцсетей, например, VkApiClient.java)


2. Сервисный слой (Business Logic)

PublishingService.java

Основной сервис, управляющий процессом публикации.

  • Зависимости: ContentQueueRepository, MessageRepository, ChannelRepository, а также все созданные API-клиенты (TelegramApiClient и др.).
  • Ключевые методы:
    • void findAndPublishScheduledContent(): Основной метод, запускаемый по расписанию.
    • void publishContentById(UUID contentId): Метод для принудительной публикации по ID.

2.1. Логика автоматической публикации (findAndPublishScheduledContent)

Этот метод должен быть аннотирован @Scheduled для регулярного запуска (например, каждую минуту).

  • Алгоритм работы:
    1. Найти в ContentQueueRepository все записи, у которых:
      • status равен ContentStatus.APPROVED.
      • scheduledAt меньше или равен текущему времени (ZonedDateTime.now()).
    2. Для каждой найденной записи (ContentQueue):
      • Получить связанный с ней канал (Channel) и его токен (apiKeyRef).
      • Получить текст и ассеты из полей postDraft и assetsRefs.
      • Вызвать соответствующий API-клиент (например, telegramApiClient.postMessage(...)).
      • В случае успеха:
        • Создать новую запись в таблице Message, сохранив externalId и url из ответа API.
        • Обновить статус записи в ContentQueue на PUBLISHED.
      • В случае ошибки:
        • Обновить статус записи в ContentQueue на FAILED.
        • Записать детальную информацию об ошибке в логи.

2.2. Логика ручной публикации (publishContentById)

  • Алгоритм работы:
    1. Найти запись в ContentQueue по contentId. Если не найдена — ошибка ResourceNotFoundException.
    2. Выполнить ту же логику публикации, что и в шаге 2.1, но для одной конкретной записи.
    3. Этот метод не зависит от статуса и времени, он должен публиковать пост немедленно.

3. API Endpoint (REST Controller)

PublishingController.java

Новый контроллер для управления процессом публикации вручную.

  • POST /api/smm/publishing/post/{contentId}
    • Описание: Принудительно опубликовать пост из очереди контента по его ID.
    • Параметры: contentId (UUID) - ID записи из ContentQueue.
    • Успешный ответ (200 OK):
      {
        "success": true,
        "message": "Пост успешно опубликован",
        "data": {
          "messageId": "...", // UUID из таблицы Message
          "externalUrl": "https://t.me/channel/12345"
        }
      }
      
    • Ответ при ошибке (404 Not Found): Если контент с таким contentId не найден.
    • Ответ при ошибке (502 Bad Gateway): Если API соцсети вернуло ошибку при публикации.

4. Конфигурация планировщика

В главном классе приложения или в отдельном конфигурационном классе необходимо включить поддержку планировщика с помощью аннотации @EnableScheduling.

Метод findAndPublishScheduledContent в PublishingService должен быть аннотирован:

@Scheduled(cron = "0 * * * * *") // Запускать каждую минуту
public void findAndPublishScheduledContent() {
    // ... логика ...
}

5. Обработка ошибок и повторные попытки

  • Ошибки API: PublishingService должен корректно обрабатывать исключения от API-клиентов.
  • Повторные попытки (Retry): Рекомендуется добавить механизм повторных попыток для постов со статусом FAILED. Например, можно добавить аннотацию @Retryable (из Spring Retry) на метод отправки в API-клиенте или создать отдельный Scheduled метод, который будет пытаться повторно опубликовать "упавшие" посты несколько раз с интервалом.

Критерии выполнения

  • Созданы API-клиенты для взаимодействия как минимум с одной соцсетью (Telegram).
  • Реализован PublishingService с логикой автоматической и ручной публикации.
  • Метод автоматической публикации успешно запускается по расписанию, находит и публикует согласованный контент.
  • После успешной публикации в таблице Message создается запись, а статус в ContentQueue меняется на PUBLISHED.
  • В случае ошибки публикации статус в ContentQueue меняется на FAILED.
  • Новый эндпоинт POST /api/smm/publishing/post/{contentId} корректно работает и позволяет публиковать посты вручную.
  • Реализована базовая обработка ошибок от API соцсетей.