diff --git a/pkg/notification/entities.go b/pkg/notification/entities.go index 4805c83..d9a191a 100644 --- a/pkg/notification/entities.go +++ b/pkg/notification/entities.go @@ -24,10 +24,14 @@ type NotificationMethods struct { // NotificationRequest represents the request structure for sending notifications type NotificationRequest struct { - EventType EventType `json:"event_type" valid:"required,in(EMAIL|SMS|PUSH|OTP)"` - Message string `json:"message" valid:"required,length(1|1000)"` - Methods NotificationMethods `json:"methods" valid:"required"` - UserID string `json:"user_id,omitempty" valid:"optional"` + UserID string `json:"user_id,omitempty" valid:"optional"` + Title string `json:"title" valid:"required"` + Message string `json:"message" valid:"required,length(1|1000)"` + Type string `json:"type" valid:"required,in(info|warning|alert|reject)"` + EventType EventType `json:"event_type" valid:"required,in(EMAIL|SMS|PUSH|OTP)"` + Priority string `json:"priority" valid:"required,in(low|medium|important)"` + ScheduledAt int64 `json:"scheduled_at"` + Methods NotificationMethods `json:"methods" valid:"required"` } // NotificationResponse represents the successful response from notification service @@ -67,6 +71,11 @@ func (nr *NotificationRequest) Validate() error { } } + // Validate scheduled_at: 0 means immediate delivery, otherwise must be future timestamp + if nr.ScheduledAt < 0 { + return ErrValidation{Field: "scheduled_at", Message: "scheduled_at cannot be negative"} + } + return nil } @@ -101,3 +110,8 @@ func (nm *NotificationMethods) GetMethodValue(eventType EventType) string { return "" } } + +// IsImmediate returns true if the notification should be sent immediately (scheduled_at = 0) +func (nr *NotificationRequest) IsImmediate() bool { + return nr.ScheduledAt == 0 +} diff --git a/pkg/notification/interfaces.go b/pkg/notification/interfaces.go index 92a2458..26ebf21 100644 --- a/pkg/notification/interfaces.go +++ b/pkg/notification/interfaces.go @@ -10,19 +10,22 @@ type NotificationService interface { SendNotification(ctx context.Context, req *NotificationRequest) (*NotificationResponse, error) // SendEmail sends an email notification - SendEmail(ctx context.Context, email, message, userID string) (*NotificationResponse, error) + SendEmail(ctx context.Context, model Model) (*NotificationResponse, error) // SendSMS sends an SMS notification - SendSMS(ctx context.Context, phoneNumber, message, userID string) (*NotificationResponse, error) + SendSMS(ctx context.Context, model Model) (*NotificationResponse, error) // SendPush sends a push notification - SendPush(ctx context.Context, deviceToken, message, userID string) (*NotificationResponse, error) + SendPush(ctx context.Context, model Model) (*NotificationResponse, error) // SendOTP sends an OTP notification - SendOTP(ctx context.Context, phoneNumber, message, userID string) (*NotificationResponse, error) + SendOTP(ctx context.Context, model Model) (*NotificationResponse, error) // Health checks if the notification service is available Health(ctx context.Context) error + + // NewBuilder creates a new notification builder + NewBuilder() Builder } // Builder provides a fluent interface for building notification requests @@ -48,6 +51,18 @@ type Builder interface { // SetOTP sets the OTP phone number SetOTP(phoneNumber string) Builder + // SetTitle sets the notification title + SetTitle(title string) Builder + + // SetType sets the notification type + SetType(notificationType string) Builder + + // SetPriority sets the notification priority + SetPriority(priority string) Builder + + // SetScheduledAt sets the scheduled delivery time (0 for immediate) + SetScheduledAt(scheduledAt int64) Builder + // Build creates the notification request Build() (*NotificationRequest, error) diff --git a/pkg/notification/sdk.go b/pkg/notification/sdk.go index 6d1226a..616f4dc 100644 --- a/pkg/notification/sdk.go +++ b/pkg/notification/sdk.go @@ -55,23 +55,23 @@ func (s *SDK) SendNotification(ctx context.Context, req *NotificationRequest) (* } // SendEmail sends an email notification -func (s *SDK) SendEmail(ctx context.Context, email, message, userID string) (*NotificationResponse, error) { - return s.service.SendEmail(ctx, email, message, userID) +func (s *SDK) SendEmail(ctx context.Context, model Model) (*NotificationResponse, error) { + return s.service.SendEmail(ctx, model) } // SendSMS sends an SMS notification -func (s *SDK) SendSMS(ctx context.Context, phoneNumber, message, userID string) (*NotificationResponse, error) { - return s.service.SendSMS(ctx, phoneNumber, message, userID) +func (s *SDK) SendSMS(ctx context.Context, model Model) (*NotificationResponse, error) { + return s.service.SendSMS(ctx, model) } // SendPush sends a push notification -func (s *SDK) SendPush(ctx context.Context, deviceToken, message, userID string) (*NotificationResponse, error) { - return s.service.SendPush(ctx, deviceToken, message, userID) +func (s *SDK) SendPush(ctx context.Context, model Model) (*NotificationResponse, error) { + return s.service.SendPush(ctx, model) } // SendOTP sends an OTP notification -func (s *SDK) SendOTP(ctx context.Context, phoneNumber, message, userID string) (*NotificationResponse, error) { - return s.service.SendOTP(ctx, phoneNumber, message, userID) +func (s *SDK) SendOTP(ctx context.Context, model Model) (*NotificationResponse, error) { + return s.service.SendOTP(ctx, model) } // NewBuilder creates a new notification builder for fluent API usage @@ -92,26 +92,26 @@ func (s *SDK) GetConfig() *Config { // Convenience functions for quick notifications // QuickEmail sends a simple email notification -func (s *SDK) QuickEmail(ctx context.Context, email, message string) error { - _, err := s.SendEmail(ctx, email, message, "") +func (s *SDK) QuickEmail(ctx context.Context, model Model) error { + _, err := s.SendEmail(ctx, model) return err } // QuickSMS sends a simple SMS notification -func (s *SDK) QuickSMS(ctx context.Context, phoneNumber, message string) error { - _, err := s.SendSMS(ctx, phoneNumber, message, "") +func (s *SDK) QuickSMS(ctx context.Context, model Model) error { + _, err := s.SendSMS(ctx, model) return err } // QuickPush sends a simple push notification -func (s *SDK) QuickPush(ctx context.Context, deviceToken, message string) error { - _, err := s.SendPush(ctx, deviceToken, message, "") +func (s *SDK) QuickPush(ctx context.Context, model Model) error { + _, err := s.SendPush(ctx, model) return err } // QuickOTP sends a simple OTP notification -func (s *SDK) QuickOTP(ctx context.Context, phoneNumber, message string) error { - _, err := s.SendOTP(ctx, phoneNumber, message, "") +func (s *SDK) QuickOTP(ctx context.Context, model Model) error { + _, err := s.SendOTP(ctx, model) return err } diff --git a/pkg/notification/service.go b/pkg/notification/service.go index b906e75..70d35f8 100644 --- a/pkg/notification/service.go +++ b/pkg/notification/service.go @@ -10,6 +10,16 @@ type Service struct { client *Client } +type Model struct { + Message string + Title string + Type string + Priority string + ScheduledAt int64 + Recipient string + UserID string +} + // NewService creates a new notification service func NewService(client *Client) NotificationService { return &Service{ @@ -23,56 +33,72 @@ func (s *Service) SendNotification(ctx context.Context, req *NotificationRequest } // SendEmail sends an email notification -func (s *Service) SendEmail(ctx context.Context, email, message, userID string) (*NotificationResponse, error) { +func (s *Service) SendEmail(ctx context.Context, model Model) (*NotificationResponse, error) { req := &NotificationRequest{ - EventType: EventTypeEmail, - Message: message, + EventType: EventTypeEmail, + Message: model.Message, + Title: model.Title, + Type: model.Type, + Priority: model.Priority, + ScheduledAt: model.ScheduledAt, Methods: NotificationMethods{ - Email: email, + Email: model.Recipient, }, - UserID: userID, + UserID: model.UserID, } return s.client.SendNotification(ctx, req) } // SendSMS sends an SMS notification -func (s *Service) SendSMS(ctx context.Context, phoneNumber, message, userID string) (*NotificationResponse, error) { +func (s *Service) SendSMS(ctx context.Context, model Model) (*NotificationResponse, error) { req := &NotificationRequest{ - EventType: EventTypeSMS, - Message: message, + EventType: EventTypeSMS, + Message: model.Message, + Title: model.Title, + Type: model.Type, + Priority: model.Priority, + ScheduledAt: model.ScheduledAt, Methods: NotificationMethods{ - SMS: phoneNumber, + SMS: model.Recipient, }, - UserID: userID, + UserID: model.UserID, } return s.client.SendNotification(ctx, req) } // SendPush sends a push notification -func (s *Service) SendPush(ctx context.Context, deviceToken, message, userID string) (*NotificationResponse, error) { +func (s *Service) SendPush(ctx context.Context, model Model) (*NotificationResponse, error) { req := &NotificationRequest{ - EventType: EventTypePush, - Message: message, + EventType: EventTypePush, + Message: model.Message, + Title: model.Title, + Type: model.Type, + Priority: model.Priority, + ScheduledAt: model.ScheduledAt, Methods: NotificationMethods{ - Push: deviceToken, + Push: model.Recipient, }, - UserID: userID, + UserID: model.UserID, } return s.client.SendNotification(ctx, req) } // SendOTP sends an OTP notification -func (s *Service) SendOTP(ctx context.Context, phoneNumber, message, userID string) (*NotificationResponse, error) { +func (s *Service) SendOTP(ctx context.Context, model Model) (*NotificationResponse, error) { req := &NotificationRequest{ - EventType: EventTypeOTP, - Message: message, + EventType: EventTypeOTP, + Message: model.Message, + Title: model.Title, + Type: model.Type, + Priority: model.Priority, + ScheduledAt: model.ScheduledAt, Methods: NotificationMethods{ - OTP: phoneNumber, + OTP: model.Recipient, }, - UserID: userID, + UserID: model.UserID, } return s.client.SendNotification(ctx, req) @@ -82,8 +108,12 @@ func (s *Service) SendOTP(ctx context.Context, phoneNumber, message, userID stri func (s *Service) Health(ctx context.Context) error { // Create a simple test request to check service availability testReq := &NotificationRequest{ - EventType: EventTypeEmail, - Message: "health check", + EventType: EventTypeEmail, + Message: "health check", + Title: "Health Check", + Type: "info", + Priority: "low", + ScheduledAt: 0, Methods: NotificationMethods{ Email: "test@example.com", }, @@ -157,6 +187,30 @@ func (b *notificationBuilder) SetOTP(phoneNumber string) Builder { return b } +// SetTitle sets the notification title +func (b *notificationBuilder) SetTitle(title string) Builder { + b.request.Title = title + return b +} + +// SetType sets the notification type +func (b *notificationBuilder) SetType(notificationType string) Builder { + b.request.Type = notificationType + return b +} + +// SetPriority sets the notification priority +func (b *notificationBuilder) SetPriority(priority string) Builder { + b.request.Priority = priority + return b +} + +// SetScheduledAt sets the scheduled delivery time (0 for immediate) +func (b *notificationBuilder) SetScheduledAt(scheduledAt int64) Builder { + b.request.ScheduledAt = scheduledAt + return b +} + // Build creates the notification request func (b *notificationBuilder) Build() (*NotificationRequest, error) { if err := b.request.Validate(); err != nil {