Class: Hermes::Deliverer

Inherits:
Object
  • Object
show all
Includes:
Extractors
Defined in:
lib/hermes/deliverer.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Extractors

#complex_extract, #extract_from, #extract_html, #extract_text, #extract_to

Constructor Details

#initialize(settings) ⇒ Deliverer

Returns a new instance of Deliverer.



9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/hermes/deliverer.rb', line 9

def initialize(settings)
  @providers = {}
  
  @config = settings[:config]

  # this will most likely come back as [:email, :sms, :tweet, :webhook]
  provider_types = @config.keys.reject{|key| key == :config}
  
  # loop through each and construct a workable array
  provider_types.each do |provider_type|
    @providers[provider_type] ||= []
    providers = settings[provider_type]
    next unless providers.try(:any?)

    # go through all of the providers and initialize each
    providers.each do |provider_name, options|
      # check to see that the provider class exists
      provider_proper_name = "#{provider_name}_provider".camelize.to_sym
      raise(ProviderNotFoundError, "Could not find provider class Hermes::#{provider_proper_name}") unless Hermes.constants.include?(provider_proper_name)

      # initialize the provider with the given weight, defaults, and credentials
      provider = Hermes.const_get(provider_proper_name).new(self, options)
      @providers[provider_type] << provider
    end

    # make sure the provider type has an aggregate weight of more than 1
    aweight = aggregate_weight_for_type(provider_type)
    unless aweight > 0
      raise(InvalidWeightError, "Provider type:#{provider_type} has aggregate weight:#{aweight}")
    end
  end
end

Instance Attribute Details

#configObject (readonly)

Returns the value of attribute config.



7
8
9
# File 'lib/hermes/deliverer.rb', line 7

def config
  @config
end

#providersObject (readonly)

Returns the value of attribute providers.



7
8
9
# File 'lib/hermes/deliverer.rb', line 7

def providers
  @providers
end

Instance Method Details

#aggregate_weight_for_type(type) ⇒ Object



58
59
60
61
62
63
# File 'lib/hermes/deliverer.rb', line 58

def aggregate_weight_for_type(type)
  providers = @providers[type]
  return 0 if providers.empty?

  providers.map(&:weight).inject(0, :+)
end

#deliver!(rails_message) ⇒ Object



105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/hermes/deliverer.rb', line 105

def deliver!(rails_message)
  # figure out what we're delivering
  delivery_type = delivery_type_for(rails_message)

  # set this on the message so it's available throughout
  rails_message.hermes_type = delivery_type

  # find a provider, weight matters here
  provider = weighted_provider_for_type(delivery_type)

  # and then send the message
  provider.send_message(rails_message)
end

#delivery_type_for(rails_message) ⇒ Object



89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/hermes/deliverer.rb', line 89

def delivery_type_for(rails_message)
  to = extract_to(rails_message, format: :address)

  if to.is_a?(Hash) && to[:twitter_username]
    :tweet
  elsif rails_message.to.first.include?('@')
    :email
  elsif to.is_a?(Phone)
    :sms
  elsif to.is_a?(URI)
    :webhook
  else
    raise UnknownDeliveryTypeError, "Cannot determine provider type from provided to:#{to}"
  end
end

#handle_failure(provider_name, exception) ⇒ Object



50
51
52
# File 'lib/hermes/deliverer.rb', line 50

def handle_failure(provider_name, exception)

end

#handle_success(provider_name) ⇒ Object



46
47
48
# File 'lib/hermes/deliverer.rb', line 46

def handle_success(provider_name)
  @config[:stats]
end

#should_deliver?Boolean

Returns:

  • (Boolean)


54
55
56
# File 'lib/hermes/deliverer.rb', line 54

def should_deliver?
  !self.test_mode? && ActionMailer::Base.perform_deliveries
end

#test_mode?Boolean

Returns:

  • (Boolean)


42
43
44
# File 'lib/hermes/deliverer.rb', line 42

def test_mode?
  !!@config[:test]
end

#weighted_provider_for_type(type) ⇒ Object



65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/hermes/deliverer.rb', line 65

def weighted_provider_for_type(type)
  providers = @providers[type]
  return nil if providers.empty?

  # get the aggregate weight, and do a rand based on it
  random_index = rand(aggregate_weight_for_type(type))
  # puts "random_index:#{random_index}"

  # loop through each, exclusive range, and find the one that it falls on
  running_total = 0
  providers.each do |provider|
    # puts "running_total:#{running_total}"
    left_index = running_total
    right_index = running_total + provider.weight
    # puts "left_index:#{left_index} right_index:#{right_index}"

    if (left_index...right_index).include?(random_index)
      return provider
    else
      running_total += provider.weight
    end
  end
end