PostChatMailTaskRunner
src/chathouse/components/tasks/post-chat-mail-task.runner.ts
Observer на [[services/chathouse/services/operator-runner]]. Після чат-переписки з RU — якщо TU ще не написала mail додатково — створює mail-таск для оператора.
Таймери
| Момент | Затримка | Умова |
|---|---|---|
Перша перевірка після старту OperatorRunner | 10 сек | ≤ 10 анкет у оператора |
Перша перевірка після старту OperatorRunner | 30 сек | > 10 анкет (розподіл навантаження) |
| Кожна наступна перевірка | 60 сек після попередньої | Завжди, незалежно від результату |
Таймер рекурсивний (setTimeout): наступний запуск планується після завершення поточного calculate().
Додаткова затримка всередині циклу: статистика враховується тільки якщо від події минуло більше 10 хвилин (POST_CHAT_MAIL_MS). Свіжіші події — ігноруються.
Обмеження
- Немає глобального ліміту тасків на оператора — але таск не створюється якщо по парі TU+RU вже є активний
UnansweredMailTask,UnansweredMessageTaskабоNeedToWriteMailTask. - Тільки діалоги з доступними mail-лімітами (
favoriteDialogsWithMailLimits). Якщо ліміти вичерпані — діалог кешується в Redis на 10 хв і пропускається. - Тільки платна активність RU (
isFree: false). Безкоштовні дії не враховуються. - Якщо TU вже надіслала mail після останнього RU-повідомлення в чаті — таск не створюється, стат додається в
closedTasks.
Ініціалізація при старті
- Будуються lookup-мапи між DB ID, API ID і ULID кожної TU оператора.
- З БД завантажуються вже оброблені таски за останні 2 місяці → заповнюється
closedTasks(Set рядкових ключів). - Перша перевірка запускається із затримкою (див. таблицю вище).
Цикл перевірки (кожні 60 сек)
-
Отримання діалогів. З
OperatorRunnerотримуються активні favorite-діалоги з mail-лімітами (getAllFavoriteMailDialogs). -
Свіжа статистика. З тимчасової таблиці завантажуються записи чат-активності RU (sum > 0,
isFree: false, тільки для manUlid-ів з цих діалогів, тільки для TU оператора).Типи активності що відстежуються:
text_message_send,photo_message_send,video_message_send,audio_message_send,sticker_message_send,send_gift,present_send,watch_private_video,profile_erotic_photo,profile_private_photo,profile_private_library_video,profile_private_library_photo. -
Дедуплікація. Для кожної пари TU+RU залишається тільки найновіший запис.
-
Перевірка надісланих mail. Завантажуються сьогоднішні inmail-відправки оператора. Якщо TU вже надіслала mail після дати статистики — стат додається в
closedTasks(відповідь вже є). -
Фільтрація по
closedTasks. Кожен стат-запис перетворюється на ключladyDbId_manUlid_dateWithTime. Вже закриті — пропускаються. -
Створення тасків. Записи групуються по
ladyDbId. Для кожного стату в рамках TU:- Знаходиться діалог по парі TU+RU.
- Якщо від події минуло менше 10 хвилин → пропустити.
- Якщо є активний
UnansweredMailTask,UnansweredMessageTaskабоNeedToWriteMailTaskпо цій парі → пропустити. - Якщо діалог позначений як “forgotten” в Redis → пропустити (ліміти кешовані).
- API-запит: отримати повідомлення діалогу, перевірити чи є доступні mail-ліміти. Якщо ні — закешувати в Redis на 10 хв, пропустити.
- Створити таск типу
NeedToWriteMailTaskз модулемpostChatMailчерезTaskFactory. - Зберегти в БД і додати до стору оператора.
Кеш оброблених подій (closedTasks)
In-memory Set. Дві схеми ключів:
| Ключ | Коли додається |
|---|---|
ladyDbId_manUlid_eventTriggerTask | Коли таск закрито оператором (pushToCacheTaskAnswered) |
ladyDbId_manUlid_dateWithTime | Після створення таску або виявлення що TU вже відповіла (pushToCacheStatistics) |
При старті відновлюється з БД (таски за 2 місяці). Redis-кеш для “без лімітів” (checkPostChatMailDialog) — окремий, не входить в closedTasks.