Module: ActivityNotification::CascadingNotificationApi
- Extended by:
- ActiveSupport::Concern
- Included in:
- NotificationApi
- Defined in:
- lib/activity_notification/apis/cascading_notification_api.rb
Overview
Defines API for cascading notifications included in Notification model. Cascading notifications enable sequential delivery through different channels based on read status, with configurable time delays between each step.
Instance Method Summary collapse
-
#cascade_in_progress? ⇒ Boolean
Checks if a cascading notification is currently in progress for this notification This is a helper method that checks if there are scheduled jobs for this notification.
-
#cascade_notify(cascade_config, options = {}) ⇒ Boolean
Starts a cascading notification chain with the specified configuration.
-
#validate_cascade_config(cascade_config) ⇒ Hash
Validates a cascade configuration array.
Instance Method Details
#cascade_in_progress? ⇒ Boolean
Checks if a cascading notification is currently in progress for this notification This is a helper method that checks if there are scheduled jobs for this notification
154 155 156 157 158 159 |
# File 'lib/activity_notification/apis/cascading_notification_api.rb', line 154 def cascade_in_progress? # This is a best-effort check that returns false by default # In production, you might want to track this state differently # (e.g., in Redis, database flag, or by querying the job queue) false end |
#cascade_notify(cascade_config, options = {}) ⇒ Boolean
Starts a cascading notification chain with the specified configuration. The chain will automatically check the read status before each step and only proceed if the notification remains unread.
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 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 |
# File 'lib/activity_notification/apis/cascading_notification_api.rb', line 34 def cascade_notify(cascade_config, = {}) validate = .fetch(:validate, true) trigger_first_immediately = .fetch(:trigger_first_immediately, false) # Validate configuration if requested if validate validation_result = validate_cascade_config(cascade_config) unless validation_result[:valid] raise ArgumentError, "Invalid cascade configuration: #{validation_result[:errors].join(', ')}" end end # Return false if cascade config is empty return false if cascade_config.blank? # Return false if notification is already opened return false if opened? if defined?(ActiveJob) && defined?(ActivityNotification::CascadingNotificationJob) && ActivityNotification::CascadingNotificationJob.respond_to?(:perform_later) if trigger_first_immediately && cascade_config.any? # Trigger first target immediately first_step = cascade_config.first target_name = first_step[:target] || first_step['target'] = first_step[:options] || first_step['options'] || {} # Perform the first step synchronously perform_cascade_step(target_name, ) # Schedule remaining steps if any if cascade_config.length > 1 remaining_config = cascade_config[1..-1] first_delay = remaining_config.first[:delay] || remaining_config.first['delay'] if first_delay.present? ActivityNotification::CascadingNotificationJob .set(wait: first_delay) .perform_later(id, remaining_config, 0) end end else # Schedule first step with its configured delay first_step = cascade_config.first first_delay = first_step[:delay] || first_step['delay'] if first_delay.present? ActivityNotification::CascadingNotificationJob .set(wait: first_delay) .perform_later(id, cascade_config, 0) else # If no delay specified for first step, trigger immediately ActivityNotification::CascadingNotificationJob .perform_later(id, cascade_config, 0) end end true else Rails.logger.error("ActiveJob or CascadingNotificationJob not available for cascading notifications") false end end |
#validate_cascade_config(cascade_config) ⇒ Hash
Validates a cascade configuration array
101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 |
# File 'lib/activity_notification/apis/cascading_notification_api.rb', line 101 def validate_cascade_config(cascade_config) errors = [] if cascade_config.nil? errors << "cascade_config cannot be nil" return { valid: false, errors: errors } end unless cascade_config.is_a?(Array) errors << "cascade_config must be an Array" return { valid: false, errors: errors } end if cascade_config.empty? errors << "cascade_config cannot be empty" end cascade_config.each_with_index do |step, index| unless step.is_a?(Hash) errors << "Step #{index} must be a Hash" next end # Check for required target parameter target = step[:target] || step['target'] if target.nil? errors << "Step #{index} missing required :target parameter" elsif !target.is_a?(Symbol) && !target.is_a?(String) errors << "Step #{index} :target must be a Symbol or String" end # Check for delay parameter (only required for steps after the first if not using trigger_first_immediately) delay = step[:delay] || step['delay'] if delay.nil? errors << "Step #{index} missing :delay parameter" elsif !delay.respond_to?(:from_now) && !delay.is_a?(Numeric) errors << "Step #{index} :delay must be an ActiveSupport::Duration or Numeric (seconds)" end # Check options if present = step[:options] || step['options'] if .present? && !.is_a?(Hash) errors << "Step #{index} :options must be a Hash" end end { valid: errors.empty?, errors: errors } end |