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



140
141
142
143
144
# File 'app/models/notify_user/base_notification.rb', line 140

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.



198
199
200
201
202
# File 'app/models/notify_user/base_notification.rb', line 198

def self.deliver_channels(notification_id)
  self.channels.each do |channel_name, options|
    self.deliver_notification_channel(notification_id, channel_name)
  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.find(notification_id) # Raise an exception if not found.

  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



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

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

.notify_aggregated_channel(notification_id, channel_name) ⇒ Object

Prepares a single channel for aggregation



240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
# 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



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

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

Instance Method Details

#aggregate_perObject

Aggregation



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

class_attribute :aggregate_per

#aggregation_pending?Boolean

Returns:

  • (Boolean)


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

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



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

class_attribute :channels

#count_for_targetObject

returns the global unread notification count for a user



73
74
75
# File 'app/models/notify_user/base_notification.rb', line 73

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

#deliverObject

Aggregates appropriately



171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
# File 'app/models/notify_user/base_notification.rb', line 171

def deliver
  if pending? and not user_has_unsubscribed?
    self.mark_as_sent!

    # 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
        # only notifies channels if no pending aggreagte notifications
        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

#deliver!Object

Sends immediately and without aggregation



190
191
192
193
194
195
# File 'app/models/notify_user/base_notification.rb', line 190

def deliver!
  if pending_no_aggregation? and not user_has_unsubscribed?
    self.mark_as_sent!
    self.class.deliver_channels(self.id)
  end
end

#descriptionObject

Notification description



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

class_attribute :description

#generate_unsubscribe_hashObject



116
117
118
119
# File 'app/models/notify_user/base_notification.rb', line 116

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



77
78
79
80
81
82
83
# File 'app/models/notify_user/base_notification.rb', line 77

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



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

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



111
112
113
114
# File 'app/models/notify_user/base_notification.rb', line 111

def notify
  # Sends with aggregation if enabled
  save
end

#notify!Object



105
106
107
108
# File 'app/models/notify_user/base_notification.rb', line 105

def notify!
  # Bang version of 'notify' ignores aggregation
  dont_aggregate!
end

#paramsObject



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

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

#to(user) ⇒ Object

Public Interface



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

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

#with(*args) ⇒ Object



100
101
102
103
# File 'app/models/notify_user/base_notification.rb', line 100

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