Class: NotifyUser::BaseNotification

Inherits:
ActiveRecord::Base
  • Object
show all
Includes:
AASM, ActionView::Helpers::TextHelper
Defined in:
app/models/notify_user/base_notification.rb

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.channel(name, options = {}) ⇒ Object

Configure a channel



145
146
147
148
149
# File 'app/models/notify_user/base_notification.rb', line 145

def self.channel(name, options={})
  channels_clone = self.channels.clone
  channels_clone[name] = options
  self.channels = channels_clone
end

.deliver_channels(notification_id) ⇒ Object

Deliver a single notification across each channel.



193
194
195
196
197
198
199
200
201
202
# File 'app/models/notify_user/base_notification.rb', line 193

def self.deliver_channels(notification_id)
  notification = self.where(id: notification_id).first
  return unless notification
  self.channels.each do |channel_name, options|
    unless unsubscribed_from_channel?(notification.target, channel_name)
      channel = (channel_name.to_s + "_channel").camelize.constantize
      channel.deliver(notification, options)
    end
  end
end

.deliver_channels_aggregated(notifications) ⇒ Object

Deliver multiple notifications across each channel as an aggregate message.



205
206
207
208
209
210
211
212
# File 'app/models/notify_user/base_notification.rb', line 205

def self.deliver_channels_aggregated(notifications)
  self.channels.each do |channel_name, options|
      if options[:aggregate_per] != false && !unsubscribed_from_channel?(notifications.first.target, channel_name)
        channel = (channel_name.to_s + "_channel").camelize.constantize
        channel.deliver_aggregated(notifications, options)
      end
  end
end

.deliver_notification_channel(notification_id, channel_name) ⇒ Object

Deliver a single notification to a specific channel.



217
218
219
220
221
222
223
224
225
226
# File 'app/models/notify_user/base_notification.rb', line 217

def self.deliver_notification_channel(notification_id, channel_name)
  notification = self.where(id: notification_id).first
  return unless notification
  channel_options = channels[channel_name.to_sym]

  channel = (channel_name.to_s + "_channel").camelize.constantize
  unless self.unsubscribed_from_channel?(notification.target, channel_name)
    channel.deliver(notification, channel_options)
  end
end

.deliver_notifications_channel(notifications, channel_name) ⇒ Object

Deliver a aggregated notifications to a specific channel.



229
230
231
232
233
234
235
236
237
# File 'app/models/notify_user/base_notification.rb', line 229

def self.deliver_notifications_channel(notifications, channel_name)
  channel_options = channels[channel_name.to_sym]
  channel = (channel_name.to_s + "_channel").camelize.constantize

  #check if user unsubsribed from channel type
  unless self.unsubscribed_from_channel?(notifications.first.target, channel_name)
    channel.deliver_aggregated(notifications, channel_options)
  end
end

.for_target(target) ⇒ Object

Sending



158
159
160
161
# File 'app/models/notify_user/base_notification.rb', line 158

def self.for_target(target)
  where(target_id: target.id)
  .where(target_type: target.class.base_class)
end

.notify_aggregated(notification_id) ⇒ Object



260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
# File 'app/models/notify_user/base_notification.rb', line 260

def self.notify_aggregated(notification_id)
  notification = self.find(notification_id) # Raise an exception if not found.

  # Find any pending notifications with the same type and target, which can all be sent in one message.
  notifications = self.pending_aggregation_with(notification)
  
  notifications.map(&:mark_as_sent)
  notifications.map(&:save)

  return if notifications.empty?

  if notifications.length == 1
    # Despite waiting for more to aggregate, we only got one in the end.
    self.deliver_channels(notifications.first.id)
  else
    # We got several notifications while waiting, send them aggregated.
    self.deliver_channels_aggregated(notifications)
  end
end

.notify_aggregated_channel(notification_id, channel_name) ⇒ Object

notifies a single channel for aggregation



240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
# File 'app/models/notify_user/base_notification.rb', line 240

def self.notify_aggregated_channel(notification_id, channel_name)
  notification = self.find(notification_id) # Raise an exception if not found.

  # Find any pending notifications with the same type and target, which can all be sent in one message.
  notifications = self.pending_aggregation_with(notification)
  
  notifications.map(&:mark_as_sent)
  notifications.map(&:save)

  return if notifications.empty?

  if notifications.length == 1
    # Despite waiting for more to aggregate, we only got one in the end.
    self.deliver_notification_channel(notifications.first.id, channel_name)
  else
    # We got several notifications while waiting, send them aggregated.
    self.deliver_notifications_channel(notifications, channel_name)
  end
