Module: ActivityNotification::NotificationApi

Extended by:
ActiveSupport::Concern
Included in:
ORM::ActiveRecord::Notification, ORM::Dynamoid::Notification, ORM::Mongoid::Notification
Defined in:
lib/activity_notification/apis/notification_api.rb

Overview

Defines API for notification included in Notification model.

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.all_index! ⇒ ActiveRecord_AssociationRelation<Notificaion>, Mongoid::Criteria<Notificaion>

Selects all notification index. ActivityNotification::Notification.all_index! is defined same as ActivityNotification::Notification.group_owners_only.latest_order

Examples:

Get all notification index of the @user

@notifications = @user.notifications.all_index!
@notifications = @user.notifications.group_owners_only.latest_order

Parameters:

  • reverse (Boolean) —

    If notification index will be ordered as earliest first

  • with_group_members (Boolean) —

    If notification index will include group members

Returns:

  • (ActiveRecord_AssociationRelation<Notificaion>, Mongoid::Criteria<Notificaion>) —

    Database query of filtered notifications



29
30
31
32
# File 'lib/activity_notification/apis/notification_api.rb', line 29

scope :all_index!,                        ->(reverse = false, with_group_members = false) {
  target_index = with_group_members ? self : group_owners_only
  reverse ? target_index.earliest_order : target_index.latest_order
}

.available_options ⇒ Array<Notificaion>

Returns available options for kinds of notify methods.

Returns:

  • (Array<Notificaion>) —

    Available options for kinds of notify methods



472
473
474
# File 'lib/activity_notification/apis/notification_api.rb', line 472

def available_options
  [:key, :group, :group_expiry_delay, :notifier, :parameters, :send_email, :send_later].freeze
end

.earliest ⇒ Notification

Returns earliest notification instance.

Returns:



162
163
164
# File 'lib/activity_notification/apis/notification_api.rb', line 162

def self.earliest
  earliest_order.first
end

.earliest! ⇒ Notification

Returns earliest notification instance. This method is to be overridden in implementation for each ORM.

Returns:



176
177
178
# File 'lib/activity_notification/apis/notification_api.rb', line 176

def self.earliest!
  earliest
end

.filtered_by_key ⇒ ActiveRecord_AssociationRelation<Notificaion>, Mongoid::Criteria<Notificaion>

Selects filtered notifications by key.

Examples:

Get filtered unopened notificatons of the @user with key 'comment.reply'

@notifications = @user.notifications.unopened_only.filtered_by_key('comment.reply')

Parameters:

  • key (String) —

    Key of the notification for filter

Returns:

  • (ActiveRecord_AssociationRelation<Notificaion>, Mongoid::Criteria<Notificaion>) —

    Database query of filtered notifications



89
# File 'lib/activity_notification/apis/notification_api.rb', line 89

scope :filtered_by_key,                   ->(key) { where(key: key) }

.filtered_by_options ⇒ ActiveRecord_AssociationRelation<Notificaion>, Mongoid::Criteria<Notificaion>

Selects filtered notifications by notifiable_type, group or key with filter options.

Examples:

Get filtered unopened notificatons of the @user for Comment notifiable class

@notifications = @user.notifications.unopened_only.filtered_by_options({ filtered_by_type: 'Comment' })

Get filtered unopened notificatons of the @user for @article as group

@notifications = @user.notifications.unopened_only.filtered_by_options({ filtered_by_group: @article })

Get filtered unopened notificatons of the @user for Article instance id=1 as group

@notifications = @user.notifications.unopened_only.filtered_by_options({ filtered_by_group_type: 'Article', filtered_by_group_id: '1' })

Get filtered unopened notificatons of the @user with key 'comment.reply'

@notifications = @user.notifications.unopened_only.filtered_by_options({ filtered_by_key: 'comment.reply' })

Get filtered unopened notificatons of the @user for Comment notifiable class with key 'comment.reply'

@notifications = @user.notifications.unopened_only.filtered_by_options({ filtered_by_type: 'Comment', filtered_by_key: 'comment.reply' })

Get custom filtered notificatons of the @user

@notifications = @user.notifications.unopened_only.filtered_by_options({ custom_filter: ["created_at >= ?", time.hour.ago] })

Parameters:

  • options (Hash) —

    Options for filter

Returns:

  • (ActiveRecord_AssociationRelation<Notificaion>, Mongoid::Criteria<Notificaion>) —

    Database query of filtered notifications



113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
# File 'lib/activity_notification/apis/notification_api.rb', line 113

scope :filtered_by_options,               ->(options = {}) {
  options = ActivityNotification.cast_to_indifferent_hash(options)
  filtered_notifications = all
  if options.has_key?(:filtered_by_type)
    filtered_notifications = filtered_notifications.filtered_by_type(options[:filtered_by_type])
  end
  if options.has_key?(:filtered_by_group)
    filtered_notifications = filtered_notifications.filtered_by_group(options[:filtered_by_group])
  end
  if options.has_key?(:filtered_by_group_type) && options.has_key?(:filtered_by_group_id)
    filtered_notifications = filtered_notifications
                             .where(group_type: options[:filtered_by_group_type], group_id: options[:filtered_by_group_id])
  end
  if options.has_key?(:filtered_by_key)
    filtered_notifications = filtered_notifications.filtered_by_key(options[:filtered_by_key])
  end
  if options.has_key?(:custom_filter)
    filtered_notifications = filtered_notifications.where(options[:custom_filter])
  end
  filtered_notifications
}

.filtered_by_target_type ⇒ ActiveRecord_AssociationRelation<Notificaion>, Mongoid::Criteria<Notificaion>

