0857314906
- Updated the NotificationRequest struct to include new fields: Title, Type, Priority, and ScheduledAt, improving the flexibility and usability of notification requests. - Implemented validation for the new ScheduledAt field to ensure it is a future timestamp or zero for immediate delivery. - Refactored the NotificationService interface and SDK methods to accept a new Model struct, streamlining the parameters for sending notifications. - Enhanced the builder pattern for constructing notification requests, adding methods for setting Title, Type, Priority, and ScheduledAt, promoting a fluent API design. - Updated service methods for sending notifications (Email, SMS, Push, OTP) to utilize the new Model struct, ensuring consistency across notification types.
118 lines
3.7 KiB
Go
118 lines
3.7 KiB
Go
package notification
|
|
|
|
import (
|
|
"github.com/asaskevich/govalidator"
|
|
)
|
|
|
|
// EventType represents the type of notification event
|
|
type EventType string
|
|
|
|
const (
|
|
EventTypeEmail EventType = "EMAIL"
|
|
EventTypeSMS EventType = "SMS"
|
|
EventTypePush EventType = "PUSH"
|
|
EventTypeOTP EventType = "OTP"
|
|
)
|
|
|
|
// NotificationMethods contains different delivery methods for notifications
|
|
type NotificationMethods struct {
|
|
OTP string `json:"otp,omitempty" valid:"optional"`
|
|
SMS string `json:"sms,omitempty" valid:"optional"`
|
|
Push string `json:"push,omitempty" valid:"optional"`
|
|
Email string `json:"email,omitempty" valid:"optional,email"`
|
|
}
|
|
|
|
// NotificationRequest represents the request structure for sending notifications
|
|
type NotificationRequest struct {
|
|
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
|
|
type NotificationResponse struct {
|
|
Status string `json:"status"`
|
|
}
|
|
|
|
// NotificationErrorResponse represents the error response from notification service
|
|
type NotificationErrorResponse struct {
|
|
Error string `json:"error"`
|
|
}
|
|
|
|
// Validate validates the notification request
|
|
func (nr *NotificationRequest) Validate() error {
|
|
// First run govalidator validation
|
|
if _, err := govalidator.ValidateStruct(nr); err != nil {
|
|
return ErrValidation{Field: "struct", Message: err.Error()}
|
|
}
|
|
|
|
// Custom validation: ensure at least one method is provided based on event type
|
|
switch nr.EventType {
|
|
case EventTypeEmail:
|
|
if nr.Methods.Email == "" {
|
|
return ErrValidation{Field: "methods.email", Message: "email address is required for EMAIL event type"}
|
|
}
|
|
case EventTypeSMS:
|
|
if nr.Methods.SMS == "" {
|
|
return ErrValidation{Field: "methods.sms", Message: "SMS number is required for SMS event type"}
|
|
}
|
|
case EventTypePush:
|
|
if nr.Methods.Push == "" {
|
|
return ErrValidation{Field: "methods.push", Message: "push device token is required for PUSH event type"}
|
|
}
|
|
case EventTypeOTP:
|
|
if nr.Methods.OTP == "" {
|
|
return ErrValidation{Field: "methods.otp", Message: "OTP number is required for OTP event type"}
|
|
}
|
|
}
|
|
|
|
// 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
|
|
}
|
|
|
|
// HasMethod checks if a specific method is configured
|
|
func (nm *NotificationMethods) HasMethod(eventType EventType) bool {
|
|
switch eventType {
|
|
case EventTypeEmail:
|
|
return nm.Email != ""
|
|
case EventTypeSMS:
|
|
return nm.SMS != ""
|
|
case EventTypePush:
|
|
return nm.Push != ""
|
|
case EventTypeOTP:
|
|
return nm.OTP != ""
|
|
default:
|
|
return false
|
|
}
|
|
}
|
|
|
|
// GetMethodValue returns the value for a specific method
|
|
func (nm *NotificationMethods) GetMethodValue(eventType EventType) string {
|
|
switch eventType {
|
|
case EventTypeEmail:
|
|
return nm.Email
|
|
case EventTypeSMS:
|
|
return nm.SMS
|
|
case EventTypePush:
|
|
return nm.Push
|
|
case EventTypeOTP:
|
|
return nm.OTP
|
|
default:
|
|
return ""
|
|
}
|
|
}
|
|
|
|
// IsImmediate returns true if the notification should be sent immediately (scheduled_at = 0)
|
|
func (nr *NotificationRequest) IsImmediate() bool {
|
|
return nr.ScheduledAt == 0
|
|
}
|