end

.pending_aggregation_with(notification) ⇒ Object



163
164
165
166
167
# File 'app/models/notify_user/base_notification.rb', line 163

def self.pending_aggregation_with(notification)
  where(type: notification.type)
  .for_target(notification.target)
  .where(state: :pending)
end

Instance Method Details

#aggregate_perObject

Aggregation



153
# File 'app/models/notify_user/base_notification.rb', line 153

class_attribute :aggregate_per

#aggregation_pending?Boolean

Returns:



169
170
171
172
173
# File 'app/models/notify_user/base_notification.rb', line 169

def aggregation_pending?
  # A notification of the same type, that would have an aggregation job associated with it,
  # already exists.
  return (self.class.pending_aggregation_with(self).where('id != ?', id).count > 0)
end

#channelsObject

Channels



131
# File 'app/models/notify_user/base_notification.rb', line 131

class_attribute :channels

#count_for_targetObject



62
63
64
# File 'app/models/notify_user/base_notification.rb', line 62

def count_for_target
  NotifyUser::BaseNotification.for_target(target).where('state IN (?)', ["sent", "pending"]).count
end

#deliver!Object

self.class.delay.deliver_channels(self.id)

end

end



184
185
186
187
188
189
190
# File 'app/models/notify_user/base_notification.rb', line 184

def deliver!
  unless user_has_unsubscribed?
    self.mark_as_sent
    self.save
    self.class.deliver_channels(self.id)
  end
end

#descriptionObject

Notification description



127
# File 'app/models/notify_user/base_notification.rb', line 127

class_attribute :description

#generate_unsubscribe_hashObject



121
122
123
124
# File 'app/models/notify_user/base_notification.rb', line 121

def generate_unsubscribe_hash
  #check if a hash already exists for that user otherwise create a new one
  return NotifyUser::UserHash.where(target_id: self.target.id).where(target_type: self.target.class.base_class).where(type: self.type).where(active: true).first || NotifyUser::UserHash.create(target: self.target, type: self.type, active: true)
end

#messageObject



66
67
68
69
70
71
72
# File 'app/models/notify_user/base_notification.rb', line 66

def message
  string = ActionView::Base.new(
         Rails.configuration.paths["app/views"]).render(
         :template => self.class.views[:mobile_sdk][:template_path].call(self), :formats => [:html], 
         :locals => { :params => self.params}, :layout => false)
  return ::CGI.unescapeHTML("#{string}")        
end

#mobile_message(length = 115) ⇒ Object



74
75
76
77
78
79
80
81
# File 'app/models/notify_user/base_notification.rb', line 74

def mobile_message(length=115)
  string = truncate(ActionView::Base.new(
         Rails.configuration.paths["app/views"]).render(
         :template => self.class.views[:mobile_sdk][:template_path].call(self), :formats => [:html], 
         :locals => { :params => self.params}, :layout => false), :length => length)

  return ::CGI.unescapeHTML("#{string}") 
end

#notifyObject

Send any Emails/SMS/APNS



102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
# File 'app/models/notify_user/base_notification.rb', line 102

def notify

  if save

    #if aggregation is false bypass aggregation completely
    self.channels.each do |channel_name, options|
      if(options[:aggregate_per] == false)
        self.class.delay.deliver_notification_channel(self.id, channel_name)    
      else
        if not aggregation_pending?
          self.class.delay_for(options[:aggregate_per] || self.aggregate_per).notify_aggregated_channel(self.id, channel_name)
        end
      end
    end

  end

end

#notify!Object



94
95
96
97
98
99
# File 'app/models/notify_user/base_notification.rb', line 94

def notify!
  save

  # Bang version of 'notify' ignores aggregation
  self.deliver!
end

#paramsObject



54
55
56
57
58
59
60
# File 'app/models/notify_user/base_notification.rb', line 54

def params
  if super.nil?
    {}
  else
    super.with_indifferent_access
  end
end

#to(user) ⇒ Object

Public Interface



84
85
86
87
# File 'app/models/notify_user/base_notification.rb', line 84

def to(user)
  self.target = user
  self
end

#with(*args) ⇒ Object



89
90
91
92
# File 'app/models/notify_user/base_notification.rb', line 89

def with(*args)
  self.params = args.reduce({}, :update)
  self
end