Selects filtered notifications by target_type.

Examples:

Get filtered unopened notificatons of User as target type

@notifications = ActivityNotification.Notification.unopened_only.filtered_by_target_type('User')

Parameters:

  • target_type (String) —

    Target type for filter

Returns:

  • (ActiveRecord_AssociationRelation<Notificaion>, Mongoid::Criteria<Notificaion>) —

    Database query of filtered notifications



73
# File 'lib/activity_notification/apis/notification_api.rb', line 73

scope :filtered_by_target_type,           ->(target_type) { where(target_type: target_type) }

.filtered_by_type ⇒ ActiveRecord_AssociationRelation<Notificaion>, Mongoid::Criteria<Notificaion>

Selects filtered notifications by notifiable_type.

Examples:

Get filtered unopened notificatons of the @user for Comment notifiable class

@notifications = @user.notifications.unopened_only.filtered_by_type('Comment')

Parameters:

  • notifiable_type (String) —

    Notifiable type for filter

Returns:

  • (ActiveRecord_AssociationRelation<Notificaion>, Mongoid::Criteria<Notificaion>) —

    Database query of filtered notifications



81
# File 'lib/activity_notification/apis/notification_api.rb', line 81

scope :filtered_by_type,                  ->(notifiable_type) { where(notifiable_type: notifiable_type) }

.generate_notification(target, notifiable, options = {}) ⇒ Object

Generates a notification

Parameters:

  • target (Object) —

    Target to send notification

  • notifiable (Object) —

    Notifiable instance

  • options (Hash) (defaults to: {}) —

    Options for notification

Options Hash (options):

  • :key (String) — default: notifiable.default_notification_key —

    Key of the notification

  • :group (Object) — default: nil —

    Group unit of the notifications

  • :notifier (Object) — default: nil —

    Notifier of the notifications

  • :parameters (Hash) — default: {} —

    Additional parameters of the notifications



411
412
413
414
415
416
417
# File 'lib/activity_notification/apis/notification_api.rb', line 411

def generate_notification(target, notifiable, options = {})
  key = options[:key] || notifiable.default_notification_key
  if target.subscribes_to_notification?(key)
    # Store notification
    notification = store_notification(target, notifiable, key, options)
  end
end

.group_member_exists?(notifications) ⇒ Boolean

Returns if group member of the notifications exists. This method is designed to be called from controllers or views to avoid N+1.

Parameters:

  • notifications (Array<Notificaion>, ActiveRecord_AssociationRelation<Notificaion>, Mongoid::Criteria<Notificaion>) —

    Array or database query of the notifications to test member exists

Returns:

  • (Boolean) —

    If group member of the notifications exists



444
445
446
# File 'lib/activity_notification/apis/notification_api.rb', line 444

def group_member_exists?(notifications)
  notifications.present? and group_members_of_owner_ids_only(notifications.map(&:id)).exists?
end

.latest ⇒ Notification

Returns latest notification instance.

Returns:



156
157
158
# File 'lib/activity_notification/apis/notification_api.rb', line 156

def self.latest
  latest_order.first
end

.latest! ⇒ Notification

Returns latest notification instance. This method is to be overridden in implementation for each ORM.

Returns:



169
170
171
# File 'lib/activity_notification/apis/notification_api.rb', line 169

def self.latest!
  latest
end

.notify(target_type, notifiable, options = {}) ⇒ Array<Notificaion> Also known as: notify_now

Generates notifications to configured targets with notifiable model.

Examples:

Use with target_type as Symbol

ActivityNotification::Notification.notify :users, @comment

Use with target_type as String

ActivityNotification::Notification.notify 'User', @comment

Use with target_type as Class

ActivityNotification::Notification.notify User, @comment

Use with options

ActivityNotification::Notification.notify :users, @comment, key: 'custom.comment', group: @comment.article
ActivityNotification::Notification.notify :users, @comment, parameters: { reply_to: @comment.reply_to }, send_later: false

Parameters:

  • target_type (Symbol, String, Class) —

    Type of target

  • notifiable (Object) —

    Notifiable instance

  • options (Hash) (defaults to: {}) —

    Options for notifications

Options Hash (options):

  • :key (String) — default: notifiable.default_notification_key —

    Key of the notification

  • :group (Object) — default: nil —

    Group unit of the notifications

  • :group_expiry_delay (ActiveSupport::Duration) — default: nil —

    Expiry period of a notification group

  • :notifier (Object) — default: nil —

    Notifier of the notifications

  • :parameters (Hash) — default: {} —

    Additional parameters of the notifications

  • :notify_later (Boolean) — default: false —

    Whether it generates notifications asynchronously

  • :send_email (Boolean) — default: true —

    Whether it sends notification email

  • :send_later (Boolean) — default: true —

    Whether it sends notification email asynchronously

  • :broadcast_action_cable (Boolean) — default: true —

    Whether it broadcasts notification to ActionCable channel

  • :action_cable_rendering (Hash) — default: {fallback: :default} —

    Options for rendering params used by ActionCable, e.g. :text or :default etc. See also Renderable#render.

  • :publish_optional_targets (Boolean) — default: true —

    Whether it publishes notification to optional targets

  • :pass_full_options (Boolean) — default: false —

    Whether it passes full options to notifiable.notification_targets, not a key only

  • :optional_targets (Hash<String, Hash>) — default: {} —

    Options for optional targets, keys are optional target name (:amazon_sns or :slack etc) and values are options

Returns:

  • (Array<Notificaion>) —

    Array of generated notifications



