Add MarkSeen Functionality to Notification System
- Implemented the MarkSeen method in the notification client to mark notifications as seen, enhancing user interaction with notifications. - Added MarkSeenRequest and MarkSeenResponse structs to facilitate the request and response handling for marking notifications. - Updated the NotificationService interface to include the new MarkSeen method, ensuring consistency across the service layer. - Enhanced the SDK with a QuickMarkSeen convenience method for easier usage in client applications. - Included logging for successful and failed attempts to mark notifications as seen, improving traceability and debugging capabilities.
This commit is contained in:
@@ -304,6 +304,65 @@ func (c *Client) buildQueryParams(req *GetNotificationsRequest) string {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MarkSeen marks a notification as seen
|
||||||
|
func (c *Client) MarkSeen(ctx context.Context, notificationID string) (*MarkSeenResponse, error) {
|
||||||
|
if c.config.EnableLogging && c.logger != nil {
|
||||||
|
c.logger.Debug("Marking notification as seen", map[string]interface{}{
|
||||||
|
"notification_id": notificationID,
|
||||||
|
"base_url": c.config.BaseURL,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create HTTP request
|
||||||
|
url := fmt.Sprintf("%s/api/v1/notifications/%s/seen", c.config.BaseURL, notificationID)
|
||||||
|
httpReq, err := http.NewRequestWithContext(ctx, "PUT", url, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to create HTTP request: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set headers
|
||||||
|
httpReq.Header.Set("Content-Type", "application/json")
|
||||||
|
httpReq.Header.Set("User-Agent", c.config.UserAgent)
|
||||||
|
|
||||||
|
// Send request
|
||||||
|
resp, err := c.httpClient.Do(httpReq)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("HTTP request failed: %w", err)
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
// Read response body
|
||||||
|
body, err := io.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to read response body: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle non-2xx status codes
|
||||||
|
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
|
||||||
|
// Try to parse error response
|
||||||
|
var errorResp NotificationErrorResponse
|
||||||
|
if json.Unmarshal(body, &errorResp) == nil && errorResp.Error != "" {
|
||||||
|
return nil, MapHTTPError(resp.StatusCode, errorResp.Error)
|
||||||
|
}
|
||||||
|
return nil, MapHTTPError(resp.StatusCode, string(body))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse success response
|
||||||
|
var markSeenResp MarkSeenResponse
|
||||||
|
if err := json.Unmarshal(body, &markSeenResp); err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to unmarshal response: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if c.config.EnableLogging && c.logger != nil {
|
||||||
|
c.logger.Info("Notification marked as seen successfully", map[string]interface{}{
|
||||||
|
"notification_id": notificationID,
|
||||||
|
"status": markSeenResp.Status,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return &markSeenResp, nil
|
||||||
|
}
|
||||||
|
|
||||||
// shouldRetry determines if a request should be retried based on the error
|
// shouldRetry determines if a request should be retried based on the error
|
||||||
func (c *Client) shouldRetry(err error) bool {
|
func (c *Client) shouldRetry(err error) bool {
|
||||||
switch e := err.(type) {
|
switch e := err.(type) {
|
||||||
|
|||||||
@@ -135,6 +135,8 @@ type NotificationItem struct {
|
|||||||
Status string `json:"status"`
|
Status string `json:"status"`
|
||||||
ScheduledAt int64 `json:"scheduled_at"`
|
ScheduledAt int64 `json:"scheduled_at"`
|
||||||
IsScheduled bool `json:"is_scheduled"`
|
IsScheduled bool `json:"is_scheduled"`
|
||||||
|
Seen bool `json:"seen"`
|
||||||
|
SeenAt int64 `json:"seen_at"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// NotificationListResponse represents the response from getting notifications list
|
// NotificationListResponse represents the response from getting notifications list
|
||||||
@@ -162,3 +164,13 @@ type GetNotificationsRequest struct {
|
|||||||
Page int `json:"page,omitempty" valid:"optional"`
|
Page int `json:"page,omitempty" valid:"optional"`
|
||||||
PerPage int `json:"per_page,omitempty" valid:"optional"`
|
PerPage int `json:"per_page,omitempty" valid:"optional"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MarkSeenRequest represents the request for marking a notification as seen
|
||||||
|
type MarkSeenRequest struct {
|
||||||
|
NotificationID string `json:"notification_id" valid:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarkSeenResponse represents the response from marking a notification as seen
|
||||||
|
type MarkSeenResponse struct {
|
||||||
|
Status string `json:"status"`
|
||||||
|
}
|
||||||
|
|||||||
@@ -24,6 +24,9 @@ type NotificationService interface {
|
|||||||
// GetNotifications retrieves a list of notifications
|
// GetNotifications retrieves a list of notifications
|
||||||
GetNotifications(ctx context.Context, req *GetNotificationsRequest) (*NotificationListResponse, error)
|
GetNotifications(ctx context.Context, req *GetNotificationsRequest) (*NotificationListResponse, error)
|
||||||
|
|
||||||
|
// MarkSeen marks a notification as seen
|
||||||
|
MarkSeen(ctx context.Context, notificationID string) (*MarkSeenResponse, error)
|
||||||
|
|
||||||
// Health checks if the notification service is available
|
// Health checks if the notification service is available
|
||||||
Health(ctx context.Context) error
|
Health(ctx context.Context) error
|
||||||
|
|
||||||
|
|||||||
@@ -79,6 +79,11 @@ func (s *SDK) GetNotifications(ctx context.Context, req *GetNotificationsRequest
|
|||||||
return s.service.GetNotifications(ctx, req)
|
return s.service.GetNotifications(ctx, req)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MarkSeen marks a notification as seen
|
||||||
|
func (s *SDK) MarkSeen(ctx context.Context, notificationID string) (*MarkSeenResponse, error) {
|
||||||
|
return s.service.MarkSeen(ctx, notificationID)
|
||||||
|
}
|
||||||
|
|
||||||
// NewBuilder creates a new notification builder for fluent API usage
|
// NewBuilder creates a new notification builder for fluent API usage
|
||||||
func (s *SDK) NewBuilder() Builder {
|
func (s *SDK) NewBuilder() Builder {
|
||||||
return s.service.(*Service).NewBuilder()
|
return s.service.(*Service).NewBuilder()
|
||||||
@@ -149,6 +154,12 @@ func (s *SDK) GetNotificationsByStatus(ctx context.Context, status string, page,
|
|||||||
return s.GetNotifications(ctx, req)
|
return s.GetNotifications(ctx, req)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// QuickMarkSeen marks a notification as seen (convenience method)
|
||||||
|
func (s *SDK) QuickMarkSeen(ctx context.Context, notificationID string) error {
|
||||||
|
_, err := s.MarkSeen(ctx, notificationID)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
// Batch operations for sending multiple notifications
|
// Batch operations for sending multiple notifications
|
||||||
|
|
||||||
// BatchRequest represents a batch notification request
|
// BatchRequest represents a batch notification request
|
||||||
|
|||||||
@@ -109,6 +109,11 @@ func (s *Service) GetNotifications(ctx context.Context, req *GetNotificationsReq
|
|||||||
return s.client.GetNotifications(ctx, req)
|
return s.client.GetNotifications(ctx, req)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MarkSeen marks a notification as seen
|
||||||
|
func (s *Service) MarkSeen(ctx context.Context, notificationID string) (*MarkSeenResponse, error) {
|
||||||
|
return s.client.MarkSeen(ctx, notificationID)
|
||||||
|
}
|
||||||
|
|
||||||
// Health checks if the notification service is available
|
// Health checks if the notification service is available
|
||||||
func (s *Service) Health(ctx context.Context) error {
|
func (s *Service) Health(ctx context.Context) error {
|
||||||
// Create a simple test request to check service availability
|
// Create a simple test request to check service availability
|
||||||
|
|||||||
Reference in New Issue
Block a user