feat: sending notifications on invites creation

This commit is contained in:
sBubshait 2025-08-05 11:17:46 +03:00
parent 339f7e1762
commit b2b4723bf0
3 changed files with 95 additions and 0 deletions

View File

@ -2,8 +2,11 @@ package online.wesal.wesal.repository;
import online.wesal.wesal.entity.User; import online.wesal.wesal.entity.User;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository; import org.springframework.stereotype.Repository;
import java.util.List;
import java.util.Optional; import java.util.Optional;
@Repository @Repository
@ -12,4 +15,7 @@ public interface UserRepository extends JpaRepository<User, Long> {
Optional<User> findByUsername(String username); Optional<User> findByUsername(String username);
boolean existsByEmail(String email); boolean existsByEmail(String email);
boolean existsByUsername(String username); boolean existsByUsername(String username);
@Query("SELECT u FROM User u WHERE u.subscriptions LIKE %:subscription% AND u.fcmToken IS NOT NULL AND u.fcmToken != ''")
List<User> findUsersSubscribedTo(@Param("subscription") String subscription);
} }

View File

@ -38,6 +38,9 @@ public class InvitationService {
@Autowired @Autowired
private FCMNotificationService fcmNotificationService; private FCMNotificationService fcmNotificationService;
@Autowired
private SubscriptionNotificationService subscriptionNotificationService;
@Transactional @Transactional
public InvitationResponse createInvitation(CreateInvitationRequest request, String userEmail) { public InvitationResponse createInvitation(CreateInvitationRequest request, String userEmail) {
User creator = userRepository.findByEmail(userEmail) User creator = userRepository.findByEmail(userEmail)
@ -58,6 +61,15 @@ public class InvitationService {
invitation.setLocation(request.getLocation()); invitation.setLocation(request.getLocation());
Invitation saved = invitationRepository.save(invitation); Invitation saved = invitationRepository.save(invitation);
// Send notification to users subscribed to "newinvites"
String title = "New Invitation! \uD83C\uDF89";
String body = String.format("%s is looking for people to join them for %s: %s",
creator.getDisplayName(),
tag.getName(),
saved.getTitle());
subscriptionNotificationService.sendNotificationToSubscription("newinvites", title, body);
return mapToResponse(saved); return mapToResponse(saved);
} }

View File

@ -0,0 +1,77 @@
package online.wesal.wesal.service;
import com.google.firebase.messaging.FirebaseMessaging;
import com.google.firebase.messaging.MulticastMessage;
import com.google.firebase.messaging.Notification;
import com.google.firebase.messaging.BatchResponse;
import online.wesal.wesal.entity.User;
import online.wesal.wesal.repository.UserRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.stream.Collectors;
@Service
public class SubscriptionNotificationService {
private static final Logger logger = LoggerFactory.getLogger(SubscriptionNotificationService.class);
@Autowired
private UserRepository userRepository;
@Async
public void sendNotificationToSubscription(String subscriptionName, String title, String body) {
try {
// Get all users subscribed to the given subscription
List<User> subscribedUsers = userRepository.findUsersSubscribedTo(subscriptionName);
if (subscribedUsers.isEmpty()) {
logger.info("No users found subscribed to '{}'", subscriptionName);
return;
}
// Extract FCM tokens from subscribed users
List<String> tokens = subscribedUsers.stream()
.map(User::getFcmToken)
.filter(token -> token != null && !token.trim().isEmpty())
.collect(Collectors.toList());
if (tokens.isEmpty()) {
logger.warn("No valid FCM tokens found for subscription '{}'", subscriptionName);
return;
}
// Create multicast message
MulticastMessage message = MulticastMessage.builder()
.setNotification(Notification.builder()
.setTitle(title)
.setBody(body)
.build())
.addAllTokens(tokens)
.build();
// Send the multicast message
BatchResponse response = FirebaseMessaging.getInstance().sendEachForMulticast(message);
logger.info("Successfully sent notifications for subscription '{}': {} successful, {} failed",
subscriptionName, response.getSuccessCount(), response.getFailureCount());
// Log any failures for debugging
if (response.getFailureCount() > 0) {
for (int i = 0; i < response.getResponses().size(); i++) {
if (!response.getResponses().get(i).isSuccessful()) {
logger.error("Failed to send notification to token {}: {}",
tokens.get(i), response.getResponses().get(i).getException().getMessage());
}
}
}
} catch (Exception e) {
logger.error("Failed to send notifications for subscription '{}': {}", subscriptionName, e.getMessage(), e);
}
}
}