226
227
228
229
230
231
232
233
234
235
# File 'lib/activity_notification/apis/notification_api.rb', line 226

def notify(target_type, notifiable, options = {})
  if options[:notify_later]
    notify_later(target_type, notifiable, options)
  else
    targets = notifiable.notification_targets(target_type, options[:pass_full_options] ? options : options[:key])
    unless targets.blank?
      notify_all(targets, notifiable, options)
    end
  end
end

.notify_all(targets, notifiable, options = {}) ⇒ Array<Notificaion> Also known as: notify_all_now

Generates notifications to specified targets.

Examples:

Notify to all users

ActivityNotification::Notification.notify_all User.all, @comment

Parameters:

  • targets (Array<Object>) —

    Targets to send notifications

  • notifiable (Object) —

    Notifiable instance

  • options (Hash) (defaults to: {}) —

    Options for notifications

Options Hash (options):

  • :key (String) — default: notifiable.default_notification_key —

    Key of the notification

  • :group (Object) — default: nil —

    Group unit of the notifications

  • :group_expiry_delay (ActiveSupport::Duration) — default: nil —

    Expiry period of a notification group

  • :notifier (Object) — default: nil —

    Notifier of the notifications

  • :parameters (Hash) — default: {} —

    Additional parameters of the notifications

  • :notify_later (Boolean) — default: false —

    Whether it generates notifications asynchronously

  • :send_email (Boolean) — default: true —

    Whether it sends notification email

  • :send_later (Boolean) — default: true —

    Whether it sends notification email asynchronously

  • :broadcast_action_cable (Boolean) — default: true —

    Whether it broadcasts notification to ActionCable channel

  • :action_cable_rendering (Hash) — default: {fallback: :default} —

    Options for rendering params used by ActionCable, e.g. :text or :default etc. See also Renderable#render.

  • :publish_optional_targets (Boolean) — default: true —

    Whether it publishes notification to optional targets

  • :optional_targets (Hash<String, Hash>) — default: {} —

    Options for optional targets, keys are optional target name (:amazon_sns or :slack etc) and values are options

Returns:

  • (Array<Notificaion>) —

    Array of generated notifications



293
294
295
296
297
298
299
# File 'lib/activity_notification/apis/notification_api.rb', line 293

def notify_all(targets, notifiable, options = {})
  if options[:notify_later]
    notify_all_later(targets, notifiable, options)
  else
    targets.map { |target| notify_to(target, notifiable, options) }
  end
end

.notify_all_later(targets, notifiable, options = {}) ⇒ Array<Notificaion>

Generates notifications to specified targets later by ActiveJob queue.

Examples:

Notify to all users later

ActivityNotification::Notification.notify_all_later User.all, @comment

Parameters:

  • targets (Array<Object>) —

    Targets to send notifications

  • notifiable (Object) —

    Notifiable instance

  • options (Hash) (defaults to: {}) —

    Options for notifications

Options Hash (options):

  • :key (String) — default: notifiable.default_notification_key —

    Key of the notification

  • :group (Object) — default: nil —

    Group unit of the notifications

  • :group_expiry_delay (ActiveSupport::Duration) — default: nil —

    Expiry period of a notification group

  • :notifier (Object) — default: nil —

    Notifier of the notifications

  • :parameters (Hash) — default: {} —

    Additional parameters of the notifications

  • :send_email (Boolean) — default: true —

    Whether it sends notification email

  • :send_later (Boolean) — default: true —

    Whether it sends notification email asynchronously

  • :broadcast_action_cable (Boolean) — default: true —

    Whether it broadcasts notification to ActionCable channel

  • :action_cable_rendering (Hash) — default: {fallback: :default} —

    Options for rendering params used by ActionCable, e.g. :text or :default etc. See also Renderable#render.

  • :publish_optional_targets (Boolean) — default: true —

    Whether it publishes notification to optional targets

  • :optional_targets (Hash<String, Hash>) — default: {} —

    Options for optional targets, keys are optional target name (:amazon_sns or :slack etc) and values are options

Returns:

  • (Array<Notificaion>) —

    Array of generated notifications



322
323
324
325
# File 'lib/activity_notification/apis/notification_api.rb', line 322

def notify_all_later(targets, notifiable, options = {})
  options.delete(:notify_later)
  ActivityNotification::NotifyAllJob.perform_later(targets, notifiable, options)
end

.notify_later(target_type, notifiable, options = {}) ⇒ Array<Notificaion>

Generates notifications to configured targets with notifiable model later by ActiveJob queue.

Examples:

Use with target_type as Symbol

ActivityNotification::Notification.notify_later :users, @comment

Use with target_type as String

ActivityNotification::Notification.notify_later 'User', @comment

Use with target_type as Class

ActivityNotification::Notification.notify_later User, @comment

Use with options

ActivityNotification::Notification.notify_later :users, @comment, key: 'custom.comment', group: @comment.article
ActivityNotification::Notification.notify_later :users, @comment, parameters: { reply_to: @comment.reply_to }, send_later: false

Parameters:

  • target_type (Symbol, String, Class) —

    Type of target

  • notifiable (Object) —

    Notifiable instance

  • options (Hash) (defaults to: {}) —

    Options for notifications

