diff --git a/internal/services/messenger/email.go b/internal/services/messenger/email.go index ddb3542..a99d2fe 100644 --- a/internal/services/messenger/email.go +++ b/internal/services/messenger/email.go @@ -3,10 +3,9 @@ package messenger import ( "context" "github.com/resend/resend-go/v2" - ) -func (s *Service) SendEmail(ctx context.Context, receiverEmail, message string, subject string) error { +func (s *Service) SendEmail(ctx context.Context, receiverEmail, message string, messageHTML string, subject string) error { apiKey := s.config.ResendApiKey client := resend.NewClient(apiKey) formattedSenderEmail := "FortuneBets <" + s.config.ResendSenderEmail + ">" @@ -15,6 +14,7 @@ func (s *Service) SendEmail(ctx context.Context, receiverEmail, message string, To: []string{receiverEmail}, Subject: subject, Text: message, + Html: messageHTML, } _, err := client.Emails.Send(params) diff --git a/internal/services/notification/service.go b/internal/services/notification/service.go index 76531db..6ba4044 100644 --- a/internal/services/notification/service.go +++ b/internal/services/notification/service.go @@ -300,7 +300,7 @@ func (s *Service) handleNotification(notification *domain.Notification) { } case domain.DeliveryChannelEmail: - err := s.SendNotificationEmail(ctx, notification.RecipientID, notification.Payload.Headline, notification.Payload.Message) + err := s.SendNotificationEmail(ctx, notification.RecipientID, notification.Payload.Message, notification.Payload.Headline) if err != nil { notification.DeliveryStatus = domain.DeliveryStatusFailed } else { @@ -371,7 +371,7 @@ func (s *Service) SendNotificationEmail(ctx context.Context, recipientID int64, if user.Email == "" { return fmt.Errorf("email is invalid") } - err = s.messengerSvc.SendEmail(ctx, user.Email, message, subject) + err = s.messengerSvc.SendEmail(ctx, user.Email, message, message, subject) if err != nil { s.mongoLogger.Error("[NotificationSvc.HandleNotification] Failed to send notification SMS", zap.Int64("recipient_id", recipientID), @@ -440,7 +440,7 @@ func (s *Service) retryFailedNotifications() { return } case domain.DeliveryChannelEmail: - if err := s.SendNotificationEmail(ctx, notification.RecipientID, notification.Payload.Headline, notification.Payload.Message); err == nil { + if err := s.SendNotificationEmail(ctx, notification.RecipientID, notification.Payload.Message, notification.Payload.Headline); err == nil { notification.DeliveryStatus = domain.DeliveryStatusSent if _, err := s.repo.UpdateNotificationStatus(ctx, notification.ID, string(notification.DeliveryStatus), notification.IsRead, notification.Metadata); err != nil { s.mongoLogger.Error("[NotificationSvc.RetryFailedNotifications] Failed to update after retry", diff --git a/internal/services/result/service.go b/internal/services/result/service.go index a872924..c8e69b9 100644 --- a/internal/services/result/service.go +++ b/internal/services/result/service.go @@ -16,6 +16,7 @@ import ( "github.com/SamuelTariku/FortuneBet-Backend/internal/services/bet" "github.com/SamuelTariku/FortuneBet-Backend/internal/services/event" "github.com/SamuelTariku/FortuneBet-Backend/internal/services/league" + "github.com/SamuelTariku/FortuneBet-Backend/internal/services/messenger" notificationservice "github.com/SamuelTariku/FortuneBet-Backend/internal/services/notification" "github.com/SamuelTariku/FortuneBet-Backend/internal/services/odds" "github.com/SamuelTariku/FortuneBet-Backend/internal/services/user" @@ -33,6 +34,7 @@ type Service struct { eventSvc event.Service leagueSvc league.Service notificationSvc *notificationservice.Service + messengerSvc *messenger.Service userSvc user.Service } @@ -46,6 +48,7 @@ func NewService( eventSvc event.Service, leagueSvc league.Service, notificationSvc *notificationservice.Service, + messengerSvc *messenger.Service, userSvc user.Service, ) *Service { return &Service{ @@ -59,6 +62,7 @@ func NewService( eventSvc: eventSvc, leagueSvc: leagueSvc, notificationSvc: notificationSvc, + messengerSvc: messengerSvc, userSvc: userSvc, } } @@ -491,6 +495,7 @@ func (s *Service) CheckAndSendResultNotifications(ctx context.Context, createdAf } func buildHeadlineAndMessage(counts domain.ResultLog) (string, string) { + totalIssues := counts.StatusNotFinishedCount + counts.StatusToBeFixedCount + counts.StatusPostponedCount + counts.StatusRemovedCount totalBets := counts.StatusEndedBets + counts.StatusNotFinishedBets + counts.StatusPostponedBets + counts.StatusRemovedBets + counts.StatusToBeFixedBets if totalIssues == 0 { @@ -517,10 +522,124 @@ func buildHeadlineAndMessage(counts domain.ResultLog) (string, string) { } headline := "⚠️ Issues Found Processing Event Results" - message := fmt.Sprintf("Processed expired event results: %s. Please review pending entries.", strings.Join(parts, ", ")) + message := fmt.Sprintf("Processed expired event results: %s. Please review pending entries.", strings.Join(parts, ", ")) return headline, message } +func buildHeadlineAndMessageEmail(counts domain.ResultLog, user domain.User) (string, string, string) { + totalIssues := counts.StatusNotFinishedCount + counts.StatusToBeFixedCount + + counts.StatusPostponedCount + counts.StatusRemovedCount + totalEvents := counts.StatusEndedCount + counts.StatusNotFinishedCount + + counts.StatusToBeFixedCount + counts.StatusPostponedCount + counts.StatusRemovedCount + totalBets := counts.StatusEndedBets + counts.StatusNotFinishedBets + + counts.StatusPostponedBets + counts.StatusRemovedBets + counts.StatusToBeFixedBets + + greeting := fmt.Sprintf("Hi %s %s,", user.FirstName, user.LastName) + + if totalIssues == 0 { + headline := "✅ Daily Results Report — All Events Processed Successfully" + plain := fmt.Sprintf(`%s + +Daily Results Summary: +- %d Ended Events +- %d Total Bets + +All events were processed successfully, and no issues were detected. + +Best regards, +The System`, greeting, counts.StatusEndedCount, totalBets) + + html := fmt.Sprintf(`
%s
+All events were processed successfully, and no issues were detected.
+Best regards,
The System
%s
+Next Steps:
Some events require your attention. Please log into the admin dashboard to review pending issues.
Best regards,
The System