follow-up-chat

Follow-up Message сервіс

Окремий per-TU сервіс для всіх причин створення FollowUpMessage. Веде Follow-up-ланцюжки, перевіряє умову >60 хв і передає готовий кандидат у Task Factory. Активні таски не тримає.

Стан ланцюжка

У фавориті зберігається:

followUpChat: {
  sourceUnansweredTaskId
  step             // кількість завершених спроб: 0–3
  nextCheckAt      // час наступної спроби
}

Runtime-пул містить усі незавершені ланцюжки конкретної TU, включно з offline RU.

Ініціалізація

  1. Взяти active favorites, Task history і favorite.followUpChat зі стартових даних.
  2. Для кожного favorite знайти останній закритий UnansweredMessage і наступні Follow-up таски цього ланцюжка.
  3. Через task history і marker фаворита визначити поточний step та чи ланцюжок ще не перейшов межу 60 хв від останнього повідомлення TU.
  4. Усі незавершені ланцюжки додати в runtime-пул незалежно від online RU.
  5. Online RU з простроченим nextCheckAt перевірити одразу.
  6. Offline RU залишити в пулі без повторного таймера: перевірка відбудеться, коли він стане online або стан буде стертий новим UnansweredMessage.

Оновлення ланцюжка

  1. Закрито UnansweredMessage — створити новий стан зі step = 0 і випадковим nextCheckAt через 60–180 с.
  2. Настав nextCheckAt, RU online — перевірити умови й шанс поточного кроку: 100%, 75%, 50%.
  3. Шанс випав — передати FollowUpMessage у Task Factory. Наступний крок планується лише після фактичного закриття цього таска.
  4. Шанс не випав — збільшити step і запланувати наступну перевірку через 60–180 с.
  5. RU offline — стан і step не змінювати. Після переходу online прострочена спроба виконується одразу.

Після закриття створеного FollowUpMessage сервіс збільшує step: якщо спроби ще залишились — зберігає новий nextCheckAt, інакше видаляє ланцюжок.

Ручна відправка TU без таска не просуває ланцюжок.

Видалення з пулу

  • новий UnansweredMessage від RU — старий ланцюжок видаляється; після закриття нового таска почнеться новий;
  • block — видалити ланцюжок;
  • favorite перестав бути active або отримав isWhite — видалити ланцюжок;
  • виконано три спроби — видалити ланцюжок;
  • діалог перейшов межу 60 хв — видалити ланцюжок.

Після 60 хв пара без розриву переходить із chain-фази у звичайну перевірку цього самого сервісу. Якщо RU online — умова перевіряється одразу; якщо offline — під час наступної появи в RU Online. Умова: active favorite, останньою писала TU й останній контакт старший за 60 хв. Для Chathouse/Prime також потрібен chat limit; Golden chat limits не має.

Перед Task Factory

Повторно перевірити: active favorite, !isWhite, online, немає block і немає сильнішого chat-таска. Для Chathouse/Prime також потрібен chat limit. Chathouse ONLINE_NOW/RECENT_PURCHASE проходить через цю саму перевірку, але не створює chain-state.

Запити

  • Chathouse / Prime використовують dialog snapshot із RU Online без додаткових запитів.
  • Golden отримує online RU id і точково читає chat history у своїй логіці.

Збереження

Runtime-пул живе в пам’яті сервісу. Кожна зміна favorite.followUpChat одразу оновлюється локально та відправляється на Stack з idempotency key TU+RU+sourceUnansweredTaskId+step. Помилка запису залишається в локальній durable-черзі й повторюється; online/offline у БД не зберігається.