Options Hash (options):

  • :key (String) — default: notifiable.default_notification_key —

    Key of the notification

  • :group (Object) — default: nil —

    Group unit of the notifications

  • :group_expiry_delay (ActiveSupport::Duration) — default: nil —

    Expiry period of a notification group

  • :notifier (Object) — default: nil —

    Notifier of the notifications

  • :parameters (Hash) — default: {} —

    Additional parameters of the notifications

  • :send_email (Boolean) — default: true —

    Whether it sends notification email

  • :send_later (Boolean) — default: true —

    Whether it sends notification email asynchronously

  • :broadcast_action_cable (Boolean) — default: true —

    Whether it broadcasts notification to ActionCable channel

  • :action_cable_rendering (Hash) — default: {fallback: :default} —

    Options for rendering params used by ActionCable, e.g. :text or :default etc. See also Renderable#render.

  • :publish_optional_targets (Boolean) — default: true —

    Whether it publishes notification to optional targets

  • :pass_full_options (Boolean) — default: false —

    Whether it passes full options to notifiable.notification_targets, not a key only

  • :optional_targets (Hash<String, Hash>) — default: {} —

    Options for optional targets, keys are optional target name (:amazon_sns or :slack etc) and values are options

Returns:

  • (Array<Notificaion>) —

    Array of generated notifications



266
267
268
269
270
# File 'lib/activity_notification/apis/notification_api.rb', line 266

def notify_later(target_type, notifiable, options = {})
  target_type = target_type.to_s if target_type.is_a? Symbol
  options.delete(:notify_later)
  ActivityNotification::NotifyJob.perform_later(target_type, notifiable, options)
end

.notify_later_to(target, notifiable, options = {}) ⇒ Notification

Generates notifications to one target later by ActiveJob queue.

Examples:

Notify to one user later

ActivityNotification::Notification.notify_later_to @comment.auther, @comment

Parameters:

  • target (Object) —

    Target to send notifications

  • notifiable (Object) —

    Notifiable instance

  • options (Hash) (defaults to: {}) —

    Options for notifications

Options Hash (options):

  • :key (String) — default: notifiable.default_notification_key —

    Key of the notification

  • :group (Object) — default: nil —

    Group unit of the notifications

  • :group_expiry_delay (ActiveSupport::Duration) — default: nil —

    Expiry period of a notification group

  • :notifier (Object) — default: nil —

    Notifier of the notifications

  • :parameters (Hash) — default: {} —

    Additional parameters of the notifications

  • :send_email (Boolean) — default: true —

    Whether it sends notification email

  • :send_later (Boolean) — default: true —

    Whether it sends notification email asynchronously

  • :broadcast_action_cable (Boolean) — default: true —

    Whether it broadcast∂s notification to ActionCable channel

  • :action_cable_rendering (Hash) — default: {fallback: :default} —

    Options for rendering params used by ActionCable, e.g. :text or :default etc. See also Renderable#render.

  • :publish_optional_targets (Boolean) — default: true —

    Whether it publishes notification to optional targets

  • :optional_targets (Hash<String, Hash>) — default: {} —

    Options for optional targets, keys are optional target name (:amazon_sns or :slack etc) and values are options

Returns:



398
399
400
401
# File 'lib/activity_notification/apis/notification_api.rb', line 398

def notify_later_to(target, notifiable, options = {})
  options.delete(:notify_later)
  ActivityNotification::NotifyToJob.perform_later(target, notifiable, options)
end

.notify_to(target, notifiable, options = {}) ⇒ Notification Also known as: notify_now_to

Generates notifications to one target.

Examples:

Notify to one user

ActivityNotification::Notification.notify_to @comment.auther, @comment

Parameters:

  • target (Object) —

    Target to send notifications

  • notifiable (Object) —

    Notifiable instance

  • options (Hash) (defaults to: {}) —

    Options for notifications

Options Hash (options):

  • :key (String) — default: notifiable.default_notification_key —

    Key of the notification

  • :group (Object) — default: nil —

    Group unit of the notifications

  • :group_expiry_delay (ActiveSupport::Duration) — default: nil —

    Expiry period of a notification group

  • :notifier (Object) — default: nil —

    Notifier of the notifications

  • :parameters (Hash) — default: {} —

    Additional parameters of the notifications

  • :notify_later (Boolean) — default: false —

    Whether it generates notifications asynchronously

  • :send_email (Boolean) — default: true —

    Whether it sends notification email

  • :send_later (Boolean) — default: true —

    Whether it sends notification email asynchronously

  • :broadcast_action_cable (Boolean) — default: true —

    Whether it broadcasts notification to ActionCable channel

  • :action_cable_rendering (Hash) — default: {fallback: :default} —

    Options for rendering params used by ActionCable, e.g. :text or :default etc. See also Renderable#render.

  • :publish_optional_targets (Boolean) — default: true —

    Whether it publishes notification to optional targets

  • :optional_targets (Hash<String, Hash>) — default: {} —

    Options for optional targets, keys are optional target name (:amazon_sns or :slack etc) and values are options

Returns:



348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
# File 'lib/activity_notification/apis/notification_api.rb', line 348

def notify_to(target, notifiable, options = {})
  if options[:notify_later]
    notify_later_to(target, notifiable, options)
  else
    send_email               = options.has_key?(:send_email)               ? options[:send_email]               : true
    send_later               = options.has_key?(:send_later)               ? options[:send_later]               : true
    broadcast_action_cable   = options.has_key?(:broadcast_action_cable)   ? options[:broadcast_action_cable]   : true
    publish_optional_targets = options.has_key?(:publish_optional_targets) ? options[:publish_optional_targets] : true
    # Generate notification
    notification = generate_notification(target, notifiable, options)
    # Send notification email
    if notification.present? && send_email
      notification.send_notification_email({ send_later: send_later })
    end
    # Broadcast to ActionCable subscribers
    if notification.present? && broadcast_action_cable
      action_cable_rendering_options = options[:action_cable_rendering] || {}
      action_cable_rendering_options[:fallback] = action_cable_rendering_options[:fallback] || :default
      notification.broadcast_to_action_cable_channel(action_cable_rendering_options)
    end
    # Publish to optional targets
    if notification.present? && publish_optional_targets
      notification.publish_to_optional_targets(options[:optional_targets] || {})
    end
    # Return generated notification
    notification
  end
