class Noticent::Dispatcher

Public Class Methods

new(config, alert_name, payload, configuration = {}) click to toggle source
# File lib/noticent/dispatcher.rb, line 5
def initialize(config, alert_name, payload, configuration = {})
  @config = config
  @alert_name = alert_name
  @payload = payload
  @configuration = configuration

  validate!

  @entity_id = @payload.send("#{scope.name}_id")
end

Public Instance Methods

alert() click to toggle source
# File lib/noticent/dispatcher.rb, line 16
def alert
  @config.alerts[@alert_name]
end
dispatch() click to toggle source
# File lib/noticent/dispatcher.rb, line 43
def dispatch
  notifiers.values.each do |notifier|
    recs = recipients(notifier.recipient)
    notifier.applicable_channels.each do |channel|
      to_send = filter_recipients(recs, channel.name)

      if to_send.count == 0 && @config.skip_alert_with_no_subscribers
        Noticent.configuration.logger.info "Skipping notification of alert #{alert.name} on channel #{channel.name} as there are no subscribers"
        next
      end

      channel_instance = channel.instance(@config, to_send, @payload, @configuration)
      begin
        raise Noticent::BadConfiguration, "channel #{channel.name} (#{channel.klass}) doesn't have a method called #{alert.name}" unless channel_instance.respond_to? alert.name

        channel_instance.send(alert.name)
      rescue StandardError => e
        # log and move on
        raise if @config.halt_on_error

        Noticent.configuration.logger.error e
      end
    end
  end
end
filter_recipients(recipients, channel) click to toggle source

only returns recipients that have opted-in for this channel

# File lib/noticent/dispatcher.rb, line 36
def filter_recipients(recipients, channel)
  raise ArgumentError, "channel should be a string or symbol" unless channel.is_a?(String) || channel.is_a?(Symbol)
  raise ArgumentError, "recipients is nil" if recipients.nil?

  recipients.select { |recipient| @config.opt_in_provider.opted_in?(recipient_id: recipient.id, scope: scope.name, entity_id: @entity_id, alert_name: alert.name, channel_name: channel) }
end
notifiers() click to toggle source
# File lib/noticent/dispatcher.rb, line 24
def notifiers
  alert.notifiers
end
recipients(notifier_name) click to toggle source

returns all recipients of a certain notifier unfiltered regardless of “opt-in” and duplicates

# File lib/noticent/dispatcher.rb, line 29
def recipients(notifier_name)
  raise Noticent::InvalidScope, "payload #{@payload.klass} doesn't have a #{notifier_name} method" unless @payload.respond_to? notifier_name

  @payload.send(notifier_name)
end
scope() click to toggle source
# File lib/noticent/dispatcher.rb, line 20
def scope
  alert.scope
end

Private Instance Methods

validate!() click to toggle source
# File lib/noticent/dispatcher.rb, line 71
def validate!
  raise Noticent::BadConfiguration, "no base_dir defined" if @config.base_dir.nil?
  raise Noticent::MissingConfiguration if @config.nil?
  raise Noticent::BadConfiguration if @config.alerts.nil?
  raise Noticent::InvalidAlert, "no alert #{@alert_name} found" if @config.alerts[@alert_name].nil?
  raise ::ArgumentError, "payload is nil" if @payload.nil?
  raise ::ArgumentError, "alert is not a symbol" unless @alert_name.is_a?(Symbol)
  raise Noticent::BadConfiguration, "payload (#{@payload.class}) doesn't belong to this scope (#{scope.name}) as it requires #{scope.payload_class}" unless !scope.payload_class.nil? && @payload.is_a?(scope.payload_class)
  raise Noticent::BadConfiguration, "payload doesn't have a #{scope.name}_id method" unless @payload.respond_to?("#{scope.name}_id")
end