Чат сендер
src/main/senders/chat-sender.ts · src/main/senders/chat-queue.ts
Автоматична розсилка чат-інвайтів. Запускається per-анкета в LadyRunner. Працює у фоні незалежно від дій оператора.
Два треки
| Трек | Кому | Пріоритет |
|---|---|---|
| FAV | Фаворити в whitelist | Вищий |
| NEW | Нові онлайн RU (не фаворити) | Нижчий |
Кожен трек має:
- Свої слоти інвайтів (
chatFAV,chatNEW) - Незалежний флаг помилки (
ERROR_FAV,ERROR_NEW)
Ініціалізація
resetState()— очищення всіх Map і лічильниківgenerateRandomIntervals()— 19 рандомних значень 65–360 сек (окремий інтервал на кожен слот інвайту; захист від патернів які міг би виявити сервер)- Завантажити
chatFAVіchatNEWзі стану сендера (pinned invite IDs) - Завантажити тексти інвайтів →
invites: Map<id, text> initSenderHistory()— заповнюєhistoryFAV,historyNEW,total:total— лічильник FAV/NEW/USER відправок per RUhistory— коли і який інвайт відправлявся кожному RU
- Надіслати початковий прогрес у renderer
Умови запуску send()
isOk()
&& chatQueue.isReady()
&& (!ERROR_FAV || !ERROR_NEW) ← хоча б один трек без помилки
&& socketConnected
&& isNormalTime() ← не 13:00–13:05 (тех. обмеження платформи)
&& isInitialized
&& !isBusy
isBusy = true на час відправки — захист від паралельних викликів.
Логіка відбору кандидата — 6 логік за пріоритетом
getCandidate(). Перша логіка, що дала кандидата — використовується. FAV завжди має пріоритет над NEW.
Логіка 1 — Previous FAV (повторна відправка фавориту)
- RU онлайн + у whitelist
- Не в minuteStop / temporaryStop
- Є наступний інвайт якого ще не отримував
- Пройшов рандомний інтервал (65–360 сек per слот)
Логіка 2 — Next FAV (новий фаворит)
- RU у whitelist + онлайн
- Не в
historyFAV(не контактували сьогодні) contactDetails.status !== Yes— RU не поділився контактами (інакше зайвий)- Не
blockedByTU - Не в stop-листах
id !== 1(системний юзер)
Обирається рандомно з усіх підходящих.
Логіка 3 — Again Previous FAV (повтор через 3+ год)
- RU онлайн + whitelist
- Всі інвайти вже відправлені
- З моменту останнього інвайту пройшло 3+ години
- Пройшов рандомний інтервал
Логіка 4 — Previous NEW (повторна для онлайн-незнайомця)
- RU онлайн
- Не став фаворитом
- Є наступний інвайт
- Пройшов рандомний інтервал
Логіка 5 — Next NEW (новий онлайн)
- RU онлайн
- Не в
historyNEW - Не у whitelist
- Не фаворит
- Якщо
lady.findNew = false— тільки зagencyService.actualAgencyStore - Якщо
lady.findNew = true— будь-який онлайн
Обирається рандомно.
Логіка 6 — Again Previous NEW (повтор через 1+ год)
Аналог Логіки 3 але для NEW-треку.
FAV = 3 години, NEW = 1 година. NEW-контакти менш теплі, тому коротший цикл.
Stop-листи
| Список | Час | Коли додається |
|---|---|---|
minuteStop | 1 хв | Сервер повернув rate-limit / будь-яка невдала відправка |
temporaryStop | 30 хв | RU написав першим або специфічна помилка |
Обидва перевіряються перед відбором кандидата.
Особливість temporaryStop
- Якщо RU у whitelist → видаляється з whitelist через API,
isWhite = falseу фаворитах - Якщо не у whitelist → додається в
temporaryStopна 30 хвилин
Помилки
Не зупиняють сендер (додають у minuteStop)
| Текст помилки з серверу | Дія |
|---|---|
"You can send a second message after 1 minute." | minuteStop |
"You send messages too often" | minuteStop |
"user is offline" | minuteStop |
CHAT_ERROR_MESSAGE | ігнорується (помилка черги) |
Зупиняють трек (ERROR_FAV / ERROR_NEW)
Будь-яка інша помилка → виставляє флаг з текстом. Сендер більше не пробує по цьому треку, поки флаг не скинеться (оновленням інвайтів або вручну).
Критично: 5+ помилок підряд → зупинка анкети
errorCounter >= 5 → ladyRunner.stop() → operatorRunner.favoriteService.sendToFrontend()
Якщо сендер масово падає — щось системно зламано. Безпечніше зупинити анкету повністю.
Зв’язки
- Черга: ChatQueue
- Сокет: StackSocket
- Whitelist: WhiteListService
- Фаворити: FavoriteService
- Інвайти (сутність): ChatInvites
- UI керування: Sender screen
- Сутність чату: Chat