end

.open_all_of(target, options = {}) ⇒ Integer

TODO:

Add filter option

Opens all notifications of the target.

Parameters:

  • target (Object) —

    Target of the notifications to open

  • options (Hash) (defaults to: {}) —

    Options for opening notifications

Options Hash (options):

  • :opened_at (DateTime) — default: Time.current —

    Time to set to opened_at of the notification record

  • :filtered_by_type (String) — default: nil —

    Notifiable type for filter

  • :filtered_by_group (Object) — default: nil —

    Group instance for filter

  • :filtered_by_group_type (String) — default: nil —

    Group type for filter, valid with :filtered_by_group_id

  • :filtered_by_group_id (String) — default: nil —

    Group instance id for filter, valid with :filtered_by_group_type

  • :filtered_by_key (String) — default: nil —

    Key of the notification for filter

Returns:

  • (Integer) —

    Number of opened notification records



431
432
433
434
435
436
437
# File 'lib/activity_notification/apis/notification_api.rb', line 431

def open_all_of(target, options = {})
  opened_at = options[:opened_at] || Time.current
  target_unopened_notifications = target.notifications.unopened_only.filtered_by_options(options)
  unopened_notification_count = target_unopened_notifications.count
  target_unopened_notifications.update_all(opened_at: opened_at)
  unopened_notification_count
end

.opened_index ⇒ ActiveRecord_AssociationRelation<Notificaion>, Mongoid::Criteria<Notificaion>

Selects unopened notification index. ActivityNotification::Notification.opened_index(limit) is defined same as ActivityNotification::Notification.opened_only(limit).group_owners_only.latest_order

Examples:

Get unopened notificaton index of the @user with limit 10

@notifications = @user.notifications.opened_index(10)
@notifications = @user.notifications.opened_only(10).group_owners_only.latest_order

Parameters:

  • limit (Integer) —

    Limit to query for opened notifications

  • reverse (Boolean) —

    If notification index will be ordered as earliest first

  • with_group_members (Boolean) —

    If notification index will include group members

Returns:

  • (ActiveRecord_AssociationRelation<Notificaion>, Mongoid::Criteria<Notificaion>) —

    Database query of filtered notifications



62
63
64
65
# File 'lib/activity_notification/apis/notification_api.rb', line 62

scope :opened_index,                      ->(limit, reverse = false, with_group_members = false) {
  target_index = with_group_members ? opened_only(limit) : opened_only(limit).group_owners_only
  reverse ? target_index.earliest_order : target_index.latest_order
}

.send_batch_notification_email(target, notifications, options = {}) ⇒ Mail::Message, ActionMailer::DeliveryJob|NilClass

Sends batch notification email to the target.

Parameters:

  • target (Object) —

    Target of batch notification email

  • notifications (Array<Notification>) —

    Target notifications to send batch notification email

  • options (Hash) (defaults to: {}) —

    Options for notification email

Options Hash (options):

  • :send_later (Boolean) — default: false —

    If it sends notification email asynchronously

  • :fallback (String, Symbol) — default: :batch_default —

    Fallback template to use when MissingTemplate is raised

  • :batch_key (String) — default: nil —

    Key of the batch notification email, a key of the first notification will be used if not specified

Returns:

  • (Mail::Message, ActionMailer::DeliveryJob|NilClass) —

    Email message or its delivery job, return NilClass for wrong target



457
458
459
460
461
462
463
464
465
466
467
# File 'lib/activity_notification/apis/notification_api.rb', line 457

def send_batch_notification_email(target, notifications, options = {})
  notifications.blank? and return
  batch_key = options[:batch_key] || notifications.first.key
  if target.batch_notification_email_allowed?(batch_key) &&
     target.subscribes_to_notification_email?(batch_key)
    send_later = options.has_key?(:send_later) ? options[:send_later] : true
    send_later ?
      @@notification_mailer.send_batch_notification_email(target, notifications, batch_key, options).deliver_later :
      @@notification_mailer.send_batch_notification_email(target, notifications, batch_key, options).deliver_now
  end
end

.set_notification_mailer ⇒ Object

Defines mailer class to send notification



477
478
479
# File 'lib/activity_notification/apis/notification_api.rb', line 477

def set_notification_mailer
  @@notification_mailer = ActivityNotification.config.mailer.constantize
end

.uniq_keys ⇒ Array<String>

Selects unique keys from query for notifications.

Returns:

  • (Array<String>) —

    Array of notification unique keys



182
183
184
185
186
187
188
# File 'lib/activity_notification/apis/notification_api.rb', line 182

def self.uniq_keys
  ## select method cannot be chained with order by other columns like created_at
  # select(:key).distinct.pluck(:key)
  ## distinct method cannot keep original sort
  # distinct(:key)
  pluck(:key).uniq
end

.unopened_index ⇒ ActiveRecord_AssociationRelation<Notificaion>, Mongoid::Criteria<Notificaion>

Selects unopened notification index. ActivityNotification::Notification.unopened_index is defined same as ActivityNotification::Notification.unopened_only.group_owners_only.latest_order

Examples:

Get unopened notificaton index of the @user

@notifications = @user.notifications.unopened_index
@notifications = @user.notifications.unopened_only.group_owners_only.latest_order

