package ironnotify import "time" // EventBuilder provides a fluent API for building notifications. type EventBuilder struct { client *Client eventType string title string message string severity SeverityLevel metadata map[string]any actions []NotificationAction userID string groupKey string deduplicationKey string expiresAt *time.Time } // newEventBuilder creates a new EventBuilder. func newEventBuilder(client *Client, eventType string) *EventBuilder { return &EventBuilder{ client: client, eventType: eventType, severity: SeverityInfo, metadata: make(map[string]any), actions: make([]NotificationAction, 0), } } // WithTitle sets the notification title. func (b *EventBuilder) WithTitle(title string) *EventBuilder { b.title = title return b } // WithMessage sets the notification message. func (b *EventBuilder) WithMessage(message string) *EventBuilder { b.message = message return b } // WithSeverity sets the severity level. func (b *EventBuilder) WithSeverity(severity SeverityLevel) *EventBuilder { b.severity = severity return b } // WithMetadata adds metadata to the notification. func (b *EventBuilder) WithMetadata(key string, value any) *EventBuilder { b.metadata[key] = value return b } // WithMetadataMap adds multiple metadata entries. func (b *EventBuilder) WithMetadataMap(metadata map[string]any) *EventBuilder { for k, v := range metadata { b.metadata[k] = v } return b } // WithAction adds an action button to the notification. func (b *EventBuilder) WithAction(label string, opts ...ActionOption) *EventBuilder { action := NotificationAction{Label: label, Style: "default"} for _, opt := range opts { opt(&action) } b.actions = append(b.actions, action) return b } // ActionOption is a function that modifies a NotificationAction. type ActionOption func(*NotificationAction) // ActionURL sets the URL for an action. func ActionURL(url string) ActionOption { return func(a *NotificationAction) { a.URL = url } } // ActionHandler sets the action handler name. func ActionHandler(action string) ActionOption { return func(a *NotificationAction) { a.Action = action } } // ActionStyle sets the style for an action. func ActionStyle(style string) ActionOption { return func(a *NotificationAction) { a.Style = style } } // ForUser sets the target user ID. func (b *EventBuilder) ForUser(userID string) *EventBuilder { b.userID = userID return b } // WithGroupKey sets the group key for grouping related notifications. func (b *EventBuilder) WithGroupKey(groupKey string) *EventBuilder { b.groupKey = groupKey return b } // WithDeduplicationKey sets the deduplication key. func (b *EventBuilder) WithDeduplicationKey(key string) *EventBuilder { b.deduplicationKey = key return b } // ExpiresIn sets the expiration time from now. func (b *EventBuilder) ExpiresIn(duration time.Duration) *EventBuilder { t := time.Now().Add(duration) b.expiresAt = &t return b } // ExpiresAt sets the expiration time. func (b *EventBuilder) ExpiresAt(t time.Time) *EventBuilder { b.expiresAt = &t return b } // Build builds the notification payload. func (b *EventBuilder) Build() (*NotificationPayload, error) { if b.title == "" { return nil, ErrTitleRequired } payload := &NotificationPayload{ EventType: b.eventType, Title: b.title, Message: b.message, Severity: b.severity, UserID: b.userID, GroupKey: b.groupKey, DeduplicationKey: b.deduplicationKey, ExpiresAt: b.expiresAt, } if len(b.metadata) > 0 { payload.Metadata = b.metadata } if len(b.actions) > 0 { payload.Actions = b.actions } return payload, nil } // Send sends the notification. func (b *EventBuilder) Send() SendResult { payload, err := b.Build() if err != nil { return SendResult{Success: false, Error: err.Error()} } return b.client.SendPayload(payload) }