UPDATE fix quick replies

This commit is contained in:
PAVEL PALMA
2025-12-16 19:07:49 -06:00
parent a15af59668
commit 1e7829d433
6 changed files with 720 additions and 17 deletions

View File

@@ -63,6 +63,7 @@ public class ConversationManagerService {
private static final Logger logger = LoggerFactory.getLogger(ConversationManagerService.class);
private static final long SESSION_RESET_THRESHOLD_MINUTES = 30;
private static final long SCREEN_CONTEXT_TIMEOUT_MINUTES = 10; // fix for the quick replies screen
private static final String CONV_HISTORY_PARAM = "conversation_history";
private final ExternalConvRequestMapper externalRequestToDialogflowMapper;
private final DialogflowClientService dialogflowServiceClient;
@@ -123,12 +124,25 @@ public class ConversationManagerService {
externalrequest.pantallaContexto());
return memoryStoreConversationService.getSessionByTelefono(externalrequest.user().telefono())
.flatMap(session -> {
if (session != null && session.pantallaContexto() != null
&& !session.pantallaContexto().isBlank()) {
logger.info(
"Detected 'pantallaContexto' in session. Delegating to QuickRepliesManagerService.");
return quickRepliesManagerService.manageConversation(obfuscatedRequest);
}
boolean isContextStale = false;
if (session.lastModified() != null) {
long minutesSinceLastUpdate = java.time.Duration.between(session.lastModified(), java.time.Instant.now()).toMinutes();
if (minutesSinceLastUpdate > SCREEN_CONTEXT_TIMEOUT_MINUTES) {
isContextStale = true;
}
}
if (session != null && session.pantallaContexto() != null
&& !session.pantallaContexto().isBlank()
&& !isContextStale) {
logger.info("Detected active 'pantallaContexto'. Delegating to QuickRepliesManagerService.");
return quickRepliesManagerService.manageConversation(obfuscatedRequest);
}
// Remove the old QR and continue as normal conversation.
if (isContextStale && session.pantallaContexto() != null) {
logger.info("Detected STALE 'pantallaContexto'. Ignoring and proceeding with normal flow.");
}
return continueManagingConversation(obfuscatedRequest);
})
.switchIfEmpty(continueManagingConversation(obfuscatedRequest));

View File

@@ -22,7 +22,7 @@ import java.util.stream.IntStream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import com.example.dto.dialogflow.conversation.QueryResultDTO;
import com.example.service.conversation.ConversationManagerService;
import org.springframework.context.annotation.Lazy;
import reactor.core.publisher.Mono;
@@ -109,16 +109,36 @@ public class QuickRepliesManagerService {
userMessagesCount = 0;
}
if (userMessagesCount == 0) { // Is the first user message in the Quick-Replies flow
// This is the second message of the flow. Return the full list.
return persistConversationTurn(session, userEntry)
.then(quickReplyContentService.getQuickReplies(session.pantallaContexto()))
.flatMap(quickReplyDTO -> {
ConversationEntryDTO agentEntry = ConversationEntryDTO
.forAgentWithMessage(quickReplyDTO.toString());
return persistConversationTurn(session, agentEntry)
.thenReturn(new DetectIntentResponseDTO(session.sessionId(), null, quickReplyDTO));
});
if (userMessagesCount == 0) {
// El usuario acaba de responder al menú.
// Validamos si lo que escribió coincide con alguna opción del menú.
return quickReplyContentService.getQuickReplies(session.pantallaContexto())
.flatMap(quickReplyDTO -> {
// Verificamos si el texto del usuario coincide con algún título de las preguntas
boolean esOpcionValida = quickReplyDTO.preguntas().stream()
.anyMatch(p -> p.titulo().equalsIgnoreCase(externalRequest.message().trim()));
if (esOpcionValida) {
// Si coincide, guardamos el mensaje y procesamos la respuesta (lógica existente para respuesta automática)
String respuesta = quickReplyDTO.preguntas().stream()
.filter(p -> p.titulo().equalsIgnoreCase(externalRequest.message().trim()))
.findFirst().get().respuesta();
QueryResultDTO queryResult = new QueryResultDTO(respuesta, null);
DetectIntentResponseDTO response = new DetectIntentResponseDTO(session.sessionId(), queryResult, null);
return persistConversationTurn(session, userEntry) // Guardamos el "input" del usuario
.then(memoryStoreConversationService.updateSession(session.withPantallaContexto(null))) // Limpiamos contexto
.then(persistConversationTurn(session, ConversationEntryDTO.forAgentWithMessage(respuesta))) // Guardamos la respuesta
.thenReturn(response);
} else {
// Si el usuario escribe algo que no es del menu valida y manda a Dialog
logger.info("El input del usuario no coincide con las Quick Replies. Redirigiendo a Dialogflow normal.");
return memoryStoreConversationService.updateSession(session.withPantallaContexto(null))
.then(conversationManagerService.manageConversation(externalRequest));
}
});
} else if (userMessagesCount == 1) { // Is the second user message in the QR flow
// This is the third message of the flow. Filter and end.
return persistConversationTurn(session, userEntry)