Parameters:

  • reverse (Boolean) —

    If notification index will be ordered as earliest first

  • with_group_members (Boolean) —

    If notification index will include group members

Returns:

  • (ActiveRecord_AssociationRelation<Notificaion>, Mongoid::Criteria<Notificaion>) —

    Database query of filtered notifications



45
46
47
48
# File 'lib/activity_notification/apis/notification_api.rb', line 45

scope :unopened_index,                    ->(reverse = false, with_group_members = false) {
  target_index = with_group_members ? unopened_only : unopened_only.group_owners_only
  reverse ? target_index.earliest_order : target_index.latest_order
}

.valid_group_owner(target, notifiable, key, group, group_expiry_delay) ⇒ Notificaion

Returns valid group owner within the expiration period

Parameters:

  • target (Object) —

    Target to send notifications

  • notifiable (Object) —

    Notifiable instance

  • key (String) —

    Key of the notification

  • group (Object) —

    Group unit of the notifications

  • group_expiry_delay (ActiveSupport::Duration) —

    Expiry period of a notification group

Returns:

  • (Notificaion) —

    Valid group owner within the expiration period



489
490
491
492
493
494
495
496
497
498
# File 'lib/activity_notification/apis/notification_api.rb', line 489

def valid_group_owner(target, notifiable, key, group, group_expiry_delay)
  return nil if group.blank?
  # Bundle notification group by target, notifiable_type, group and key
  # Different notifiable.id can be made in a same group
  group_owner_notifications = filtered_by_target(target).filtered_by_type(notifiable.to_class_name).filtered_by_key(key)
                             .filtered_by_group(group).group_owners_only.unopened_only
  group_expiry_delay.present? ?
    group_owner_notifications.within_expiration_only(group_expiry_delay).earliest :
    group_owner_notifications.earliest
end

Instance Method Details

#broadcast_to_action_cable_channel(params = {}) ⇒ Object

Broadcast to ActionCable subscribers Do nothing with Rails < 5.0

Parameters:

  • params (Hash) (defaults to: {}) —

    Parameters for rendering notifications



563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
# File 'lib/activity_notification/apis/notification_api.rb', line 563

def broadcast_to_action_cable_channel(params = {})
  if target.notification_action_cable_allowed?(notifiable, key) &&
    notifiable.notification_action_cable_allowed?(target, key)
    target_channel_name = "#{ActivityNotification.config.notification_channel_prefix}_#{target_type}#{ActivityNotification.config.composite_key_delimiter}#{target_id}"
    index_options = params.slice(:filter, :limit, :without_grouping, :with_group_members, :filtered_by_type, :filtered_by_group_type, :filtered_by_group_id, :filtered_by_key)
    ActionCable.server.broadcast(target_channel_name,
      id:                          id,
      view:                        render(ActivityNotification::NotificationsController.renderer, params),
      text:                        text(params),
      notifiable_path:             notifiable_path,
      group_owner_id:              group_owner_id,
      group_owner_view:            group_owner? ? nil : group_owner.render(ActivityNotification::NotificationsController.renderer, params),
      unopened_notification_count: target.unopened_notification_count(index_options)
    )
  end
end

#earliest_order ⇒ ActiveRecord_AssociationRelation<Notificaion>, Mongoid::Criteria<Notificaion>

Orders by earliest (older) first as created_at: :asc.

Returns:

  • (ActiveRecord_AssociationRelation<Notificaion>, Mongoid::Criteria<Notificaion>) —

    Database query of notifications ordered by earliest first



141
# File 'lib/activity_notification/apis/notification_api.rb', line 141

scope :earliest_order,                    -> { order(created_at: :asc) }

#earliest_order! ⇒ ActiveRecord_AssociationRelation<Notificaion>, Mongoid::Criteria<Notificaion>

Orders by earliest (older) first as created_at: :asc. This method is to be overridden in implementation for each ORM.

Returns:

  • (ActiveRecord_AssociationRelation<Notificaion>, Mongoid::Criteria<Notificaion>) —

    Database query of notifications ordered by earliest first



152
# File 'lib/activity_notification/apis/notification_api.rb', line 152

scope :earliest_order!,                   -> { earliest_order }

#email_subscribed? ⇒ Boolean

Returns if the target subscribes this notification email.

Returns:

  • (Boolean) —

    If the target subscribes the notification



756
757
758
# File 'lib/activity_notification/apis/notification_api.rb', line 756

def email_subscribed?
  target.subscribes_to_notification_email?(key)
end

#group_member? ⇒ Boolean

Returns if the notification is group member belonging to owner.

Returns:

  • (Boolean) —

    If the notification is group member



655
656
657
# File 'lib/activity_notification/apis/notification_api.rb', line 655

def group_member?
  group_owner_id.present?
end

#group_member_count(limit = ActivityNotification.config.opened_index_limit) ⇒ Integer

Returns count of group members of the notification. This method is designed to cache group by query result to avoid N+1 call.

Parameters:

  • limit (Integer) (defaults to: ActivityNotification.config.opened_index_limit) —

    Limit to query for opened notifications

Returns:

  • (Integer) —

    Count of group members of the notification



684
685
686
# File 'lib/activity_notification/apis/notification_api.rb', line 684

def group_member_count(limit = ActivityNotification.config.opened_index_limit)
  meta_group_member_count(:opened_group_member_count, :unopened_group_member_count, limit)
end

#group_member_exists?(limit = ActivityNotification.config.opened_index_limit) ⇒ Boolean

Returns if group member of the notification exists. This method is designed to cache group by query result to avoid N+1 call.

