Skip to content

Commit

Permalink
(#411) notifications: update comment service external events and even…
Browse files Browse the repository at this point in the history
…ts handlers
  • Loading branch information
SaintAngeLs committed Sep 15, 2024
1 parent f84de45 commit 4b62d33
Showing 11 changed files with 171 additions and 53 deletions.
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using MiniSpace.Services.Notifications.Core.Entities;
using MiniSpace.Services.Notifications.Application.Dto.Comments;

namespace MiniSpace.Services.Notifications.Application.Dto
namespace MiniSpace.Services.Notifications.Application.Dto.Comments
{
public class CommentDto
{
public Guid Id { get; set; }
public Guid ContextId { get; set; }
public string CommentContext { get; set; }
public Guid StudentId { get; set; }
public string StudentName { get; set; }
public Guid UserId { get; set; }
public IEnumerable<Guid> Likes { get; set; }
public Guid ParentId { get; set; }
public string TextContent { get; set; }
@@ -21,5 +19,10 @@ public class CommentDto
public DateTime LastReplyAt { get; set; }
public int RepliesCount { get; set; }
public bool IsDeleted { get; set; }
public IEnumerable<ReplyDto> Replies { get; set; }

public CommentDto()
{
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace MiniSpace.Services.Notifications.Application.Dto.Comments
{
public class ReplyDto
{
public Guid Id { get; set; }
public Guid UserId { get; set; }
public Guid CommentId { get; set; }
public string TextContent { get; set; }
public DateTime CreatedAt { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -17,10 +17,13 @@ public class CommentCreated : IEvent
public DateTime LastUpdatedAt { get; }
public int RepliesCount { get; }
public bool IsDeleted { get; }
public string UserName { get; }
public string ProfileImageUrl { get; }

public CommentCreated(Guid commentId, Guid contextId, string commentContext, Guid userId,
Guid parentId, string textContent, DateTime createdAt,
DateTime lastUpdatedAt, int repliesCount, bool isDeleted)
DateTime lastUpdatedAt, int repliesCount, bool isDeleted,
string userName, string profileImageUrl)
{
CommentId = commentId;
ContextId = contextId;
@@ -32,6 +35,8 @@ public CommentCreated(Guid commentId, Guid contextId, string commentContext, Gui
LastUpdatedAt = lastUpdatedAt;
RepliesCount = repliesCount;
IsDeleted = isDeleted;
UserName = userName;
ProfileImageUrl = profileImageUrl;
}
}
}
Original file line number Diff line number Diff line change
@@ -12,14 +12,19 @@ public class CommentUpdated : IEvent
public string CommentContext { get; }
public DateTime UpdatedAt { get; }
public string CommentContent { get; }
public string UserName { get; }
public string ProfileImageUrl { get; }

public CommentUpdated(Guid commentId, Guid userId, string commentContext, DateTime updatedAt, string commentContent)
public CommentUpdated(Guid commentId, Guid userId, string commentContext,
DateTime updatedAt, string commentContent, string userName, string profileImageUrl)
{
CommentId = commentId;
UserId = userId;
CommentContext = commentContext;
UpdatedAt = updatedAt;
CommentContent = commentContent;
UserName = userName;
ProfileImageUrl = profileImageUrl;
}
}
}
Original file line number Diff line number Diff line change
@@ -45,22 +45,11 @@ public async Task HandleAsync(CommentCreated @event, CancellationToken cancellat
{
try
{
// Fetch comment details from the comment service
var commentDetails = await _commentsServiceClient.GetCommentAsync(@event.CommentId);
if (commentDetails == null)
{
_logger.LogError("No comment details found for CommentCreated event.");
return;
}

// Initialize entity owner and name variables
var entityOwnerId = Guid.Empty;
string entityName = string.Empty;

// Check if it's an event or post
if (@event.CommentContext.Equals("OrganizationEvent", StringComparison.OrdinalIgnoreCase))
{
// Fetch organization event details
var organizationEvent = await _eventsServiceClient.GetEventAsync(@event.ContextId);
if (organizationEvent != null)
{
@@ -72,8 +61,7 @@ public async Task HandleAsync(CommentCreated @event, CancellationToken cancellat
}
else if (@event.CommentContext.Equals("OrganizationPost", StringComparison.OrdinalIgnoreCase))
{
// Fetch organization post details
var organizationPost = await _postsServiceClient.GetPostAsync(@event.ContextId);
var organizationPost = await _postsServiceClient.GetPostAsync(@event.ContextId);
if (organizationPost != null)
{
entityOwnerId = organizationPost.UserId.HasValue ? organizationPost.UserId.Value : Guid.Empty;
@@ -82,7 +70,6 @@ public async Task HandleAsync(CommentCreated @event, CancellationToken cancellat
}
else if (@event.CommentContext.Equals("UserEvent", StringComparison.OrdinalIgnoreCase))
{
// Fetch user event details
var userEvent = await _eventsServiceClient.GetEventAsync(@event.ContextId);
if (userEvent != null)
{
@@ -92,7 +79,6 @@ public async Task HandleAsync(CommentCreated @event, CancellationToken cancellat
}
else if (@event.CommentContext.Equals("UserPost", StringComparison.OrdinalIgnoreCase))
{
// Fetch user post details
var userPost = await _postsServiceClient.GetPostAsync(@event.ContextId);
if (userPost != null)
{
@@ -112,11 +98,12 @@ public async Task HandleAsync(CommentCreated @event, CancellationToken cancellat
return;
}

// Notify the entity owner (user or organization)
var notificationMessage = $"A new comment has been made on '{entityName}' by {@event.UserName}. <img src='{@event.ProfileImageUrl}' alt='Profile Image' style='width:50px;height:50px;' />";

var notification = new Notification(
notificationId: Guid.NewGuid(),
userId: entityOwnerId,
message: $"A new comment has been made on '{entityName}' by {commentDetails.StudentName}.",
message: notificationMessage,
status: NotificationStatus.Unread,
createdAt: DateTime.UtcNow,
updatedAt: null,
@@ -130,15 +117,14 @@ public async Task HandleAsync(CommentCreated @event, CancellationToken cancellat
userNotifications.AddNotification(notification);
await _userNotificationsRepository.AddOrUpdateAsync(userNotifications);

// Broadcast notification via SignalR
var notificationDto = new NotificationDto
{
UserId = entityOwnerId,
Message = notification.Message,
Message = notificationMessage,
CreatedAt = notification.CreatedAt,
EventType = NotificationEventType.CommentCreated,
RelatedEntityId = @event.CommentId,
Details = $"<p>A new comment was made on '{entityName}'.</p>"
Details = $"<p>{@event.UserName} commented: '{@event.TextContent}' on '{entityName}'.</p><img src='{@event.ProfileImageUrl}' alt='Profile Image' style='width:50px;height:50px;' />"
};

await NotificationHub.BroadcastNotification(_hubContext, notificationDto, _logger);
Original file line number Diff line number Diff line change
@@ -12,6 +12,7 @@
using MiniSpace.Services.Notifications.Application.Dto;
using MiniSpace.Services.Notifications.Application.Events.External.Comments;
using MiniSpace.Services.Notifications.Application.Dto.Events;
using MiniSpace.Services.Notifications.Application.Dto.Comments;

namespace MiniSpace.Services.Notifications.Application.Events.External.Handlers
{
@@ -77,15 +78,16 @@ public async Task HandleAsync(CommentUpdated eventArgs, CancellationToken cancel
throw;
}

var studentNotifications = await _studentNotificationsRepository.GetByUserIdAsync(commentDetails.StudentId);
var studentNotifications = await _studentNotificationsRepository.GetByUserIdAsync(commentDetails.UserId);
if (studentNotifications == null)
{
studentNotifications = new UserNotifications(commentDetails.StudentId);
studentNotifications = new UserNotifications(commentDetails.UserId);
}

// Create notification for the user who updated the comment
var userNotification = new Notification(
notificationId: Guid.NewGuid(),
userId: commentDetails.StudentId,
userId: commentDetails.UserId,
message: $"Your updated comment on the event '{eventDetails.Name}' has been processed.",
status: NotificationStatus.Unread,
createdAt: DateTime.UtcNow,
@@ -114,7 +116,7 @@ public async Task HandleAsync(CommentUpdated eventArgs, CancellationToken cancel
// Broadcast the updated notification via SignalR
var notificationDto = new NotificationDto
{
UserId = commentDetails.StudentId,
UserId = commentDetails.UserId,
Message = userNotification.Message,
CreatedAt = userNotification.CreatedAt,
EventType = NotificationEventType.CommentUpdated,
@@ -123,18 +125,20 @@ public async Task HandleAsync(CommentUpdated eventArgs, CancellationToken cancel
};

await NotificationHub.BroadcastNotification(_hubContext, notificationDto, _logger);
_logger.LogInformation("Broadcasted SignalR notification to all users.");
_logger.LogInformation("Broadcasted SignalR notification to the user.");

// Organizer notification
var organizerNotifications = await _studentNotificationsRepository.GetByUserIdAsync(eventDetails.Organizer.Id);
if (organizerNotifications == null)
{
organizerNotifications = new UserNotifications(eventDetails.Organizer.Id);
}

// Create notification for the organizer
var organizerNotification = new Notification(
notificationId: Guid.NewGuid(),
userId: eventDetails.Organizer.Id,
message: $"{commentDetails.StudentName} has updated their comment on your event '{eventDetails.Name}'.",
message: $"{eventArgs.UserName} has updated their comment on your event '{eventDetails.Name}'.",
status: NotificationStatus.Unread,
createdAt: DateTime.UtcNow,
updatedAt: DateTime.UtcNow,
@@ -145,13 +149,14 @@ public async Task HandleAsync(CommentUpdated eventArgs, CancellationToken cancel
organizerNotifications.AddNotification(organizerNotification);
await _studentNotificationsRepository.AddOrUpdateAsync(organizerNotifications);

// Prepare and send organizer notification details HTML
var organizerNotificationDetailsHtml = $"<p>{commentDetails.StudentName} updated their comment on your event '{eventDetails.Name}': {commentDetails.CommentContext}</p>";
// Prepare and send organizer notification details HTML, including profile image
var organizerNotificationDetailsHtml = $"<p>{eventArgs.UserName} updated their comment on your event '{eventDetails.Name}': {eventArgs.CommentContent}.</p>" +
$"<img src='{eventArgs.ProfileImageUrl}' alt='Profile Image' style='width:50px;height:50px;' />";

var organizerNotificationUpdatedEvent = new NotificationCreated(
notificationId: Guid.NewGuid(),
userId: eventDetails.Organizer.Id,
message: $"{commentDetails.StudentName} has updated their comment on your event '{eventDetails.Name}'.",
message: $"{eventArgs.UserName} has updated their comment on your event '{eventDetails.Name}'.",
createdAt: DateTime.UtcNow,
eventType: NotificationEventType.CommentUpdated.ToString(),
relatedEntityId: eventArgs.CommentId,
@@ -171,7 +176,7 @@ public async Task HandleAsync(CommentUpdated eventArgs, CancellationToken cancel
};

await NotificationHub.BroadcastNotification(_hubContext, organizerNotificationDto, _logger);
_logger.LogInformation("Broadcasted SignalR notification to all users.");
_logger.LogInformation("Broadcasted SignalR notification to the event organizer.");
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
using System;
using System.Threading;
using System.Threading.Tasks;
using Convey.CQRS.Events;
using MiniSpace.Services.Notifications.Core.Repositories;
using MiniSpace.Services.Notifications.Application.Services.Clients;
using Microsoft.Extensions.Logging;
using MiniSpace.Services.Notifications.Application.Hubs;
using MiniSpace.Services.Notifications.Application.Dto;
using Microsoft.AspNetCore.SignalR;
using MiniSpace.Services.Notifications.Core.Entities;

namespace MiniSpace.Services.Notifications.Application.Events.External.Comments.Handlers
{
public class LikeAddedHandler : IEventHandler<LikeAdded>
{
private readonly ICommentsServiceClient _commentsServiceClient;
private readonly IPostsServiceClient _postsServiceClient;
private readonly IUserNotificationsRepository _userNotificationsRepository;
private readonly ILogger<LikeAddedHandler> _logger;
private readonly IHubContext<NotificationHub> _hubContext;

public LikeAddedHandler(
ICommentsServiceClient commentsServiceClient,
IPostsServiceClient postsServiceClient,
IUserNotificationsRepository userNotificationsRepository,
ILogger<LikeAddedHandler> logger,
IHubContext<NotificationHub> hubContext)
{
_commentsServiceClient = commentsServiceClient;
_postsServiceClient = postsServiceClient;
_userNotificationsRepository = userNotificationsRepository;
_logger = logger;
_hubContext = hubContext;
}

public async Task HandleAsync(LikeAdded @event, CancellationToken cancellationToken = default)
{
try
{
var commentDetails = await _commentsServiceClient.GetCommentAsync(@event.CommentId);
if (commentDetails == null)
{
_logger.LogError($"No comment details found for LikeAdded event. CommentId: {@event.CommentId}");
return;
}

var entityOwnerId = commentDetails.UserId;
var entityName = commentDetails.TextContent;

var notification = new Notification(
notificationId: Guid.NewGuid(),
userId: entityOwnerId,
message: $"{@event.UserName} liked your comment '{entityName}'.",
status: NotificationStatus.Unread,
createdAt: DateTime.UtcNow,
updatedAt: null,
relatedEntityId: @event.CommentId,
eventType: NotificationEventType.CommentLikeAdded
);

var userNotifications = await _userNotificationsRepository.GetByUserIdAsync(entityOwnerId)
?? new UserNotifications(entityOwnerId);

userNotifications.AddNotification(notification);
await _userNotificationsRepository.AddOrUpdateAsync(userNotifications);

var notificationDetails = $"<p>{@event.UserName} liked your comment: '{@event.CommentContext}'.</p>" +
$"<img src='{@event.ProfileImageUrl}' alt='Profile Image' style='width:50px;height:50px;' />";

var notificationDto = new NotificationDto
{
UserId = entityOwnerId,
Message = notification.Message,
CreatedAt = notification.CreatedAt,
EventType = NotificationEventType.CommentLikeAdded,
RelatedEntityId = @event.CommentId,
Details = notificationDetails
};

await NotificationHub.BroadcastNotification(_hubContext, notificationDto, _logger);
}
catch (Exception ex)
{
_logger.LogError($"Failed to handle LikeAdded event: {ex.Message}");
}
}
}
}
Original file line number Diff line number Diff line change
@@ -11,13 +11,18 @@ public class LikeAdded : IEvent
public Guid UserId { get; }
public string CommentContext { get; }
public DateTime LikedAt { get; }
public string UserName { get; }
public string ProfileImageUrl { get; }

public LikeAdded(Guid commentId, Guid userId, string commentContext, DateTime likedAt)
public LikeAdded(Guid commentId, Guid userId, string commentContext,
DateTime likedAt, string userName, string profileImageUrl)
{
CommentId = commentId;
UserId = userId;
CommentContext = commentContext;
LikedAt = likedAt;
UserName = userName;
ProfileImageUrl = profileImageUrl;
}
}
}
Loading

0 comments on commit 4b62d33

Please sign in to comment.