Sender

src/chathouse/components/sender/ · Swagger → Sender

HTTP-контракт (маршрути, параметри, відповіді) — у Swagger. Тут тільки бізнес-логіка і нюанси.

Сховища

КолекціяЩо зберігає
chathouse_sender_messagesПовідомлення для TU (масиви chat[] і mail[] + sendingErrors[])
chathouse_sender_lady_historyІсторія відправлених повідомлень TU↔RU (sendedMessages[])

Flow 1 — Конфігурація повідомлень (UI)

Хто тригерить: supervisor або top manager у UI → SenderControllerSenderService (Swagger → Sender)

Створення основного повідомлення

Supervisor створює chat або mail шаблон для TU. При збереженні:

  • очищується кеш “не вистачає повідомлень” для цієї TU — SenderRunner одразу почне відправляти
  • чиститься кеш усіх текстів для логіки плагіату (senderMessages(type))
  • якщо в TU раніше були зафіксовані помилки відправки цього типу — вони знімаються

Обмеження при створенні:

  • Текст не може містити кирилицю
  • Mail-повідомлення з прикріпленими фото не можна позначити як “для low credit”

Додаткові повідомлення (тільки chat)

До chat-шаблону можна додати до 2 додаткових повідомлень (текст, стікер або фото). Кожне має власну затримку (timerMs) — відлік від відправки попереднього.

  • Після збереження текстового додаткового повідомлення чиститься кеш текстів.
  • Стікер і фото кеш не перевіряються на плагіат.

Позначення mail як “для low credit”

assignMailSenderForLowCredit — можна встановити або зняти прапор на вже існуючому mail-повідомленні. Шаблон з фото позначити “для low credit” не можна.

Зміна порядку та видалення

  • Порядок повідомлень впливає на порядок відправки в SenderRunner — наступним відправляється перше невідправлене повідомлення за списком.
  • При видаленні chat видаляються і всі його додаткові повідомлення.
  • При видаленні конкретного додаткового повідомлення основний шаблон залишається.
  • Після видалення чиститься кеш текстів для відповідного типу.

Перевірка плагіату тексту

getAllMessageTexts повертає усі унікальні тексти шаблонів певного типу по всіх TU системи. Використовується UI для підказки/перевірки чи текст вже використовується. Результат кешується в Redis і очищується при будь-якій зміні шаблонів.


Відображення червоного статусу (UI)

Хто тригерить: UI при відкритті сторінки (Swagger → Sender)

Supervisor TOP отримує інформацію чи є зафіксовані помилки відправки по chat mail. Якщо є помилка - TU має фарбуватись в червоний колір.


Flow 2 — Робота сендера в фоновому режимі (SenderRunner)

SenderRunner — observer на LadyRunner, що відправляє chat і mail повідомлення від TU до RU у фоновому режимі.

Де запускається:

  • OnlineTask — після опрацювання онлайн-діалогів; відбираються діалоги з лімітами, останнє повідомлення від TU, не фаворит діалоги.

Алгоритм для кожного діалогу

Всі діалоги обробляються паралельно (Promise.allSettled). Для кожного:

  1. Якщо в Redis є флаг “вже слали” для цієї пари TU↔RU — пропускаємо. Флаг живе 1 годину після відправки chat.
  2. Перевірка шаблонів — якщо у TU немає жодного chat або mail повідомлення — позначаємо в кеші “не вистачає повідомлень” і пропускаємо.
  3. Відбір повідомлення — вибирається наступне повідомлення якого ще не надсилали цьому RU (ротація по порядку, відносно історії відправок).
  4. Пріоритет chat → mail:
    • Спочатку відправляємо chat (якщо є ліміт і є повідомлення).
    • Mail надсилається тільки якщо chat вже відправлено або ліміту чи повідомлення для chat немає.
  5. Mail і кредити RUCredits у RU-діалозі:
    • 20+ кредитів — звичайний відбір mail по черзі.
    • 0–20 кредитів — тільки повідомлення з позначкою “для low credit”. Якщо таких немає або всі вже надіслані — mail не відправляємо.
  6. Чорний список — безпосередньо перед відправкою перевіряємо чи RU не в чорному списку TU. Якщо так — встановлюємо довший cooldown і пропускаємо без відправки.

Cooldown після відправки:

ТипЗатримка між повідомленнями
Chat1 година
Mail6 годин

Додаткові повідомлення

Chat-повідомлення може мати до 2 додаткових повідомлень (текст / стікер / фото), які відправляються з затримкою після основного.

Постановка в чергу (при відправці основного повідомлення):

  • Стікер — не ставиться в чергу, якщо у RU немає ліміту на стікери.
  • Фото — не ставиться в чергу, якщо RU має менше 20 кредитів.

Безпосередньо перед відправкою (по спрацюванню таймера):

  • Верифікується що останнє повідомлення в діалозі відповідає очікуваному попередньому (текст збігається, стікер/фото за URL). Якщо ні — відправку цього додаткового повідомлення скасовуємо.
  • Для фото — кредити RU перевіряються повторно (могли змінитися за час очікування).

Наслідок: RU з низькими кредитами не отримують ні mail з фото, ні додаткові фото-повідомлення.


Нюанси

  • Якщо у TU вичерпались повідомлення певного типу (chat або mail), це фіксується як помилка в БД один раз — щоб supervisor міг побачити в статусі при відображенні списків senders.
  • Low credit mail-шаблон не може мати прикріплені фото — заборона на рівні конфігурації шаблону.
  • На локальному середовищі (NODE_ENV=computer) сендер не відправляє повідомлення.
  • SenderRunner не є синглтоном — створюється щоразу при запуску таску. stop() скасовує всі заплановані таймери додаткових повідомлень і знімає observer з LadyRunner.