Parameters:

  • limit (Integer) (defaults to: ActivityNotification.config.opened_index_limit) —

    Limit to query for opened notifications

Returns:

  • (Boolean) —

    If group member of the notification exists



664
665
666
# File 'lib/activity_notification/apis/notification_api.rb', line 664

def group_member_exists?(limit = ActivityNotification.config.opened_index_limit)
  group_member_count(limit) > 0
end

#group_member_notifier_count(limit = ActivityNotification.config.opened_index_limit) ⇒ Integer

Returns count of group member notifiers of the notification not including group owner notifier. It always returns 0 if group owner notifier is blank. It counts only the member notifier of the same type with group owner notifier. This method is designed to cache group by query result to avoid N+1 call.

Parameters:

  • limit (Integer) (defaults to: ActivityNotification.config.opened_index_limit) —

    Limit to query for opened notifications

Returns:

  • (Integer) —

    Count of group member notifiers of the notification



704
705
706
# File 'lib/activity_notification/apis/notification_api.rb', line 704

def group_member_notifier_count(limit = ActivityNotification.config.opened_index_limit)
  meta_group_member_count(:opened_group_member_notifier_count, :unopened_group_member_notifier_count, limit)
end

#group_member_notifier_exists?(limit = ActivityNotification.config.opened_index_limit) ⇒ Boolean

Returns if group member notifier except group owner notifier exists. It always returns false if group owner notifier is blank. It counts only the member notifier of the same type with group owner notifier. This method is designed to cache group by query result to avoid N+1 call.

Parameters:

  • limit (Integer) (defaults to: ActivityNotification.config.opened_index_limit) —

    Limit to query for opened notifications

Returns:

  • (Boolean) —

    If group member of the notification exists



675
676
677
# File 'lib/activity_notification/apis/notification_api.rb', line 675

def group_member_notifier_exists?(limit = ActivityNotification.config.opened_index_limit)
  group_member_notifier_count(limit) > 0
end

#group_notification_count(limit = ActivityNotification.config.opened_index_limit) ⇒ Integer

Returns count of group notifications including owner and members. This method is designed to cache group by query result to avoid N+1 call.

Parameters:

  • limit (Integer) (defaults to: ActivityNotification.config.opened_index_limit) —

    Limit to query for opened notifications

Returns:

  • (Integer) —

    Count of group notifications including owner and members



693
694
695
# File 'lib/activity_notification/apis/notification_api.rb', line 693

def group_notification_count(limit = ActivityNotification.config.opened_index_limit)
  group_member_count(limit) + 1
end

#group_notifier_count(limit = ActivityNotification.config.opened_index_limit) ⇒ Integer

Returns count of group member notifiers including group owner notifier. It always returns 0 if group owner notifier is blank. This method is designed to cache group by query result to avoid N+1 call.

Parameters:

  • limit (Integer) (defaults to: ActivityNotification.config.opened_index_limit) —

    Limit to query for opened notifications

Returns:

  • (Integer) —

    Count of group notifications including owner and members



714
715
716
717
# File 'lib/activity_notification/apis/notification_api.rb', line 714

def group_notifier_count(limit = ActivityNotification.config.opened_index_limit)
  notification = group_member? && group_owner.present? ? group_owner : self
  notification.notifier.present? ? group_member_notifier_count(limit) + 1 : 0
end

#group_owner? ⇒ Boolean

Returns if the notification is group owner.

Returns:

  • (Boolean) —

    If the notification is group owner



648
649
650
# File 'lib/activity_notification/apis/notification_api.rb', line 648

def group_owner?
  !group_member?
end

#latest_group_member ⇒ Notificaion

Returns the latest group member notification instance of this notification. If this group owner has no group members, group owner instance self will be returned.

Returns:

  • (Notificaion) —

    Notification instance of the latest group member notification



723
724
725
726
# File 'lib/activity_notification/apis/notification_api.rb', line 723

def latest_group_member
  notification = group_member? && group_owner.present? ? group_owner : self
  notification.group_member_exists? ? notification.group_members.latest : self
end

#latest_order ⇒ ActiveRecord_AssociationRelation<Notificaion>, Mongoid::Criteria<Notificaion>

Orders by latest (newest) first as created_at: :desc.

Returns:

  • (ActiveRecord_AssociationRelation<Notificaion>, Mongoid::Criteria<Notificaion>) —

    Database query of notifications ordered by latest first



137
# File 'lib/activity_notification/apis/notification_api.rb', line 137

scope :latest_order,                      -> { order(created_at: :desc) }

#latest_order! ⇒ ActiveRecord_AssociationRelation<Notificaion>, Mongoid::Criteria<Notificaion>

Orders by latest (newest) first as created_at: :desc. This method is to be overridden in implementation for each ORM.

Parameters:

  • reverse (Boolean) —

    If notifications will be ordered as earliest first

Returns:

  • (ActiveRecord_AssociationRelation<Notificaion>, Mongoid::Criteria<Notificaion>) —

    Database query of ordered notifications



147
# File 'lib/activity_notification/apis/notification_api.rb', line 147

scope :latest_order!,                     ->(reverse = false) { reverse ? earliest_order : latest_order }

#notifiable_path ⇒ String

Returns notifiable_path to move after opening notification with notifiable.notifiable_path.

Returns:

  • (String) —

    Notifiable path URL to move after opening notification



743
744
745
746
# File 'lib/activity_notification/apis/notification_api.rb', line 743

def notifiable_path
  notifiable.present? or raise ActiveRecord::RecordNotFound.new("Couldn't find notifiable #{notifiable_type}")
  notifiable.notifiable_path(target_type, key)
