diff --git a/pom.xml b/pom.xml
index b989bd1..f426642 100644
--- a/pom.xml
+++ b/pom.xml
@@ -114,6 +114,12 @@
jackson-databind
+
+
+ com.fasterxml.jackson.datatype
+ jackson-datatype-jsr310
+
+
org.apache.xmlgraphics
batik-codec
diff --git a/src/main/java/kz/konturai/parser/config/MongoConfig.java b/src/main/java/kz/konturai/parser/config/MongoConfig.java
index 2e5ace0..fa5951d 100644
--- a/src/main/java/kz/konturai/parser/config/MongoConfig.java
+++ b/src/main/java/kz/konturai/parser/config/MongoConfig.java
@@ -2,6 +2,7 @@ package kz.konturai.parser.config;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import org.bson.Document;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -21,7 +22,8 @@ import java.util.Map;
public class MongoConfig {
private static final Logger logger = LoggerFactory.getLogger(MongoConfig.class);
- private static final ObjectMapper objectMapper = new ObjectMapper();
+ private static final ObjectMapper objectMapper = new ObjectMapper()
+ .registerModule(new JavaTimeModule());
@Bean
public MongoCustomConversions customConversions() {
diff --git a/src/main/java/kz/konturai/parser/service/MarketingStrategyService.java b/src/main/java/kz/konturai/parser/service/MarketingStrategyService.java
index c1983f7..7aa6e1e 100644
--- a/src/main/java/kz/konturai/parser/service/MarketingStrategyService.java
+++ b/src/main/java/kz/konturai/parser/service/MarketingStrategyService.java
@@ -13,6 +13,7 @@ import kz.konturai.parser.repository.MarketingAnalysisRepository;
import kz.konturai.parser.repository.MarketingStrategyRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
@@ -36,6 +37,9 @@ public class MarketingStrategyService {
private final PostingTaskService postingTaskService;
private final ObjectMapper objectMapper = new ObjectMapper();
+ @Value("${image.generation.delayBetweenRequestsMs:3000}")
+ private long delayBetweenRequestsMs;
+
public MarketingStrategyService(
MarketingStrategyRepository repository,
MarketingAnalysisService marketingAnalysisService,
@@ -432,6 +436,17 @@ public class MarketingStrategyService {
// Generate image for the post
generateAndSaveImageForPost(item, businessContext);
+ // Add delay between image generation requests to avoid rate limiting
+ // This helps prevent 429 errors from Gemini API
+ if (delayBetweenRequestsMs > 0) {
+ try {
+ Thread.sleep(delayBetweenRequestsMs);
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ logger.warn("Image generation delay interrupted");
+ }
+ }
+
calendar.add(item);
}
diff --git a/src/main/java/kz/konturai/parser/service/NanoBananaImageGenerationService.java b/src/main/java/kz/konturai/parser/service/NanoBananaImageGenerationService.java
index 3c26489..e893d61 100644
--- a/src/main/java/kz/konturai/parser/service/NanoBananaImageGenerationService.java
+++ b/src/main/java/kz/konturai/parser/service/NanoBananaImageGenerationService.java
@@ -50,11 +50,15 @@ public class NanoBananaImageGenerationService implements ImageGenerationService
@Value("${google.gemini.retry.multiplier:2.0}")
private double retryMultiplier;
+ @Value("${google.gemini.rateLimit.delayMs:2000}")
+ private long rateLimitDelayMs;
+
public NanoBananaImageGenerationService() {
HttpClient httpClient = HttpClient.create()
.responseTimeout(Duration.ofMillis(90000));
- // Configure exchange strategies to increase buffer limit for large base64 responses
+ // Configure exchange strategies to increase buffer limit for large base64
+ // responses
ExchangeStrategies strategies = ExchangeStrategies.builder()
.codecs(configurer -> configurer.defaultCodecs().maxInMemorySize(10 * 1024 * 1024)) // 10 MB
.build();
@@ -164,16 +168,16 @@ public class NanoBananaImageGenerationService implements ImageGenerationService
try {
// Структура ответа Gemini API:
// {
- // "candidates": [{
- // "content": {
- // "parts": [{
- // "inlineData": {
- // "mimeType": "image/png",
- // "data": "base64_encoded_image_data"
- // }
- // }]
- // }
- // }]
+ // "candidates": [{
+ // "content": {
+ // "parts": [{
+ // "inlineData": {
+ // "mimeType": "image/png",
+ // "data": "base64_encoded_image_data"
+ // }
+ // }]
+ // }
+ // }]
// }
List