diff --git a/README.md b/README.md
index e725a4a..9392ea1 100644
--- a/README.md
+++ b/README.md
@@ -4,14 +4,3 @@
* *Spring Boot Version:* `3.2.5` (defined in the parent POM)
* *Spring Cloud GCP Version:* `5.3.0` (managed via `spring-cloud-gcp-dependencies`)
* *Spring Cloud Version:* `2023.0.0` (managed via `spring-cloud-dependencies`)
-
-
-Response Body Development:
-```json
-"responseId": "e582a35c-157c-4fb0-b96f-be4a0272ee33",
- "queryResult": {
- "responseText": "¡Hola! Soy Beto, tu asesor financiero de Banorte. ¿En qué puedo ayudarte hoy?",
- "parameters": {},
- }
-```
-
diff --git a/pom.xml b/pom.xml
index 339d537..d762ca8 100644
--- a/pom.xml
+++ b/pom.xml
@@ -114,7 +114,11 @@
com.fasterxml.jackson.modulejackson-module-parameter-names2.19.0
-
+
+
+ com.google.api
+ gax
+
diff --git a/src/main/java/com/example/Orchestrator.java b/src/main/java/com/example/Orchestrator.java
index c078aaf..e9214d0 100644
--- a/src/main/java/com/example/Orchestrator.java
+++ b/src/main/java/com/example/Orchestrator.java
@@ -1,22 +1,18 @@
-package com.example;
+/*
+ * Copyright 2025 Google. This software is provided as-is, without warranty or representation for any use or purpose.
+ * Your use of it is subject to your agreement with Google.
+ */
-import static org.springframework.web.reactive.function.server.RequestPredicates.GET;
-import static org.springframework.web.reactive.function.server.RouterFunctions.route;
-import static org.springframework.web.reactive.function.server.ServerResponse.ok;
+package com.example;
import com.google.api.gax.core.CredentialsProvider;
import com.google.api.gax.core.NoCredentialsProvider;
import com.google.cloud.spring.data.firestore.repository.config.EnableReactiveFirestoreRepositories;
-import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
-import org.springframework.core.io.Resource;
-import org.springframework.http.MediaType;
import org.springframework.transaction.annotation.EnableTransactionManagement;
-import org.springframework.web.reactive.function.server.RouterFunction;
-import org.springframework.web.reactive.function.server.ServerResponse;
@SpringBootApplication
@@ -35,10 +31,4 @@ public class Orchestrator {
public static void main(String[] args) {
SpringApplication.run(Orchestrator.class, args);
}
-
- @Bean
- public RouterFunction indexRouter(
- @Value("classpath:/static/index.html") final Resource indexHtml) {
- return route(GET("/"), request -> ok().contentType(MediaType.TEXT_HTML).bodyValue(indexHtml));
- }
}
diff --git a/src/main/java/com/example/config/VertexAIConfig.java b/src/main/java/com/example/config/GeminiConfig.java
similarity index 63%
rename from src/main/java/com/example/config/VertexAIConfig.java
rename to src/main/java/com/example/config/GeminiConfig.java
index 1310acf..6121eb7 100644
--- a/src/main/java/com/example/config/VertexAIConfig.java
+++ b/src/main/java/com/example/config/GeminiConfig.java
@@ -1,3 +1,8 @@
+/*
+ * Copyright 2025 Google. This software is provided as-is, without warranty or representation for any use or purpose.
+ * Your use of it is subject to your agreement with Google.
+ */
+
package com.example.config;
import com.google.genai.Client;
@@ -9,10 +14,16 @@ import org.springframework.context.annotation.Configuration;
import java.io.IOException;
+/**
+ * Spring configuration class for initializing the Google Gen AI Client.
+ * It uses properties from the application's configuration to create a
+ * singleton `Client` bean for interacting with the Gemini model, ensuring
+ * proper resource management by specifying a destroy method.
+ */
@Configuration
-public class VertexAIConfig {
+public class GeminiConfig {
- private static final Logger logger = LoggerFactory.getLogger(VertexAIConfig.class);
+ private static final Logger logger = LoggerFactory.getLogger(GeminiConfig.class);
@Value("${google.cloud.project}")
private String projectId;
diff --git a/src/main/java/com/example/config/OpenApiConfig.java b/src/main/java/com/example/config/OpenApiConfig.java
index 9a02397..09dc794 100644
--- a/src/main/java/com/example/config/OpenApiConfig.java
+++ b/src/main/java/com/example/config/OpenApiConfig.java
@@ -1,3 +1,8 @@
+/*
+ * Copyright 2025 Google. This software is provided as-is, without warranty or representation for any use or purpose.
+ * Your use of it is subject to your agreement with Google.
+ */
+
package com.example.config;
import io.swagger.v3.oas.models.OpenAPI;
@@ -6,6 +11,11 @@ import io.swagger.v3.oas.models.info.License;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
+/**
+ * Spring configuration class for customizing OpenAPI (Swagger) documentation.
+ * It defines a single bean to configure the API's title, version, description,
+ * and license, providing a structured and user-friendly documentation page.
+ */
@Configuration
public class OpenApiConfig {
diff --git a/src/main/java/com/example/config/RedisConfig.java b/src/main/java/com/example/config/RedisConfig.java
index ea1c100..ca28bc6 100644
--- a/src/main/java/com/example/config/RedisConfig.java
+++ b/src/main/java/com/example/config/RedisConfig.java
@@ -1,6 +1,12 @@
+/*
+ * Copyright 2025 Google. This software is provided as-is, without warranty or representation for any use or purpose.
+ * Your use of it is subject to your agreement with Google.
+ */
+
package com.example.config;
-import com.example.dto.dialogflow.ConversationSessionDTO;
+import com.example.dto.dialogflow.conversation.ConversationSessionDTO;
+import com.example.dto.dialogflow.notification.NotificationSessionDTO;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
@@ -12,32 +18,60 @@ import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.StringRedisSerializer;
+/**
+ * Spring configuration class for setting up Reactive Redis(Memorystore in GCP)
+ * templates.
+ * It defines and customizes `ReactiveRedisTemplate` beans for different data
+ * types
+ * like `ConversationSessionDTO` and `NotificationDTO`, using Jackson for JSON
+ * serialization and ensuring proper handling of Java 8 and higher date/time
+ * objects.
+ */
@Configuration
public class RedisConfig {
@Bean
public ReactiveRedisTemplate reactiveConversationRedisTemplate(
- ReactiveRedisConnectionFactory factory) {
+ ReactiveRedisConnectionFactory factory) {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.registerModule(new JavaTimeModule());
- objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
+ objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
- Jackson2JsonRedisSerializer serializer =
- new Jackson2JsonRedisSerializer<>(objectMapper, ConversationSessionDTO.class);
+ Jackson2JsonRedisSerializer serializer = new Jackson2JsonRedisSerializer<>(
+ objectMapper, ConversationSessionDTO.class);
return new ReactiveRedisTemplate<>(factory, RedisSerializationContext
- .newSerializationContext(new StringRedisSerializer())
- .value(serializer)
- .build());
+ .newSerializationContext(new StringRedisSerializer())
+ .value(serializer)
+ .build());
}
@Bean
public ReactiveRedisTemplate reactiveStringRedisTemplate(
- ReactiveRedisConnectionFactory factory) {
+ ReactiveRedisConnectionFactory factory) {
return new ReactiveRedisTemplate<>(factory, RedisSerializationContext
- .newSerializationContext(new StringRedisSerializer())
- .value(new StringRedisSerializer())
- .build());
- }
+ .newSerializationContext(new StringRedisSerializer())
+ .value(new StringRedisSerializer())
+ .build());
+}
+
+@Bean
+public ReactiveRedisTemplate reactiveNotificationRedisTemplate(
+ ReactiveRedisConnectionFactory factory) {
+ ObjectMapper notificationObjectMapper = new ObjectMapper();
+ notificationObjectMapper.registerModule(new JavaTimeModule());
+ notificationObjectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
+
+ StringRedisSerializer keySerializer = new StringRedisSerializer();
+ Jackson2JsonRedisSerializer valueSerializer = new Jackson2JsonRedisSerializer<>(
+ notificationObjectMapper, NotificationSessionDTO.class);
+
+ RedisSerializationContext.RedisSerializationContextBuilder builder = RedisSerializationContext
+ .newSerializationContext(keySerializer);
+
+ RedisSerializationContext context = builder.value(valueSerializer)
+ .build();
+ return new ReactiveRedisTemplate<>(factory, context);
+}
}
\ No newline at end of file
diff --git a/src/main/java/com/example/controller/ConversationController.java b/src/main/java/com/example/controller/ConversationController.java
index 0638944..6e707ba 100644
--- a/src/main/java/com/example/controller/ConversationController.java
+++ b/src/main/java/com/example/controller/ConversationController.java
@@ -1,8 +1,14 @@
+/*
+ * Copyright 2025 Google. This software is provided as-is, without warranty or representation for any use or purpose.
+ * Your use of it is subject to your agreement with Google.
+ */
+
package com.example.controller;
-import com.example.dto.dialogflow.DetectIntentRequestDTO;
-import com.example.dto.dialogflow.DetectIntentResponseDTO;
-import com.example.service.ConversationManagerService;
+import com.example.dto.dialogflow.base.DetectIntentResponseDTO;
+import com.example.dto.dialogflow.conversation.ExternalConvRequestDTO;
+import com.example.mapper.conversation.ExternalConvRequestMapper;
+import com.example.service.conversation.ConversationManagerService;
import jakarta.validation.Valid;
@@ -16,24 +22,21 @@ import org.slf4j.LoggerFactory;
@RestController
-@RequestMapping("/api/v1")
+@RequestMapping("/api/v1/dialogflow")
public class ConversationController {
private static final Logger logger = LoggerFactory.getLogger(ConversationController.class);
private final ConversationManagerService conversationManagerService;
- public ConversationController(ConversationManagerService conversationManagerService) {
+ public ConversationController(ConversationManagerService conversationManagerService,
+ ExternalConvRequestMapper externalRequestToDialogflowMapper) {
this.conversationManagerService = conversationManagerService;
}
- @PostMapping("/dialogflow/detect-intent")
- public Mono detectIntent(@Valid @RequestBody DetectIntentRequestDTO request) {
- logger.info("Received request for session: {}", request.sessionId());
+ @PostMapping("/detect-intent")
+ public Mono detectIntent(@Valid @RequestBody ExternalConvRequestDTO request) {
return conversationManagerService.manageConversation(request)
- .doOnSuccess(response -> logger.info("Successfully processed direct Dialogflow request for session: {}", request.sessionId()))
- .doOnError(error -> logger.error("Error processing direct Dialogflow request for session {}: {}", request.sessionId(), error.getMessage(), error));
+ .doOnSuccess(response -> logger.info("Successfully processed direct Dialogflow request"))
+ .doOnError(error -> logger.error("Error processing direct Dialogflow request: {}", error.getMessage(), error));
}
-
-
-
}
\ No newline at end of file
diff --git a/src/main/java/com/example/controller/ConversationSummaryController.java b/src/main/java/com/example/controller/ConversationSummaryController.java
index a32ead0..7e54a94 100644
--- a/src/main/java/com/example/controller/ConversationSummaryController.java
+++ b/src/main/java/com/example/controller/ConversationSummaryController.java
@@ -1,10 +1,16 @@
+/*
+ * Copyright 2025 Google. This software is provided as-is, without warranty or representation for any use or purpose.
+ * Your use of it is subject to your agreement with Google.
+ */
package com.example.controller;
import com.example.dto.gemini.ConversationSummaryRequest;
import com.example.dto.gemini.ConversationSummaryResponse;
+import com.example.service.summary.ConversationSummaryService;
+
import jakarta.validation.Valid;
-import com.example.service.ConversationSummaryService;
+
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
diff --git a/src/main/java/com/example/controller/NotificationController.java b/src/main/java/com/example/controller/NotificationController.java
new file mode 100644
index 0000000..e091274
--- /dev/null
+++ b/src/main/java/com/example/controller/NotificationController.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2025 Google. This software is provided as-is, without warranty or representation for any use or purpose.
+ * Your use of it is subject to your agreement with Google.
+ */
+
+package com.example.controller;
+
+import com.example.dto.dialogflow.notification.ExternalNotRequestDTO;
+import com.example.service.notification.NotificationManagerService;
+
+import jakarta.validation.Valid;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import reactor.core.publisher.Mono;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@RestController
+@RequestMapping("/api/v1/dialogflow")
+public class NotificationController {
+
+ private static final Logger logger = LoggerFactory.getLogger(ConversationController.class);
+ private final NotificationManagerService notificationManagerService;
+
+ public NotificationController(NotificationManagerService notificationManagerService) {
+ this.notificationManagerService = notificationManagerService;
+ }
+
+ @PostMapping("/notification")
+ public Mono processNotification(@Valid @RequestBody ExternalNotRequestDTO request) {
+ return notificationManagerService.processNotification(request)
+ .doOnSuccess(response -> logger.info("Successfully processed direct Dialogflow request"))
+ .doOnError(error -> logger.error("Error processing direct Dialogflow request: {}", error.getMessage(), error))
+ .then();
+ }
+}
diff --git a/src/main/java/com/example/dto/base/BaseRequest.java b/src/main/java/com/example/dto/base/BaseRequest.java
deleted file mode 100644
index f298c6d..0000000
--- a/src/main/java/com/example/dto/base/BaseRequest.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package com.example.dto.base;
-
-import com.fasterxml.jackson.annotation.JsonSubTypes;
-import com.fasterxml.jackson.annotation.JsonTypeInfo;
-
-@JsonTypeInfo(
- use = JsonTypeInfo.Id.NAME,
- include = JsonTypeInfo.As.PROPERTY,
- property = "type"
-)
-@JsonSubTypes({
- @JsonSubTypes.Type(value = NotificationRequest.class, name = "NOTIFICATION"),
-})
-public sealed interface BaseRequest
- permits NotificationRequest{
- String type();
-}
\ No newline at end of file
diff --git a/src/main/java/com/example/dto/base/ConversationContext.java b/src/main/java/com/example/dto/base/ConversationContext.java
deleted file mode 100644
index 37de5e5..0000000
--- a/src/main/java/com/example/dto/base/ConversationContext.java
+++ /dev/null
@@ -1,8 +0,0 @@
-package com.example.dto.base;
-
-public record ConversationContext(
- String userId,
- String sessionId,
- String userMessageText,
- String primaryPhoneNumber
-) {}
\ No newline at end of file
diff --git a/src/main/java/com/example/dto/base/NotificationRequest.java b/src/main/java/com/example/dto/base/NotificationRequest.java
deleted file mode 100644
index 6d9b613..0000000
--- a/src/main/java/com/example/dto/base/NotificationRequest.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package com.example.dto.base;
-import com.fasterxml.jackson.annotation.JsonInclude;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import jakarta.validation.Valid;
-
-@JsonInclude(JsonInclude.Include.NON_NULL)
-public record NotificationRequest(
- @JsonProperty("requestId") String requestId,
- @JsonProperty("sessionId") String sessionId,
- @JsonProperty("mensaje") String message,
- @JsonProperty("SIC") String SIC,
- @Valid Usuario usuario,
- @JsonProperty("pantalla_contexto") String pantallaContexto,
- @JsonProperty("canal") String canal
-) implements BaseRequest {
- @Override
- public String type() {
- return "NOTIFICATION";
- }
- @JsonInclude(JsonInclude.Include.NON_NULL)
- public record Usuario(
- String telefono,
- String nickname
- ) {
- }
-}
\ No newline at end of file
diff --git a/src/main/java/com/example/dto/dialogflow/ConversationEntryDTO.java b/src/main/java/com/example/dto/dialogflow/ConversationEntryDTO.java
deleted file mode 100644
index 4302c19..0000000
--- a/src/main/java/com/example/dto/dialogflow/ConversationEntryDTO.java
+++ /dev/null
@@ -1,35 +0,0 @@
-package com.example.dto.dialogflow;
-
-import com.fasterxml.jackson.annotation.JsonInclude;
-import java.time.Instant;
-import java.util.Map;
-
-@JsonInclude(JsonInclude.Include.NON_NULL)
-public record ConversationEntryDTO(
- ConversationEntryType type,
- Instant timestamp,
- String text,
- String intentDisplayName,
- Map parameters,
- String webhookStatus,
- String canal
-) {
- public static ConversationEntryDTO forUser(String text) {
- return new ConversationEntryDTO(ConversationEntryType.USER_MESSAGE, Instant.now(),
- text, null, null, null, null);
- }
-
- public static ConversationEntryDTO forAgent(QueryResultDTO agentQueryResult) {
- String fulfillmentText = (agentQueryResult != null && agentQueryResult.responseText() != null) ? agentQueryResult.responseText() : "";
-
- return new ConversationEntryDTO(
- ConversationEntryType.AGENT_RESPONSE,
- Instant.now(),
- fulfillmentText,
- null,
- agentQueryResult.parameters(),
- null,
- null
- );
- }
-}
\ No newline at end of file
diff --git a/src/main/java/com/example/dto/dialogflow/ConversationEntryType.java b/src/main/java/com/example/dto/dialogflow/ConversationEntryType.java
deleted file mode 100644
index ca130da..0000000
--- a/src/main/java/com/example/dto/dialogflow/ConversationEntryType.java
+++ /dev/null
@@ -1,6 +0,0 @@
-package com.example.dto.dialogflow;
-
-public enum ConversationEntryType {
- USER_MESSAGE,
- AGENT_RESPONSE
-}
\ No newline at end of file
diff --git a/src/main/java/com/example/dto/dialogflow/DetectIntentRequestDTO.java b/src/main/java/com/example/dto/dialogflow/DetectIntentRequestDTO.java
deleted file mode 100644
index 147fe1f..0000000
--- a/src/main/java/com/example/dto/dialogflow/DetectIntentRequestDTO.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package com.example.dto.dialogflow;
-
-import com.example.dto.base.UsuarioDTO;
-import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-@JsonIgnoreProperties(ignoreUnknown = true)
-public record DetectIntentRequestDTO(
- @JsonProperty("session") String sessionId,
- @JsonProperty("queryInput") QueryInputDTO queryInput,
- @JsonProperty("queryParams") QueryParamsDTO queryParams,
- @JsonProperty("usuario") UsuarioDTO usuario,
- String userId
-) {
-
- public DetectIntentRequestDTO withSessionId(String newSessionId) {
- return new DetectIntentRequestDTO(
- newSessionId,
- this.queryInput(),
- this.queryParams(),
- this.usuario(),
- this.userId()
- );
- }
-}
\ No newline at end of file
diff --git a/src/main/java/com/example/dto/dialogflow/DetectIntentResponseDTO.java b/src/main/java/com/example/dto/dialogflow/DetectIntentResponseDTO.java
deleted file mode 100644
index 7eac05e..0000000
--- a/src/main/java/com/example/dto/dialogflow/DetectIntentResponseDTO.java
+++ /dev/null
@@ -1,8 +0,0 @@
-package com.example.dto.dialogflow;
-
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-public record DetectIntentResponseDTO(
- @JsonProperty("responseId") String responseId,
- @JsonProperty("queryResult") QueryResultDTO queryResult
-) {}
\ No newline at end of file
diff --git a/src/main/java/com/example/dto/dialogflow/IntentDTO.java b/src/main/java/com/example/dto/dialogflow/IntentDTO.java
deleted file mode 100644
index 26aa0f4..0000000
--- a/src/main/java/com/example/dto/dialogflow/IntentDTO.java
+++ /dev/null
@@ -1,6 +0,0 @@
-package com.example.dto.dialogflow;
-
-public record IntentDTO(
- String name,
- String displayName
-) {}
\ No newline at end of file
diff --git a/src/main/java/com/example/dto/dialogflow/QueryInputDTO.java b/src/main/java/com/example/dto/dialogflow/QueryInputDTO.java
deleted file mode 100644
index 037f9a1..0000000
--- a/src/main/java/com/example/dto/dialogflow/QueryInputDTO.java
+++ /dev/null
@@ -1,3 +0,0 @@
-package com.example.dto.dialogflow;
-
-public record QueryInputDTO(TextInputDTO text, String languageCode) {}
\ No newline at end of file
diff --git a/src/main/java/com/example/dto/dialogflow/QueryParamsDTO.java b/src/main/java/com/example/dto/dialogflow/QueryParamsDTO.java
deleted file mode 100644
index ce54ea9..0000000
--- a/src/main/java/com/example/dto/dialogflow/QueryParamsDTO.java
+++ /dev/null
@@ -1,4 +0,0 @@
-package com.example.dto.dialogflow;
-
-import java.util.Map;
-public record QueryParamsDTO(Map parameters) {}
diff --git a/src/main/java/com/example/dto/dialogflow/TextInputDTO.java b/src/main/java/com/example/dto/dialogflow/TextInputDTO.java
deleted file mode 100644
index 12f93a9..0000000
--- a/src/main/java/com/example/dto/dialogflow/TextInputDTO.java
+++ /dev/null
@@ -1,3 +0,0 @@
-package com.example.dto.dialogflow;
-
-public record TextInputDTO(String text) {}
\ No newline at end of file
diff --git a/src/main/java/com/example/dto/dialogflow/base/DetectIntentRequestDTO.java b/src/main/java/com/example/dto/dialogflow/base/DetectIntentRequestDTO.java
new file mode 100644
index 0000000..f26c861
--- /dev/null
+++ b/src/main/java/com/example/dto/dialogflow/base/DetectIntentRequestDTO.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2025 Google. This software is provided as-is, without warranty or representation for any use or purpose.
+ * Your use of it is subject to your agreement with Google.
+ */
+
+package com.example.dto.dialogflow.base;
+
+import com.example.dto.dialogflow.conversation.QueryInputDTO;
+import com.example.dto.dialogflow.conversation.QueryParamsDTO;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+public record DetectIntentRequestDTO(
+ @JsonProperty("queryInput") QueryInputDTO queryInput,
+ @JsonProperty("queryParams") QueryParamsDTO queryParams
+) {
+
+public DetectIntentRequestDTO withParameter(String key, Object value) {
+ // Create a new QueryParamsDTO with the updated session parameter
+ QueryParamsDTO updatedQueryParams = this.queryParams().withSessionParameter(key, value);
+
+ // Return a new DetectIntentRequestDTO instance with the updated QueryParamsDTO
+ return new DetectIntentRequestDTO(
+ this.queryInput(),
+ updatedQueryParams
+ );
+}
+}
\ No newline at end of file
diff --git a/src/main/java/com/example/dto/dialogflow/base/DetectIntentResponseDTO.java b/src/main/java/com/example/dto/dialogflow/base/DetectIntentResponseDTO.java
new file mode 100644
index 0000000..9411f6d
--- /dev/null
+++ b/src/main/java/com/example/dto/dialogflow/base/DetectIntentResponseDTO.java
@@ -0,0 +1,14 @@
+/*
+ * Copyright 2025 Google. This software is provided as-is, without warranty or representation for any use or purpose.
+ * Your use of it is subject to your agreement with Google.
+ */
+
+package com.example.dto.dialogflow.base;
+
+import com.example.dto.dialogflow.conversation.QueryResultDTO;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+public record DetectIntentResponseDTO(
+ @JsonProperty("responseId") String responseId,
+ @JsonProperty("queryResult") QueryResultDTO queryResult
+) {}
\ No newline at end of file
diff --git a/src/main/java/com/example/dto/dialogflow/conversation/ConversationContext.java b/src/main/java/com/example/dto/dialogflow/conversation/ConversationContext.java
new file mode 100644
index 0000000..def56e3
--- /dev/null
+++ b/src/main/java/com/example/dto/dialogflow/conversation/ConversationContext.java
@@ -0,0 +1,13 @@
+/*
+ * Copyright 2025 Google. This software is provided as-is, without warranty or representation for any use or purpose.
+ * Your use of it is subject to your agreement with Google.
+ */
+
+package com.example.dto.dialogflow.conversation;
+
+public record ConversationContext(
+ String userId,
+ String sessionId,
+ String userMessageText,
+ String primaryPhoneNumber
+) {}
\ No newline at end of file
diff --git a/src/main/java/com/example/dto/dialogflow/conversation/ConversationEntryDTO.java b/src/main/java/com/example/dto/dialogflow/conversation/ConversationEntryDTO.java
new file mode 100644
index 0000000..2fedd96
--- /dev/null
+++ b/src/main/java/com/example/dto/dialogflow/conversation/ConversationEntryDTO.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2025 Google. This software is provided as-is, without warranty or representation for any use or purpose.
+ * Your use of it is subject to your agreement with Google.
+ */
+
+package com.example.dto.dialogflow.conversation;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import java.time.Instant;
+import java.util.Map;
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public record ConversationEntryDTO(
+ ConversationEntryEntity entity,
+ ConversationEntryType type,
+ Instant timestamp,
+ String text,
+ Map parameters,
+ String canal
+) {
+ public static ConversationEntryDTO forUser(String text) {
+ return new ConversationEntryDTO(
+ ConversationEntryEntity.USUARIO,
+ ConversationEntryType.CONVERSACION,
+ Instant.now(),
+ text,
+ null,
+ null);
+ }
+
+ public static ConversationEntryDTO forAgent(QueryResultDTO agentQueryResult) {
+ String fulfillmentText = (agentQueryResult != null && agentQueryResult.responseText() != null) ? agentQueryResult.responseText() : "";
+
+ return new ConversationEntryDTO(
+ ConversationEntryEntity.AGENTE,
+ ConversationEntryType.CONVERSACION,
+ Instant.now(),
+ fulfillmentText,
+ agentQueryResult.parameters(),
+ null
+ );
+ }
+ public static ConversationEntryDTO forSystem(String text) {
+ return new ConversationEntryDTO(
+ ConversationEntryEntity.SISTEMA,
+ ConversationEntryType.CONVERSACION,
+ Instant.now(),
+ text,
+ null,
+ null
+ );
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/example/dto/dialogflow/conversation/ConversationEntryEntity.java b/src/main/java/com/example/dto/dialogflow/conversation/ConversationEntryEntity.java
new file mode 100644
index 0000000..17f442a
--- /dev/null
+++ b/src/main/java/com/example/dto/dialogflow/conversation/ConversationEntryEntity.java
@@ -0,0 +1,12 @@
+/*
+ * Copyright 2025 Google. This software is provided as-is, without warranty or representation for any use or purpose.
+ * Your use of it is subject to your agreement with Google.
+ */
+
+package com.example.dto.dialogflow.conversation;
+
+public enum ConversationEntryEntity {
+ USUARIO,
+ AGENTE,
+ SISTEMA
+}
\ No newline at end of file
diff --git a/src/main/java/com/example/dto/dialogflow/conversation/ConversationEntryType.java b/src/main/java/com/example/dto/dialogflow/conversation/ConversationEntryType.java
new file mode 100644
index 0000000..0f1efdd
--- /dev/null
+++ b/src/main/java/com/example/dto/dialogflow/conversation/ConversationEntryType.java
@@ -0,0 +1,11 @@
+/*
+ * Copyright 2025 Google. This software is provided as-is, without warranty or representation for any use or purpose.
+ * Your use of it is subject to your agreement with Google.
+ */
+
+package com.example.dto.dialogflow.conversation;
+
+public enum ConversationEntryType {
+ INICIO,
+ CONVERSACION
+}
\ No newline at end of file
diff --git a/src/main/java/com/example/dto/dialogflow/ConversationSessionDTO.java b/src/main/java/com/example/dto/dialogflow/conversation/ConversationSessionDTO.java
similarity index 88%
rename from src/main/java/com/example/dto/dialogflow/ConversationSessionDTO.java
rename to src/main/java/com/example/dto/dialogflow/conversation/ConversationSessionDTO.java
index 458c693..d5cc2dd 100644
--- a/src/main/java/com/example/dto/dialogflow/ConversationSessionDTO.java
+++ b/src/main/java/com/example/dto/dialogflow/conversation/ConversationSessionDTO.java
@@ -1,4 +1,9 @@
-package com.example.dto.dialogflow;
+/*
+ * Copyright 2025 Google. This software is provided as-is, without warranty or representation for any use or purpose.
+ * Your use of it is subject to your agreement with Google.
+ */
+
+package com.example.dto.dialogflow.conversation;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import java.time.Instant;
diff --git a/src/main/java/com/example/dto/dialogflow/conversation/ExternalConvRequestDTO.java b/src/main/java/com/example/dto/dialogflow/conversation/ExternalConvRequestDTO.java
new file mode 100644
index 0000000..5b88f92
--- /dev/null
+++ b/src/main/java/com/example/dto/dialogflow/conversation/ExternalConvRequestDTO.java
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2025 Google. This software is provided as-is, without warranty or representation for any use or purpose.
+ * Your use of it is subject to your agreement with Google.
+ */
+
+package com.example.dto.dialogflow.conversation;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+public record ExternalConvRequestDTO(
+ @JsonProperty("mensaje") String message,
+ @JsonProperty("usuario") UsuarioDTO user,
+ @JsonProperty("canal") String channel,
+ @JsonProperty("tipo") ConversationEntryType tipo
+) {
+ public ExternalConvRequestDTO {}
+ }
\ No newline at end of file
diff --git a/src/main/java/com/example/dto/dialogflow/conversation/QueryInputDTO.java b/src/main/java/com/example/dto/dialogflow/conversation/QueryInputDTO.java
new file mode 100644
index 0000000..4545b1a
--- /dev/null
+++ b/src/main/java/com/example/dto/dialogflow/conversation/QueryInputDTO.java
@@ -0,0 +1,14 @@
+/*
+ * Copyright 2025 Google. This software is provided as-is, without warranty or representation for any use or purpose.
+ * Your use of it is subject to your agreement with Google.
+ */
+
+package com.example.dto.dialogflow.conversation;
+
+import com.example.dto.dialogflow.notification.EventInputDTO;
+
+public record QueryInputDTO(
+ TextInputDTO text, // Can be null if using event
+ EventInputDTO event,
+ String languageCode // REQUIRED for both text and event inputs
+) {}
\ No newline at end of file
diff --git a/src/main/java/com/example/dto/dialogflow/conversation/QueryParamsDTO.java b/src/main/java/com/example/dto/dialogflow/conversation/QueryParamsDTO.java
new file mode 100644
index 0000000..8ab4b6d
--- /dev/null
+++ b/src/main/java/com/example/dto/dialogflow/conversation/QueryParamsDTO.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2025 Google. This software is provided as-is, without warranty or representation for any use or purpose.
+ * Your use of it is subject to your agreement with Google.
+ */
+
+package com.example.dto.dialogflow.conversation;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+public record QueryParamsDTO(
+ @JsonProperty("parameters") Map parameters) {
+
+ public QueryParamsDTO {
+ parameters = Objects.requireNonNullElseGet(parameters, HashMap::new);
+ parameters = new HashMap<>(parameters);
+ }
+
+ public QueryParamsDTO withSessionParameter(String key, Object value) {
+ Map updatedParams = new HashMap<>(this.parameters());
+ updatedParams.put(key, value);
+ return new QueryParamsDTO(updatedParams);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/example/dto/dialogflow/QueryResultDTO.java b/src/main/java/com/example/dto/dialogflow/conversation/QueryResultDTO.java
similarity index 50%
rename from src/main/java/com/example/dto/dialogflow/QueryResultDTO.java
rename to src/main/java/com/example/dto/dialogflow/conversation/QueryResultDTO.java
index a8f1c46..485d893 100644
--- a/src/main/java/com/example/dto/dialogflow/QueryResultDTO.java
+++ b/src/main/java/com/example/dto/dialogflow/conversation/QueryResultDTO.java
@@ -1,4 +1,9 @@
-package com.example.dto.dialogflow;
+/*
+ * Copyright 2025 Google. This software is provided as-is, without warranty or representation for any use or purpose.
+ * Your use of it is subject to your agreement with Google.
+ */
+
+package com.example.dto.dialogflow.conversation;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.Map;
diff --git a/src/main/java/com/example/dto/dialogflow/conversation/TextInputDTO.java b/src/main/java/com/example/dto/dialogflow/conversation/TextInputDTO.java
new file mode 100644
index 0000000..b4546ee
--- /dev/null
+++ b/src/main/java/com/example/dto/dialogflow/conversation/TextInputDTO.java
@@ -0,0 +1,8 @@
+/*
+ * Copyright 2025 Google. This software is provided as-is, without warranty or representation for any use or purpose.
+ * Your use of it is subject to your agreement with Google.
+ */
+
+package com.example.dto.dialogflow.conversation;
+
+public record TextInputDTO(String text) {}
\ No newline at end of file
diff --git a/src/main/java/com/example/dto/base/UsuarioDTO.java b/src/main/java/com/example/dto/dialogflow/conversation/UsuarioDTO.java
similarity index 50%
rename from src/main/java/com/example/dto/base/UsuarioDTO.java
rename to src/main/java/com/example/dto/dialogflow/conversation/UsuarioDTO.java
index f101439..11bc796 100644
--- a/src/main/java/com/example/dto/base/UsuarioDTO.java
+++ b/src/main/java/com/example/dto/dialogflow/conversation/UsuarioDTO.java
@@ -1,4 +1,9 @@
-package com.example.dto.base;
+/*
+ * Copyright 2025 Google. This software is provided as-is, without warranty or representation for any use or purpose.
+ * Your use of it is subject to your agreement with Google.
+ */
+
+package com.example.dto.dialogflow.conversation;
import com.fasterxml.jackson.annotation.JsonProperty;
import jakarta.validation.constraints.NotBlank;
diff --git a/src/main/java/com/example/dto/dialogflow/notification/EventInputDTO.java b/src/main/java/com/example/dto/dialogflow/notification/EventInputDTO.java
new file mode 100644
index 0000000..0501fcb
--- /dev/null
+++ b/src/main/java/com/example/dto/dialogflow/notification/EventInputDTO.java
@@ -0,0 +1,10 @@
+/*
+ * Copyright 2025 Google. This software is provided as-is, without warranty or representation for any use or purpose.
+ * Your use of it is subject to your agreement with Google.
+ */
+
+package com.example.dto.dialogflow.notification;
+
+public record EventInputDTO(
+ String event
+) {}
diff --git a/src/main/java/com/example/dto/dialogflow/notification/ExternalNotRequestDTO.java b/src/main/java/com/example/dto/dialogflow/notification/ExternalNotRequestDTO.java
new file mode 100644
index 0000000..3113deb
--- /dev/null
+++ b/src/main/java/com/example/dto/dialogflow/notification/ExternalNotRequestDTO.java
@@ -0,0 +1,16 @@
+/*
+ * Copyright 2025 Google. This software is provided as-is, without warranty or representation for any use or purpose.
+ * Your use of it is subject to your agreement with Google.
+ */
+
+package com.example.dto.dialogflow.notification;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+public record ExternalNotRequestDTO(
+ @JsonProperty("texto") String text,
+ @JsonProperty("telefono") String phoneNumber) {
+ public ExternalNotRequestDTO {
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/example/dto/dialogflow/notification/NotificationDTO.java b/src/main/java/com/example/dto/dialogflow/notification/NotificationDTO.java
new file mode 100644
index 0000000..1aed0fe
--- /dev/null
+++ b/src/main/java/com/example/dto/dialogflow/notification/NotificationDTO.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2025 Google. This software is provided as-is, without warranty or representation for any use or purpose.
+ * Your use of it is subject to your agreement with Google.
+ */
+package com.example.dto.dialogflow.notification;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import java.time.Instant;
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * Represents a notification record to be stored in Firestore and cached in
+ * Redis.
+ */
+@JsonIgnoreProperties(ignoreUnknown = true) // Ignorar campos adicionales durante la deserialización
+public record NotificationDTO(
+ String idNotificacion, // ID único para esta notificación (ej. el sessionId usado con Dialogflow)
+ String telefono,
+ Instant timestampCreacion, // Momento en que la notificación fue procesada
+ String texto, // 'texto' original de NotificationRequestDTO (si aplica)
+ String nombreEventoDialogflow, // Nombre del evento enviado a Dialogflow (ej. "tu Estado de cuenta listo")
+ String codigoIdiomaDialogflow, // Código de idioma usado para el evento
+ Map parametros // Parámetros de sesión finales después del procesamiento de// Dialogflow
+) {
+ public NotificationDTO {
+ Objects.requireNonNull(idNotificacion, "Notification ID cannot be null.");
+ Objects.requireNonNull(timestampCreacion, "Notification timestamp cannot be null.");
+ Objects.requireNonNull(nombreEventoDialogflow, "Dialogflow event name cannot be null.");
+ Objects.requireNonNull(codigoIdiomaDialogflow, "Dialogflow language code cannot be null.");
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/example/dto/dialogflow/notification/NotificationSessionDTO.java b/src/main/java/com/example/dto/dialogflow/notification/NotificationSessionDTO.java
new file mode 100644
index 0000000..8169ddb
--- /dev/null
+++ b/src/main/java/com/example/dto/dialogflow/notification/NotificationSessionDTO.java
@@ -0,0 +1,24 @@
+// src/main/java/com/example/dto/dialogflow/notification/NotificationSessionDTO.java
+package com.example.dto.dialogflow.notification;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import java.time.Instant;
+import java.util.List;
+import java.util.Objects;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+public record NotificationSessionDTO(
+ String sessionId, // The unique session identifier (e.g., the phone number)
+ String telefono, // The phone number for this session
+ Instant fechaCreacion, // When the session was first created
+ Instant ultimaActualizacion, // When the session was last updated
+ List notificaciones // List of individual notification events
+) {
+ public NotificationSessionDTO {
+ Objects.requireNonNull(sessionId, "Session ID cannot be null.");
+ Objects.requireNonNull(telefono, "Phone number cannot be null.");
+ Objects.requireNonNull(fechaCreacion, "Creation timestamp cannot be null.");
+ Objects.requireNonNull(ultimaActualizacion, "Last updated timestamp cannot be null.");
+ Objects.requireNonNull(notificaciones, "Notifications list cannot be null.");
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/example/dto/gemini/ConversationEntrySummaryDTO.java b/src/main/java/com/example/dto/gemini/ConversationEntrySummaryDTO.java
index 87e8e93..a98acec 100644
--- a/src/main/java/com/example/dto/gemini/ConversationEntrySummaryDTO.java
+++ b/src/main/java/com/example/dto/gemini/ConversationEntrySummaryDTO.java
@@ -1,6 +1,11 @@
+/*
+ * Copyright 2025 Google. This software is provided as-is, without warranty or representation for any use or purpose.
+ * Your use of it is subject to your agreement with Google.
+ */
+
package com.example.dto.gemini;
-import com.example.dto.dialogflow.ConversationEntryType;
+import com.example.dto.dialogflow.conversation.ConversationEntryEntity;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
@@ -12,7 +17,7 @@ import java.util.Optional;
public record ConversationEntrySummaryDTO(
@JsonProperty("text") String text,
@JsonProperty("timestamp") Timestamp timestamp,
- Optional type,
+ Optional type,
@JsonProperty("intentDisplayName") String intentDisplayName,
@JsonProperty("parameters") Map parameters,
@JsonProperty("webhookStatus") String webhookStatus,
@@ -33,7 +38,7 @@ public record ConversationEntrySummaryDTO(
timestamp,
Optional.ofNullable(typeString).map(t -> {
try {
- return ConversationEntryType.valueOf(t);
+ return ConversationEntryEntity.valueOf(t);
} catch (IllegalArgumentException e) {
System.err.println("Warning: Invalid ConversationEntryType string during deserialization: " + t);
return null;
diff --git a/src/main/java/com/example/dto/gemini/ConversationSessionSummaryDTO.java b/src/main/java/com/example/dto/gemini/ConversationSessionSummaryDTO.java
index 3e4ec56..5168cba 100644
--- a/src/main/java/com/example/dto/gemini/ConversationSessionSummaryDTO.java
+++ b/src/main/java/com/example/dto/gemini/ConversationSessionSummaryDTO.java
@@ -1,3 +1,8 @@
+/*
+ * Copyright 2025 Google. This software is provided as-is, without warranty or representation for any use or purpose.
+ * Your use of it is subject to your agreement with Google.
+ */
+
package com.example.dto.gemini;
import com.fasterxml.jackson.annotation.JsonCreator;
diff --git a/src/main/java/com/example/dto/gemini/ConversationSummaryRequest.java b/src/main/java/com/example/dto/gemini/ConversationSummaryRequest.java
index 4c0f29b..7e71f5f 100644
--- a/src/main/java/com/example/dto/gemini/ConversationSummaryRequest.java
+++ b/src/main/java/com/example/dto/gemini/ConversationSummaryRequest.java
@@ -1,7 +1,12 @@
+/*
+ * Copyright 2025 Google. This software is provided as-is, without warranty or representation for any use or purpose.
+ * Your use of it is subject to your agreement with Google.
+ */
+
package com.example.dto.gemini;
-import jakarta.validation.constraints.Max;
-import jakarta.validation.constraints.Min;
+import jakarta.validation.constraints.DecimalMax;
+import jakarta.validation.constraints.DecimalMin;
import jakarta.validation.constraints.NotBlank;
public record ConversationSummaryRequest(
@@ -9,11 +14,16 @@ public record ConversationSummaryRequest(
String sessionId,
@NotBlank(message = "Prompt for summarization is required.")
String prompt,
- @Min(value = 0, message = "Temperature must be between 0.0 and 1.0.")
- @Max(value = 1, message = "Temperature must be between 0.0 and 1.0.")
+ @DecimalMin(value = "0.0", message = "Temperature must be between 0.0 and 1.0.")
+ @DecimalMax(value = "0.1", message = "Temperature must be between 0.0 and 1.0.")
Float temperature,
- @Min(value = 1, message = "Max Output Tokens must be at least 1.")
+ @DecimalMin(value = "0.1", message = "Max Output Tokens must be at least 1.")
Integer maxOutputTokens,
@NotBlank(message = "model is required.")
- String modelName
+ String modelName,
+ @NotBlank(message = "topP is required.")
+ @DecimalMin(value = "0.0", message = "topP must be between 0.0 and 1.0.")
+ Float top_P
+
+
) {}
\ No newline at end of file
diff --git a/src/main/java/com/example/dto/gemini/ConversationSummaryResponse.java b/src/main/java/com/example/dto/gemini/ConversationSummaryResponse.java
index 918f636..b7d0a2f 100644
--- a/src/main/java/com/example/dto/gemini/ConversationSummaryResponse.java
+++ b/src/main/java/com/example/dto/gemini/ConversationSummaryResponse.java
@@ -1,3 +1,8 @@
+/*
+ * Copyright 2025 Google. This software is provided as-is, without warranty or representation for any use or purpose.
+ * Your use of it is subject to your agreement with Google.
+ */
+
package com.example.dto.gemini;
import jakarta.validation.constraints.NotBlank;
diff --git a/src/main/java/com/example/exception/GeminiClientException.java b/src/main/java/com/example/exception/GeminiClientException.java
new file mode 100644
index 0000000..6e76ee2
--- /dev/null
+++ b/src/main/java/com/example/exception/GeminiClientException.java
@@ -0,0 +1,12 @@
+package com.example.exception;
+
+public class GeminiClientException extends Exception {
+
+ public GeminiClientException(String message) {
+ super(message);
+ }
+
+ public GeminiClientException(String message, Throwable cause) {
+ super(message, cause);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/example/mapper/DialogflowRequestMapper.java b/src/main/java/com/example/mapper/DialogflowRequestMapper.java
deleted file mode 100644
index 7a50ad0..0000000
--- a/src/main/java/com/example/mapper/DialogflowRequestMapper.java
+++ /dev/null
@@ -1,79 +0,0 @@
-package com.example.mapper;
-
-import com.example.dto.dialogflow.DetectIntentRequestDTO;
-import com.example.util.ProtobufUtil;
-
-import com.google.cloud.dialogflow.cx.v3.DetectIntentRequest;
-import com.google.cloud.dialogflow.cx.v3.QueryInput;
-import com.google.cloud.dialogflow.cx.v3.QueryParameters;
-import com.google.cloud.dialogflow.cx.v3.TextInput;
-import com.google.protobuf.Struct;
-import com.google.protobuf.Value;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.stereotype.Component;
-
-import java.util.Map;
-import java.util.Objects;
-
-@Component
-public class DialogflowRequestMapper {
-
- private static final Logger logger = LoggerFactory.getLogger(DialogflowRequestMapper.class);
-
- @org.springframework.beans.factory.annotation.Value("${dialogflow.default-language-code:es}") String defaultLanguageCode;
-
- public DetectIntentRequest.Builder mapToDetectIntentRequestBuilder(DetectIntentRequestDTO requestDto) {
- Objects.requireNonNull(requestDto, "DetectIntentRequestDTO cannot be null for mapping.");
-
- logger.debug("Building partial Dialogflow CX DetectIntentRequest Protobuf Builder from DTO (only QueryInput and QueryParams).");
-
- // Build QueryInput from the DTO's text and language code
- QueryInput.Builder queryInputBuilder = QueryInput.newBuilder();
- if (requestDto.queryInput() != null && requestDto.queryInput().text() != null &&
- requestDto.queryInput().text().text() != null && !requestDto.queryInput().text().text().trim().isEmpty()) {
-
- queryInputBuilder.setText(TextInput.newBuilder()
- .setText(requestDto.queryInput().text().text())
- .build());
- queryInputBuilder.setLanguageCode(requestDto.queryInput().languageCode() != null ? requestDto.queryInput().languageCode() : defaultLanguageCode);
- } else {
- logger.error("Dialogflow query input text is required for building Protobuf query input.");
- throw new IllegalArgumentException("Dialogflow query input text is required.");
- }
-
- // Build QueryParameters from the DTO's parameters map
- QueryParameters.Builder queryParametersBuilder = QueryParameters.newBuilder();
- Struct.Builder paramsStructBuilder = Struct.newBuilder();
- // Add existing parameters from DTO's queryParams
- if (requestDto.queryParams() != null && requestDto.queryParams().parameters() != null) {
- for (Map.Entry entry : requestDto.queryParams().parameters().entrySet()) {
- Value protobufValue = ProtobufUtil.convertJavaObjectToProtobufValue(entry.getValue());
- paramsStructBuilder.putFields(entry.getKey(), protobufValue);
- }
- }
-
- if (requestDto.usuario() != null && requestDto.usuario().telefono() != null && !requestDto.usuario().telefono().trim().isEmpty()) {
- paramsStructBuilder.putFields("telefono", Value.newBuilder().setStringValue(requestDto.usuario().telefono()).build());
- logger.debug("Added 'telefono' as a query parameter: {}", requestDto.usuario().telefono());
- }
-
- if (paramsStructBuilder.getFieldsCount() > 0) {
- queryParametersBuilder.setParameters(paramsStructBuilder.build());
- logger.debug("Custom parameters (including telefono if present) added to Protobuf request builder.");
- } else {
- logger.debug("No custom parameters provided in DTO (or no telefono in usuario).");
- }
-
- DetectIntentRequest.Builder detectIntentRequestBuilder = DetectIntentRequest.newBuilder()
- .setQueryInput(queryInputBuilder.build());
-
- if (queryParametersBuilder.hasParameters()) {
- detectIntentRequestBuilder.setQueryParams(queryParametersBuilder.build());
- }
-
- logger.debug("Finished building partial DetectIntentRequest Protobuf Builder.");
- return detectIntentRequestBuilder;
- }
-}
\ No newline at end of file
diff --git a/src/main/java/com/example/mapper/FirestoreConversationMapper.java b/src/main/java/com/example/mapper/FirestoreConversationMapper.java
deleted file mode 100644
index 20f0979..0000000
--- a/src/main/java/com/example/mapper/FirestoreConversationMapper.java
+++ /dev/null
@@ -1,132 +0,0 @@
-package com.example.mapper;
-
-import com.example.dto.dialogflow.ConversationEntryDTO;
-import com.example.dto.dialogflow.ConversationEntryType;
-import com.example.dto.dialogflow.ConversationSessionDTO;
-import com.google.cloud.Timestamp;
-import com.google.cloud.firestore.FieldValue;
-import com.google.cloud.firestore.DocumentSnapshot;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.stereotype.Component;
-
-import java.time.Instant;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.stream.Collectors;
-
-@Component
-public class FirestoreConversationMapper {
-
- private static final Logger logger = LoggerFactory.getLogger(FirestoreConversationMapper.class);
-
- public Map createUpdateMapForSingleEntry(ConversationEntryDTO newEntry) {
- Map updates = new HashMap<>();
- // Convert Instant to Firestore Timestamp
- Map entryMap = toFirestoreEntryMap(newEntry);
- updates.put("entries", FieldValue.arrayUnion(entryMap));
- // Convert Instant to Firestore Timestamp
- updates.put("lastModified", Timestamp.of(java.util.Date.from(Instant.now())));
- return updates;
- }
-
- public Map createNewSessionMapForSingleEntry(String sessionId, String userId, String telefono, ConversationEntryDTO initialEntry) {
- Map sessionMap = new HashMap<>();
- sessionMap.put("sessionId", sessionId);
- sessionMap.put("userId", userId);
-
- if (telefono != null && !telefono.trim().isEmpty()) {
- sessionMap.put("telefono", telefono);
- } else {
- sessionMap.put("telefono", null);
- }
-
- // Convert Instant to Firestore Timestamp
- sessionMap.put("createdAt", Timestamp.of(java.util.Date.from(Instant.now())));
- sessionMap.put("lastModified", Timestamp.of(java.util.Date.from(Instant.now())));
-
- List