From fa3dbee49afbf12968bf4d3ce1c57a01ede36d5f Mon Sep 17 00:00:00 2001 From: arys Date: Sun, 5 Apr 2026 19:46:00 +0500 Subject: [PATCH] target fix --- .../TargetingCampaignController.java | 26 ++++++++ .../service/MarketingStrategyService.java | 1 - .../service/MarketingStrategyV3Service.java | 61 +++++++++++++++++++ .../parser/service/PostingTaskService.java | 12 +++- 4 files changed, 96 insertions(+), 4 deletions(-) diff --git a/src/main/java/kz/konturai/parser/controller/TargetingCampaignController.java b/src/main/java/kz/konturai/parser/controller/TargetingCampaignController.java index bf4ecd5..e4df454 100644 --- a/src/main/java/kz/konturai/parser/controller/TargetingCampaignController.java +++ b/src/main/java/kz/konturai/parser/controller/TargetingCampaignController.java @@ -29,6 +29,7 @@ public class TargetingCampaignController { private final SocialMediaCredentialsService credentialsService; private final JwtService jwtService; private final CampaignPredictionService predictionService; + private final MarketingStrategyV3Service marketingStrategyV3Service; private String resolveUserId(String userIdHeader, String authHeader) { if (StringUtils.hasText(userIdHeader)) { @@ -288,6 +289,31 @@ public class TargetingCampaignController { return ResponseEntity.ok(campaignService.updateAudience(id, userId, audience)); } + // ── Direct Facebook Publish ────────────────────────────────────────────── + + @PostMapping("/strategy/{strategyId}/facebook/publish") + public ResponseEntity publishFirstFacebookPostFromStrategy( + @RequestHeader(value = "X-User-Id", required = false) String userIdHeader, + @RequestHeader(value = "Authorization", required = false) String authHeader, + @PathVariable String strategyId) { + String userId = resolveUserId(userIdHeader, authHeader); + log.info("[Targeting] Direct Facebook publish for strategy {} requested by {}", strategyId, userId); + + try { + String postId = marketingStrategyV3Service.publishFirstFacebookPost(strategyId); + return ResponseEntity.ok(Map.of( + "success", true, + "message", "Пост успешно опубликован в Facebook", + "postId", postId + )); + } catch (IllegalArgumentException | IllegalStateException e) { + return ResponseEntity.badRequest().body(Map.of("success", false, "error", e.getMessage())); + } catch (Exception e) { + log.error("Failed to publish post: ", e); + return ResponseEntity.internalServerError().body(Map.of("success", false, "error", "Не удалось опубликовать пост")); + } + } + // ── AdSets ─────────────────────────────────────────────────────────────── @GetMapping("/campaigns/{id}/adsets") diff --git a/src/main/java/kz/konturai/parser/service/MarketingStrategyService.java b/src/main/java/kz/konturai/parser/service/MarketingStrategyService.java index 2123bcc..336da6d 100644 --- a/src/main/java/kz/konturai/parser/service/MarketingStrategyService.java +++ b/src/main/java/kz/konturai/parser/service/MarketingStrategyService.java @@ -37,7 +37,6 @@ public class MarketingStrategyService { private final MarketingAnalysisRepository analysisRepository; private final MarketingAnalysisV2Repository v2Repository; private final OpenAIAnalyticsService openAIAnalyticsService; - private final ImageGenerationService imageGenerationService; private final MinIOService minIOService; private final PostingTaskService postingTaskService; private final ObjectMapper objectMapper = new ObjectMapper(); diff --git a/src/main/java/kz/konturai/parser/service/MarketingStrategyV3Service.java b/src/main/java/kz/konturai/parser/service/MarketingStrategyV3Service.java index 1add192..5a5eae3 100644 --- a/src/main/java/kz/konturai/parser/service/MarketingStrategyV3Service.java +++ b/src/main/java/kz/konturai/parser/service/MarketingStrategyV3Service.java @@ -40,6 +40,7 @@ public class MarketingStrategyV3Service { private final GeminiVideoGenerationService geminiVideoService; private final PostingTaskService postingTaskService; private final MinIOService minIOService; + private final FacebookPostingService facebookPostingService; @Autowired @Lazy private MarketingStrategyV3Service self; @@ -1185,4 +1186,64 @@ public class MarketingStrategyV3Service { repository.save(s); }); } + + // ===================================================================== + // FACEBOOK DIRECT PUBLISH + // ===================================================================== + + public String publishFirstFacebookPost(String strategyId) { + Optional optStrategy = repository.findById(strategyId); + if (optStrategy.isEmpty()) { + throw new IllegalArgumentException("Strategy not found: " + strategyId); + } + + MarketingStrategy strategy = optStrategy.get(); + if (strategy.getPostCalendar() == null || strategy.getPostCalendar().isEmpty()) { + throw new IllegalStateException("Strategy has no posts in calendar"); + } + + Optional fbPostOpt = strategy.getPostCalendar().stream() + .filter(item -> "facebook".equalsIgnoreCase(item.getPlatform())) + .findFirst(); + + if (fbPostOpt.isEmpty()) { + throw new IllegalStateException("No Facebook posts found in the strategy calendar"); + } + + MarketingStrategy.PostCalendarItem fbPost = fbPostOpt.get(); + + byte[] imageData = null; + if (fbPost.getImageFilename() != null && !fbPost.getImageFilename().isEmpty()) { + try { + java.io.InputStream imageStream = minIOService.downloadFile(fbPost.getImageFilename()); + imageData = imageStream.readAllBytes(); + } catch (Exception e) { + log.warn("Failed to load image for post: {}", e.getMessage()); + } + } + + String postId; + if (imageData != null && imageData.length > 0) { + postId = facebookPostingService.postToPageWithImage(fbPost.getPostText(), fbPost.getHashtags(), imageData); + } else { + postId = facebookPostingService.postToPage(fbPost.getPostText(), fbPost.getHashtags()); + } + + if (postId != null) { + try { + String reportText = "✅ НОВЫЙ ПОСТ ОПУБЛИКОВАН!\n\n" + + "📜 Текст поста:\n" + fbPost.getPostText() + "\n\n" + + "🔗 Ссылка: https://facebook.com/" + postId + "\n" + + "🕒 Время: " + LocalDateTime.now(); + facebookPostingService.sendPrivateMessage("25769470256007187", reportText); // TEST_RECIPIENT_ID + if (imageData != null && imageData.length > 0) { + facebookPostingService.sendPrivateImageMessage("25769470256007187", imageData); + } + } catch (Exception msgEx) { + log.warn("Post published but failed to send private notification: {}", msgEx.getMessage()); + } + } + + return postId; + } } \ No newline at end of file diff --git a/src/main/java/kz/konturai/parser/service/PostingTaskService.java b/src/main/java/kz/konturai/parser/service/PostingTaskService.java index c2931e3..ae1dee3 100644 --- a/src/main/java/kz/konturai/parser/service/PostingTaskService.java +++ b/src/main/java/kz/konturai/parser/service/PostingTaskService.java @@ -56,6 +56,9 @@ public class PostingTaskService { .toList(); for (String platform : platforms) { + if ("facebook".equalsIgnoreCase(platform)) { + continue; // Игнорируем проверку БД, так как Facebook берет ключи из application.properties + } if (!credentialsService.hasCredentials(strategy.getUserId(), platform)) { throw new IllegalStateException( "Credentials not found for platform: " + platform + ". Please configure credentials first."); @@ -126,9 +129,12 @@ public class PostingTaskService { taskRepository.save(task); try { - String credentials = credentialsService.getCredentials(task.getUserId(), task.getPlatform()); - if (credentials == null || credentials.isEmpty()) { - throw new IllegalStateException("Credentials not found for platform: " + task.getPlatform()); + String credentials = null; + if (!"facebook".equalsIgnoreCase(task.getPlatform())) { + credentials = credentialsService.getCredentials(task.getUserId(), task.getPlatform()); + if (credentials == null || credentials.isEmpty()) { + throw new IllegalStateException("Credentials not found for platform: " + task.getPlatform()); + } } byte[] imageData = null;