Class: ActivityNotification::CascadingNotificationJob

Inherits:
Object
  • Object
show all
Defined in:
app/jobs/activity_notification/cascading_notification_job.rb

Overview

Job to handle cascading notifications with time delays and read status checking. This job enables sequential delivery of notifications through different channels based on whether previous notifications were read.

Examples:

Basic usage

cascade_config = [
  { delay: 10.minutes, target: :slack },
  { delay: 10.minutes, target: :email }
]
CascadingNotificationJob.perform_later(notification.id, cascade_config, 0)

Instance Method Summary collapse

Instance Method Details

#perform(notification_id, cascade_config, step_index = 0) ⇒ Hash?

Performs a single step in the cascading notification chain. Checks if the notification is still unread, and if so, triggers the next optional target and schedules the next step in the cascade.

Parameters:

  • notification_id (Integer)

    ID of the notification to check

  • cascade_config (Array<Hash>)

    Array of cascade step configurations

  • step_index (Integer) (defaults to: 0)

    Current step index in the cascade chain (0-based)

Options Hash (cascade_config):

  • :delay (ActiveSupport::Duration)

    Time to wait before checking and sending

  • :target (Symbol, String)

    Name of the optional target to trigger (e.g., :slack, :email)

  • :options (Hash)

    Optional parameters to pass to the optional target

Returns:

  • (Hash, nil)

    Result of triggering the optional target, or nil if notification was read or not found



26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'app/jobs/activity_notification/cascading_notification_job.rb', line 26

def perform(notification_id, cascade_config, step_index = 0)
  # Find the notification using ORM-appropriate method
  # :nocov:
  notification = case ActivityNotification.config.orm
                 when :dynamoid
                   ActivityNotification::Notification.find(notification_id, raise_error: false)
                 when :mongoid
                   begin
                     ActivityNotification::Notification.find(notification_id)
                   rescue Mongoid::Errors::DocumentNotFound
                     nil
                   end
                 else
                   ActivityNotification::Notification.find_by(id: notification_id)
                 end
  # :nocov:
  
  # Return early if notification not found or has been opened (read)
  return nil if notification.nil? || notification.opened?
  
  # Get current step configuration
  current_step = cascade_config[step_index]
  return nil if current_step.nil?
  
  # Extract step parameters
  target_name = current_step[:target] || current_step['target']
  target_options = current_step[:options] || current_step['options'] || {}
  
  # Trigger the optional target for this step
  result = trigger_optional_target(notification, target_name, target_options)
  
  # Schedule next step if available and notification is still unread
  next_step_index = step_index + 1
  if next_step_index < cascade_config.length
    next_step = cascade_config[next_step_index]
    delay = next_step[:delay] || next_step['delay']
    
    if delay.present?
      # Schedule the next step with the specified delay
      self.class.set(wait: delay).perform_later(
        notification_id,
        cascade_config,
        next_step_index
      )
    end
  end
  
  result
end