end

#open!(options = {}) ⇒ Integer

Opens the notification.

Parameters:

  • options (Hash) (defaults to: {}) —

    Options for opening notifications

Options Hash (options):

  • :opened_at (DateTime) — default: Time.current —

    Time to set to opened_at of the notification record

  • :with_members (Boolean) — default: true —

    If it opens notifications including group members

Returns:

  • (Integer) —

    Number of opened notification records



621
622
623
624
625
626
627
628
629
# File 'lib/activity_notification/apis/notification_api.rb', line 621

def open!(options = {})
  opened? and return 0
  opened_at    = options[:opened_at] || Time.current
  with_members = options.has_key?(:with_members) ? options[:with_members] : true
  unopened_member_count = with_members ? group_members.unopened_only.count : 0
  group_members.update_all(opened_at: opened_at) if with_members
  update(opened_at: opened_at)
  unopened_member_count + 1
end

#opened? ⇒ Boolean

Returns if the notification is opened.

Returns:

  • (Boolean) —

    If the notification is opened



641
642
643
# File 'lib/activity_notification/apis/notification_api.rb', line 641

def opened?
  opened_at.present?
end

#optional_target_names ⇒ Array<Symbol>

Returns optional_target names of the notification from configured field or overridden method.

Returns:

  • (Array<Symbol>) —

    Array of optional target names



775
776
777
# File 'lib/activity_notification/apis/notification_api.rb', line 775

def optional_target_names
  notifiable.optional_target_names(target.to_resources_name, key)
end

#optional_target_subscribed?(optional_target_name) ⇒ Boolean

Returns if the target subscribes this notification email.

Parameters:

  • optional_target_name (String, Symbol) —

    Class name of the optional target implementation (e.g. :amazon_sns, :slack)

Returns:

  • (Boolean) —

    If the target subscribes the specified optional target of the notification



763
764
765
# File 'lib/activity_notification/apis/notification_api.rb', line 763

def optional_target_subscribed?(optional_target_name)
  target.subscribes_to_optional_target?(key, optional_target_name)
end

#optional_targets ⇒ Array<ActivityNotification::OptionalTarget::Base>

Returns optional_targets of the notification from configured field or overridden method.

Returns:



769
770
771
# File 'lib/activity_notification/apis/notification_api.rb', line 769

def optional_targets
  notifiable.optional_targets(target.to_resources_name, key)
end

#prepare_to_store ⇒ Object

Returns prepared notification object to store

Returns:

  • (Object) —

    prepared notification object to store



520
521
522
# File 'lib/activity_notification/apis/notification_api.rb', line 520

def prepare_to_store
  self
end

#publish_to_optional_targets(options = {}) ⇒ Hash

Publishes notification to the optional targets.

Parameters:

  • options (Hash) (defaults to: {}) —

    Options for optional targets

Returns:

  • (Hash) —

    Result of publishing to optional target



603
604
605
606
607
608
609
610
611
612
613
# File 'lib/activity_notification/apis/notification_api.rb', line 603

def publish_to_optional_targets(options = {})
  notifiable.optional_targets(target.to_resources_name, key).map { |optional_target|
    optional_target_name = optional_target.to_optional_target_name
    if optional_target_subscribed?(optional_target_name)
      optional_target.notify(self, options[optional_target_name] || {})
      [optional_target_name, true]
    else
      [optional_target_name, false]
    end
  }.to_h
end

#remove_from_group ⇒ Notificaion

Remove from notification group and make a new group owner.

Returns:

  • (Notificaion) —

    New group owner instance of the notification group



731
732
733
734
735
736
737
738
# File 'lib/activity_notification/apis/notification_api.rb', line 731

def remove_from_group
  new_group_owner = group_members.earliest
  if new_group_owner.present?
    new_group_owner.update(group_owner_id: nil)
    group_members.update_all(group_owner_id: new_group_owner.id)
  end
  new_group_owner
end

#send_notification_email(options = {}) ⇒ Mail::Message, ActionMailer::DeliveryJob

Sends notification email to the target.

Parameters:

  • options (Hash) (defaults to: {}) —

    Options for notification email

Options Hash (options):

  • :send_later (Boolean) —

    If it sends notification email asynchronously

  • :fallback (String, Symbol) — default: :default —

    Fallback template to use when MissingTemplate is raised

Returns:

  • (Mail::Message, ActionMailer::DeliveryJob) —

    Email message or its delivery job



530
531
532
533
534
535
536
537
538
539
# File 'lib/activity_notification/apis/notification_api.rb', line 530

def send_notification_email(options = {})
  if target.notification_email_allowed?(notifiable, key) &&
     notifiable.notification_email_allowed?(target, key) &&
     email_subscribed?
    send_later = options.has_key?(:send_later) ? options[:send_later] : true
    send_later ?
      @@notification_mailer.send_notification_email(self, options).deliver_later :
      @@notification_mailer.send_notification_email(self, options).deliver_now
  end
end

#subscribed? ⇒ Boolean

Returns if the target subscribes this notification.

Returns:

  • (Boolean) —

    If the target subscribes the notification



750
751
752
# File 'lib/activity_notification/apis/notification_api.rb', line 750

def subscribed?
  target.subscribes_to_notification?(key)
end

#unopened? ⇒ Boolean

Returns if the notification is unopened.

Returns:

  • (Boolean) —

    If the notification is unopened



634
635
636
# File 'lib/activity_notification/apis/notification_api.rb', line 634

def unopened?
  !opened?
end