Merge pull request 'Refactor notification service to support multiple delivery channels' (#48) from notif-channel into develop
Reviewed-on: https://repo.ravanertebat.com/TM/tm_back/pulls/48
This commit is contained in:
@@ -28,8 +28,26 @@ const (
|
||||
DeliveryChannelInApp DeliveryChannel = "in_app"
|
||||
)
|
||||
|
||||
// EventTypeInApp identifies notifications stored for the in-app notification center.
|
||||
const EventTypeInApp = "in_app"
|
||||
// Persisted event types for stored notifications (admin list / notification center).
|
||||
const (
|
||||
EventTypeInApp = "in_app"
|
||||
EventTypeEmail = "email"
|
||||
EventTypePush = "push"
|
||||
)
|
||||
|
||||
// persistedEventType maps a delivery channel to the event_type stored in MongoDB.
|
||||
func persistedEventType(channel DeliveryChannel) (string, bool) {
|
||||
switch channel {
|
||||
case DeliveryChannelEmail:
|
||||
return EventTypeEmail, true
|
||||
case DeliveryChannelPush:
|
||||
return EventTypePush, true
|
||||
case DeliveryChannelInApp:
|
||||
return EventTypeInApp, true
|
||||
default:
|
||||
return "", false
|
||||
}
|
||||
}
|
||||
|
||||
// DeliveryStatus represents the delivery status of notification
|
||||
type NotificationStatus string
|
||||
|
||||
@@ -99,13 +99,27 @@ func (s *notificationService) Send(ctx context.Context, req *NotificationRequest
|
||||
}
|
||||
|
||||
func (s *notificationService) sendToRecipient(ctx context.Context, recipient notificationRecipient, req *NotificationRequest, link, image string) {
|
||||
if err := s.persistNotification(ctx, recipient, req, link, image); err != nil {
|
||||
// Always persist an in-app record so every send appears in the notification center.
|
||||
if err := s.persistNotification(ctx, recipient, req, link, image, DeliveryChannelInApp); err != nil {
|
||||
s.logger.Error("Failed to persist in-app notification", map[string]interface{}{
|
||||
"error": err.Error(),
|
||||
"user_id": recipient.UserID,
|
||||
})
|
||||
}
|
||||
|
||||
for _, channel := range req.Channels {
|
||||
if channel == DeliveryChannelInApp {
|
||||
continue
|
||||
}
|
||||
if err := s.persistNotification(ctx, recipient, req, link, image, channel); err != nil {
|
||||
s.logger.Error("Failed to persist notification", map[string]interface{}{
|
||||
"error": err.Error(),
|
||||
"user_id": recipient.UserID,
|
||||
"channel": channel,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
metadata := map[string]any{
|
||||
"tender": strings.TrimSpace(req.Tender),
|
||||
}
|
||||
@@ -149,15 +163,26 @@ func (s *notificationService) sendToRecipient(ctx context.Context, recipient not
|
||||
}
|
||||
}
|
||||
|
||||
func (s *notificationService) persistNotification(ctx context.Context, recipient notificationRecipient, req *NotificationRequest, link, image string) error {
|
||||
methods := map[string]string{
|
||||
"in_app": "true",
|
||||
func (s *notificationService) persistNotification(ctx context.Context, recipient notificationRecipient, req *NotificationRequest, link, image string, channel DeliveryChannel) error {
|
||||
eventType, ok := persistedEventType(channel)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
if slices.Contains(req.Channels, DeliveryChannelEmail) && recipient.Email != "" {
|
||||
|
||||
methods := map[string]string{}
|
||||
switch channel {
|
||||
case DeliveryChannelEmail:
|
||||
if recipient.Email == "" {
|
||||
return nil
|
||||
}
|
||||
methods["email"] = recipient.Email
|
||||
}
|
||||
if slices.Contains(req.Channels, DeliveryChannelPush) && len(recipient.DeviceTokens) > 0 {
|
||||
case DeliveryChannelPush:
|
||||
if len(recipient.DeviceTokens) == 0 {
|
||||
return nil
|
||||
}
|
||||
methods["push"] = recipient.DeviceTokens[0]
|
||||
case DeliveryChannelInApp:
|
||||
methods["in_app"] = "true"
|
||||
}
|
||||
|
||||
status := string(DeliveryStatusSent)
|
||||
@@ -173,7 +198,7 @@ func (s *notificationService) persistNotification(ctx context.Context, recipient
|
||||
Image: image,
|
||||
Priority: string(req.Priority),
|
||||
Type: string(req.Type),
|
||||
EventType: EventTypeInApp,
|
||||
EventType: eventType,
|
||||
Status: status,
|
||||
Methods: methods,
|
||||
Metadata: map[string]any{
|
||||
|
||||
Reference in New Issue
Block a user