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"
|
DeliveryChannelInApp DeliveryChannel = "in_app"
|
||||||
)
|
)
|
||||||
|
|
||||||
// EventTypeInApp identifies notifications stored for the in-app notification center.
|
// Persisted event types for stored notifications (admin list / notification center).
|
||||||
const EventTypeInApp = "in_app"
|
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
|
// DeliveryStatus represents the delivery status of notification
|
||||||
type NotificationStatus string
|
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) {
|
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{}{
|
s.logger.Error("Failed to persist in-app notification", map[string]interface{}{
|
||||||
"error": err.Error(),
|
"error": err.Error(),
|
||||||
"user_id": recipient.UserID,
|
"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{
|
metadata := map[string]any{
|
||||||
"tender": strings.TrimSpace(req.Tender),
|
"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 {
|
func (s *notificationService) persistNotification(ctx context.Context, recipient notificationRecipient, req *NotificationRequest, link, image string, channel DeliveryChannel) error {
|
||||||
methods := map[string]string{
|
eventType, ok := persistedEventType(channel)
|
||||||
"in_app": "true",
|
if !ok {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
methods := map[string]string{}
|
||||||
|
switch channel {
|
||||||
|
case DeliveryChannelEmail:
|
||||||
|
if recipient.Email == "" {
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
if slices.Contains(req.Channels, DeliveryChannelEmail) && recipient.Email != "" {
|
|
||||||
methods["email"] = recipient.Email
|
methods["email"] = recipient.Email
|
||||||
|
case DeliveryChannelPush:
|
||||||
|
if len(recipient.DeviceTokens) == 0 {
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
if slices.Contains(req.Channels, DeliveryChannelPush) && len(recipient.DeviceTokens) > 0 {
|
|
||||||
methods["push"] = recipient.DeviceTokens[0]
|
methods["push"] = recipient.DeviceTokens[0]
|
||||||
|
case DeliveryChannelInApp:
|
||||||
|
methods["in_app"] = "true"
|
||||||
}
|
}
|
||||||
|
|
||||||
status := string(DeliveryStatusSent)
|
status := string(DeliveryStatusSent)
|
||||||
@@ -173,7 +198,7 @@ func (s *notificationService) persistNotification(ctx context.Context, recipient
|
|||||||
Image: image,
|
Image: image,
|
||||||
Priority: string(req.Priority),
|
Priority: string(req.Priority),
|
||||||
Type: string(req.Type),
|
Type: string(req.Type),
|
||||||
EventType: EventTypeInApp,
|
EventType: eventType,
|
||||||
Status: status,
|
Status: status,
|
||||||
Methods: methods,
|
Methods: methods,
|
||||||
Metadata: map[string]any{
|
Metadata: map[string]any{
|
||||||
|
|||||||
Reference in New Issue
Block a user