notify_user 0.0.1 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (79) hide show
  1. checksums.yaml +7 -0
  2. data/app/assets/javascripts/notify_user/notification.js +7 -0
  3. data/app/assets/stylesheets/notify_user/notify_user.css +50 -0
  4. data/app/controllers/notify_user/base_notifications_controller.rb +144 -0
  5. data/app/controllers/notify_user/notifications_controller.rb +7 -32
  6. data/app/helpers/notify_user/application_helper.rb +9 -0
  7. data/app/mailers/notify_user/notification_mailer.rb +2 -0
  8. data/app/models/notify_user/apns.rb +37 -0
  9. data/app/models/notify_user/base_notification.rb +136 -32
  10. data/app/models/notify_user/unsubscribe.rb +55 -0
  11. data/app/models/notify_user/user_hash.rb +36 -0
  12. data/app/serializers/notify_user/notification_serializer.rb +2 -2
  13. data/app/views/notify_user/action_mailer/aggregate_notification.html.erb +2 -1
  14. data/app/views/notify_user/action_mailer/notification.html.erb +1 -1
  15. data/app/views/notify_user/base_notifications/index.html.erb +20 -0
  16. data/app/views/notify_user/base_notifications/unsubscribe.html.erb +19 -0
  17. data/config/routes.rb +8 -0
  18. data/lib/generators/notify_user/install/install_generator.rb +20 -3
  19. data/lib/generators/notify_user/install/templates/{migration.rb → create_notify_user_notifications.rb} +1 -1
  20. data/lib/generators/notify_user/install/templates/create_notify_user_unsubscribes.rb +10 -0
  21. data/lib/generators/notify_user/install/templates/create_notify_user_user_hashes.rb +12 -0
  22. data/lib/generators/notify_user/install/templates/initializer.rb +2 -0
  23. data/lib/generators/notify_user/install/templates/notifications_controller.rb +9 -0
  24. data/lib/generators/notify_user/json_update/USAGE +5 -0
  25. data/lib/generators/notify_user/json_update/json_update_generator.rb +36 -0
  26. data/lib/generators/notify_user/json_update/templates/add_json_column_to_notifications.rb +9 -0
  27. data/lib/generators/notify_user/json_update/templates/move_params_to_json.rb +8 -0
  28. data/lib/generators/notify_user/notification/notification_generator.rb +2 -0
  29. data/lib/generators/notify_user/notification/templates/email_layout_template.html.erb.erb +6 -0
  30. data/lib/generators/notify_user/notification/templates/notification.rb.erb +2 -1
  31. data/lib/notify_user.rb +4 -1
  32. data/lib/notify_user/channels/action_mailer/action_mailer_channel.rb +2 -1
  33. data/lib/notify_user/channels/apns/apns_channel.rb +17 -0
  34. data/lib/notify_user/engine.rb +2 -0
  35. data/lib/notify_user/railtie.rb +10 -0
  36. data/lib/notify_user/version.rb +1 -1
  37. data/lib/tasks/notify_user.rake +15 -0
  38. data/spec/controllers/notify_user/notifications_controller_spec.rb +89 -1
  39. data/spec/dummy/rails-4.0.2/Gemfile +2 -2
  40. data/spec/dummy/rails-4.0.2/app/controllers/notify_user/notifications_controller.rb +9 -0
  41. data/spec/dummy/rails-4.0.2/app/notifications/new_post_notification.rb +2 -1
  42. data/spec/dummy/rails-4.0.2/app/views/notify_user/layouts/action_mailer.html.erb +6 -0
  43. data/spec/dummy/rails-4.0.2/config/database.yml +42 -13
  44. data/spec/dummy/rails-4.0.2/config/database2.yml +57 -0
  45. data/spec/dummy/rails-4.0.2/config/initializers/notify_user.rb +2 -0
  46. data/spec/dummy/rails-4.0.2/config/initializers/secret_token.rb +1 -1
  47. data/spec/dummy/rails-4.0.2/db/migrate/{20140105070446_create_users.rb → 20140428015529_create_users.rb} +0 -0
  48. data/spec/dummy/rails-4.0.2/db/migrate/{20140105070448_create_notify_user_notifications.rb → 20140428015531189189694000_create_notify_user_notifications.rb} +1 -1
  49. data/spec/dummy/rails-4.0.2/db/migrate/20140428015531190190743000_create_notify_user_unsubscribes.rb +10 -0
  50. data/spec/dummy/rails-4.0.2/db/migrate/20140428015531191191953000_create_notify_user_user_hashes.rb +12 -0
  51. data/spec/dummy/rails-4.0.2/db/schema.rb +23 -2
  52. data/spec/dummy/rails-4.0.2/log/test.log +787 -1414
  53. data/spec/dummy/rails-4.0.2/tmp/cache/assets/test/sprockets/13195a56ea8581e42f709ea01ea4604f +0 -0
  54. data/{app/assets/stylesheets/notify_user/application.css → spec/dummy/rails-4.0.2/tmp/cache/assets/test/sprockets/13fe41fee1fe35b49d145bcc06610705} +0 -0
  55. data/spec/dummy/rails-4.0.2/tmp/cache/assets/test/sprockets/148f39f7dc2ea6cb194598111dbd4598 +0 -0
  56. data/spec/dummy/rails-4.0.2/tmp/cache/assets/test/sprockets/1d6bc1877ba2bbb89f393e10e8303d39 +0 -0
  57. data/spec/dummy/rails-4.0.2/tmp/cache/assets/test/sprockets/2f5173deea6c795b8fdde723bb4b63af +0 -0
  58. data/spec/dummy/rails-4.0.2/tmp/cache/assets/test/sprockets/311d2b645a860b78f79ff156f12092ce +0 -0
  59. data/spec/dummy/rails-4.0.2/tmp/cache/assets/test/sprockets/357970feca3ac29060c1e3861e2c0953 +0 -0
  60. data/spec/dummy/rails-4.0.2/tmp/cache/assets/test/sprockets/39651f0f2ac78423732234ebf092c632 +0 -0
  61. data/spec/dummy/rails-4.0.2/tmp/cache/assets/test/sprockets/5c85b1b5ac27b699c5f800c4e7ec82fb +0 -0
  62. data/spec/dummy/rails-4.0.2/tmp/cache/assets/test/sprockets/68752c7ddc300bee3e9823db8befc306 +0 -0
  63. data/spec/dummy/rails-4.0.2/tmp/cache/assets/test/sprockets/6961013077b8573ed19d1e33abb8ebc5 +0 -0
  64. data/spec/dummy/rails-4.0.2/tmp/cache/assets/test/sprockets/7a316b3629b980c6d3a28924cb5fbbd8 +0 -0
  65. data/spec/dummy/rails-4.0.2/tmp/cache/assets/test/sprockets/8698d6fed0ef2f173a377160752b959f +0 -0
  66. data/spec/dummy/rails-4.0.2/tmp/cache/assets/test/sprockets/8bab520aad78da438df1c428288cf229 +0 -0
  67. data/spec/dummy/rails-4.0.2/tmp/cache/assets/test/sprockets/cffd775d018f68ce5dba1ee0d951a994 +0 -0
  68. data/spec/dummy/rails-4.0.2/tmp/cache/assets/test/sprockets/d771ace226fc8215a3572e0aa35bb0d6 +0 -0
  69. data/spec/dummy/rails-4.0.2/tmp/cache/assets/test/sprockets/f7cbd26ba1d28d48de824f0e94586655 +0 -0
  70. data/spec/dummy/rails-4.0.2/tmp/cache/assets/test/sprockets/fa138a16887e031c0ae1b4caccfb4c05 +0 -0
  71. data/spec/mailers/notify_user/notification_mailer_spec.rb +1 -0
  72. data/spec/models/notify_user/notification_spec.rb +122 -1
  73. data/spec/models/notify_user/unsubscribe_spec.rb +40 -0
  74. data/spec/models/notify_user/user_hash_spec.rb +35 -0
  75. data/spec/spec_helper.rb +5 -0
  76. data/spec/support/database.yml +21 -0
  77. data/spec/support/rails_template.rb +9 -0
  78. metadata +196 -65
  79. data/spec/dummy/rails-4.0.2/db/test.sqlite3 +0 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 6ccbda4d4f6f0bd85a37c2e9295789c8c3c28844
4
+ data.tar.gz: f8f67249b41082e9af5dc4686bb3f85639360507
5
+ SHA512:
6
+ metadata.gz: b9258b901edd1eb111a33354aafc2aa668b7520587594fad58e03d5d887042836633cc620a8b49d167220ebb16cac1c18423c78d9d45d8fc9bbbf76d4d5eaf78
7
+ data.tar.gz: ae8fd4a46fde87ffe996adc8e42e63b667a5b0525ceb269205a76e437a17df21209ff5f7f8e59d1298f4eee57cec35738b0d3059b094aa80876808cf8712f42f
@@ -0,0 +1,7 @@
1
+ $( document ).ready(function() {
2
+ $('.message').click(function(){
3
+ item = $(this).parent().parent();
4
+ item.addClass('read');
5
+
6
+ });
7
+ });
@@ -0,0 +1,50 @@
1
+ .unread a{
2
+ font-weight: bold;
3
+ }
4
+ .read a{
5
+ font-weight: normal;
6
+ }
7
+ #notifications_list{
8
+ margin: 0 auto;
9
+ width: 100%;
10
+ width: 720px;
11
+ color: #000;
12
+ font-family: arial;
13
+ font-size: 14px;
14
+ text-align: right;
15
+ padding: 5px;
16
+ text-align: center;
17
+ }
18
+
19
+ #notifications_list .inner{
20
+ margin-top: 10px;
21
+ border: 1px solid #dedede;
22
+ text-align: left;
23
+
24
+ }
25
+ #notifications_list a{
26
+ color: #454545;
27
+ text-decoration: none;
28
+ }
29
+ #notifications_list .item:hover a{
30
+ text-decoration: underline;
31
+ }
32
+
33
+ #notifications_list .title{
34
+ text-align: left;
35
+ }
36
+
37
+ #notifications_list .item{
38
+ padding: 20px 10px;
39
+ border-bottom: 1px solid #dedede;
40
+ }
41
+ #notifications_list .item.read{
42
+ background: #eaeaea;
43
+ }
44
+ #notifications_list .item .time_ago{
45
+ font-size: 12px;
46
+ text-align: right;
47
+ }
48
+ #notifications_list .mark_as_read{
49
+ text-align: right;
50
+ }
@@ -0,0 +1,144 @@
1
+ class NotifyUser::BaseNotificationsController < ApplicationController
2
+
3
+ before_filter :authenticate!, :except => [:unauth_unsubscribe]
4
+
5
+ def index
6
+ @notifications = NotifyUser::BaseNotification.for_target(@user)
7
+ .order("created_at DESC")
8
+ .limit(30)
9
+ .page(params[:page]).per(params[:per_page])
10
+
11
+ respond_to do |format|
12
+ format.html
13
+ format.json {render :json => @notifications, meta: { pagination: { per_page: @notifications.limit_value, total_pages: @notifications.total_pages, total_objects: @notifications.total_count } }}
14
+ end
15
+ end
16
+
17
+ def mark_read
18
+ @notifications = NotifyUser::BaseNotification.for_target(@user).where('id IN (?)', params[:ids])
19
+ @notifications.update_all(state: :read)
20
+ render json: @notifications
21
+ end
22
+
23
+ def mark_all
24
+ @notifications = NotifyUser::BaseNotification.for_target(@user).where('state IN (?)', ["pending","sent"])
25
+ @notifications.update_all(state: :read)
26
+ redirect_to notify_user_notifications_path
27
+ end
28
+
29
+ def notifications_count
30
+ @notifications = NotifyUser::BaseNotification.for_target(@user).where('state IN (?)', ["sent"])
31
+ render json: {:count => @notifications.count}
32
+ end
33
+
34
+ #get
35
+ def read
36
+ @notification = NotifyUser::BaseNotification.for_target(@user).where('id = ?', params[:id]).first
37
+ @notification.mark_as_read
38
+ redirect_logic(@notification)
39
+ end
40
+
41
+ def redirect_logic(notification)
42
+ render :text => "redirect setup goes here"
43
+ end
44
+
45
+ def unsubscribe
46
+ if params[:type]
47
+ unsubscribe_from(params[:type])
48
+ redirect_to notify_user_notifications_unsubscribe_path
49
+ end
50
+ @unsubscribale_types = NotifyUser.unsubscribable_notifications
51
+ @unsubscribale_channels = NotifyUser::BaseNotification.channels
52
+ end
53
+
54
+ #endpoint for accessing subscriptions and their statuses
55
+ def subscriptions
56
+ update_subscriptions(params[:types]) if params[:types]
57
+ @types = build_notification_types
58
+ render :json => @types
59
+ end
60
+
61
+ def update_subscriptions(types)
62
+ types.each do |type|
63
+ unsubscribe = NotifyUser::Unsubscribe.has_unsubscribed_from(@user, type[:type])
64
+ if type[:status] == '0'
65
+ if unsubscribe.empty?
66
+ #if unsubscribe doesn't exist create it
67
+ unsubscribe = NotifyUser::Unsubscribe.create(target: @user, type: type[:type])
68
+ end
69
+ else
70
+ subscribe_to(type[:type])
71
+ end
72
+ end
73
+ end
74
+
75
+ def unauth_unsubscribe
76
+ if params[:token] && params[:type]
77
+ if NotifyUser::UserHash.confirm_hash(params[:token], params[:type])
78
+ user_hash = NotifyUser::UserHash.where(token: params[:token], type: params[:type]).first
79
+ @user = user_hash.target
80
+ unsubscribe = NotifyUser::Unsubscribe.create(target: @user, type: params[:type])
81
+ user_hash.deactivate
82
+ return render :text => "successfully unsubscribed from #{params[:type]} notifications"
83
+ else
84
+ return render :text => "invalid token"
85
+ end
86
+ end
87
+ return render :text => "Something went wrong please try again later"
88
+ end
89
+
90
+ def subscribe
91
+ subscribe_to(params[:type]) if params[:type]
92
+ redirect_to notify_user_notifications_unsubscribe_path
93
+ end
94
+
95
+ protected
96
+
97
+ def default_serializer_options
98
+ {
99
+ each_serializer: NotifyUser::NotificationSerializer,
100
+ template_renderer: self
101
+ }
102
+ end
103
+
104
+ def authenticate!
105
+ method(NotifyUser.authentication_method).call
106
+ @user = method(NotifyUser.current_user_method).call
107
+ end
108
+
109
+ private
110
+ def build_notification_types()
111
+ #dirty way to build a json hash with pagination
112
+ types = {:subscriptions => []}
113
+
114
+ notification_types = NotifyUser.unsubscribable_notifications
115
+
116
+ #iterates over channels
117
+ NotifyUser::BaseNotification.channels.each do |type, options|
118
+ channel = (type.to_s + "_channel").camelize.constantize
119
+ types[:subscriptions] << {type: type, description: channel.default_options[:description],
120
+ status: NotifyUser::Unsubscribe.has_unsubscribed_from(@user, type).empty?}
121
+ end
122
+
123
+ #iterates over type
124
+ notification_types.each do |type|
125
+ types[:subscriptions] << {type: type, description: type.constantize.description,
126
+ status: NotifyUser::Unsubscribe.has_unsubscribed_from(@user, type).empty?}
127
+ end
128
+ return types
129
+ end
130
+
131
+ def unsubscribe_from(type)
132
+ unsubscribe = NotifyUser::Unsubscribe.new(target: @user, type: type)
133
+ if unsubscribe.save
134
+ flash[:message] = "successfully unsubscribed from #{type} notifications"
135
+ else
136
+ flash[:message] = "Please try again"
137
+ end
138
+ end
139
+
140
+ def subscribe_to(type)
141
+ NotifyUser::Unsubscribe.unsubscribe(@user,type)
142
+ flash[:message] = "successfully subscribed to #{type} notifications"
143
+ end
144
+ end
@@ -1,33 +1,8 @@
1
- class NotifyUser::NotificationsController < ApplicationController
2
-
3
- before_filter :authenticate!
4
-
5
- def index
6
- @notifications = NotifyUser::BaseNotification.for_target(@user)
7
- .order("created_at DESC")
8
- .limit(30)
9
- .page(params[:page])
10
-
11
- render json: @notifications
12
- end
13
-
14
- def mark_read
15
- @notifications = NotifyUser::BaseNotification.for_target(@user).where('id IN (?)', params[:ids])
16
- @notifications.update_all(state: :read)
17
- render json: @notifications
18
- end
19
-
20
- protected
21
-
22
- def default_serializer_options
23
- {
24
- each_serializer: NotifyUser::NotificationSerializer,
25
- template_renderer: self
26
- }
27
- end
28
-
29
- def authenticate!
30
- method(NotifyUser.authentication_method).call
31
- @user = method(NotifyUser.current_user_method).call
32
- end
1
+ class NotifyUser::NotificationsController < NotifyUser::BaseNotificationsController
2
+ def redirect_logic(notification)
3
+ render :text => "set redirect logic in notify_user/notifications_controller.rb"
4
+ #notification redirect logic goes here
5
+ #property = Property.find(@notification.params[:property_id])
6
+ #redirect_to property_url(@property)
7
+ end
33
8
  end
@@ -1,4 +1,13 @@
1
1
  module NotifyUser
2
2
  module ApplicationHelper
3
+ def unsubscribe_link(notification, text)
4
+ user_hash = notification.generate_unsubscribe_hash
5
+ html = link_to(text, notify_user_notifications_unauth_unsubscribe_url(:type => notification.type, :token => user_hash.token))
6
+ return html.to_s.html_safe
7
+ end
8
+
9
+ def is_unsubscribeable?(notification)
10
+ return NotifyUser.unsubscribable_notifications.include? notification.type
11
+ end
3
12
  end
4
13
  end
@@ -1,5 +1,6 @@
1
1
  module NotifyUser
2
2
  class NotificationMailer < ActionMailer::Base
3
+ helper NotifyUser::ApplicationHelper
3
4
 
4
5
  layout "notify_user/layouts/action_mailer"
5
6
 
@@ -15,6 +16,7 @@ module NotifyUser
15
16
 
16
17
  def aggregate_notifications_email(notifications, options)
17
18
  @notifications = notifications
19
+ @notification = notifications.first
18
20
 
19
21
  mail to: @notifications.first.target.email,
20
22
  template_name: "aggregate_notification",
@@ -0,0 +1,37 @@
1
+ module NotifyUser
2
+ class Apns
3
+ SYMBOL_NAMES_SIZE = 10
4
+ PAYLOAD_LIMIT = 255
5
+
6
+ #sends push notification
7
+ def self.push_notification(notification)
8
+ #calculates the bytes already used
9
+ used_space = SYMBOL_NAMES_SIZE + notification.id.size + notification.created_at.to_time.to_i.size +
10
+ notification.type.size
11
+
12
+ used_space += notification.params[:action_id].size if notification.params[:action_id]
13
+
14
+ space_allowance = PAYLOAD_LIMIT - used_space
15
+
16
+ payload = {
17
+ :alias => notification.target_id,
18
+ :aps => {alert: notification.mobile_message(space_allowance), badge: 1},
19
+ :n_data => {
20
+ '#' => notification.id,
21
+ t: notification.created_at.to_time.to_i,
22
+ '?' => notification.type
23
+ }
24
+ }
25
+ payload[:n_data]['!'] = notification.params[:action_id] if notification.params[:action_id]
26
+
27
+ response = Urbanairship.push(payload)
28
+ if response.success?
29
+ puts "Push notification sent successfully."
30
+ return true
31
+ else
32
+ puts "Push notification failed."
33
+ return false
34
+ end
35
+ end
36
+ end
37
+ end
@@ -3,6 +3,7 @@ require 'sidekiq'
3
3
 
4
4
  module NotifyUser
5
5
  class BaseNotification < ActiveRecord::Base
6
+ include ActionView::Helpers::TextHelper
6
7
 
7
8
  if ActiveRecord::VERSION::MAJOR < 4
8
9
  attr_accessible :params, :target, :type, :state
@@ -11,8 +12,11 @@ module NotifyUser
11
12
  # Override point in case of collisions, plus keeps the table name tidy.
12
13
  self.table_name = "notify_user_notifications"
13
14
 
15
+ #checks if user has unsubscribed from this notif type
16
+ validate :unsubscribed_validation
17
+
14
18
  # Params for creating the notification message.
15
- serialize :params, Hash
19
+ # serialize :params, Hash
16
20
 
17
21
  # The user to send the notification to
18
22
  belongs_to :target, polymorphic: true
@@ -46,8 +50,29 @@ module NotifyUser
46
50
  end
47
51
  end
48
52
 
49
- ## Public Interface
53
+ def params
54
+ if super.nil?
55
+ {}
56
+ else
57
+ super.with_indifferent_access
58
+ end
59
+ end
60
+
61
+ def message
62
+ ActionView::Base.new(
63
+ Rails.configuration.paths["app/views"]).render(
64
+ :template => self.class.views[:mobile_sdk][:template_path].call(self), :formats => [:html],
65
+ :locals => { :params => self.params}, :layout => false)
66
+ end
50
67
 
68
+ def mobile_message(length=115)
69
+ truncate(ActionView::Base.new(
70
+ Rails.configuration.paths["app/views"]).render(
71
+ :template => self.class.views[:mobile_sdk][:template_path].call(self), :formats => [:html],
72
+ :locals => { :params => self.params}, :layout => false), :length => length)
73
+ end
74
+
75
+ ## Public Interface
51
76
  def to(user)
52
77
  self.target = user
53
78
  self
@@ -59,7 +84,7 @@ module NotifyUser
59
84
  end
60
85
 
61
86
  def notify!
62
- save!
87
+ save
63
88
 
64
89
  # Bang version of 'notify' ignores aggregation
65
90
  self.deliver!
@@ -68,29 +93,35 @@ module NotifyUser
68
93
  # Send any Emails/SMS/APNS
69
94
  def notify
70
95
 
71
- save!
72
-
73
- if self.class.aggregate_per
74
-
75
- # Schedule to send later if there aren't already any scheduled.
76
- # Otherwise ignore, as the already-scheduled aggregate job will pick this one up when it runs.
77
- if not aggregation_pending?
96
+ save
78
97
 
79
- # Send in X minutes, along with any others created in the intervening times.
80
- self.class.delay_for(self.class.aggregate_per).notify_aggregated(self.id)
98
+ #if aggregation is false bypass aggregation completely
99
+ self.channels.each do |channel_name, options|
100
+ if(options[:aggregate_per] == false)
101
+ self.class.delay.deliver_notification_channel(self.id, channel_name)
102
+ else
103
+ if not aggregation_pending?
104
+ self.class.delay_for(options[:aggregate_per] || self.aggregate_per).notify_aggregated_channel(self.id, channel_name)
105
+ end
81
106
  end
82
- else
83
- # No aggregation, send immediately.
84
- self.deliver
85
107
  end
86
108
 
87
109
  end
88
110
 
111
+ def generate_unsubscribe_hash
112
+ #check if a hash already exists for that user otherwise create a new one
113
+ 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)
114
+ end
115
+
116
+ ## Notification description
117
+ class_attribute :description
118
+ self.description = ""
119
+
89
120
  ## Channels
90
121
 
91
122
  mattr_accessor :channels
92
123
  @@channels = {
93
- action_mailer: {},
124
+ action_mailer: {description: 'Email notifications'}
94
125
  }
95
126
 
96
127
  # Not sure about this. The JSON and web feeds don't fit into channels, because nothing is broadcast through
@@ -109,14 +140,14 @@ module NotifyUser
109
140
 
110
141
  ## Aggregation
111
142
 
112
- mattr_accessor :aggregate_per
113
- @@aggregate_per = 1.minute
143
+ class_attribute :aggregate_per
144
+ self.aggregate_per = 1.minute
114
145
 
115
146
  ## Sending
116
147
 
117
148
  def self.for_target(target)
118
149
  where(target_id: target.id)
119
- .where(target_type: target.class.name)
150
+ .where(target_type: target.class.base_class)
120
151
  end
121
152
 
122
153
  def self.pending_aggregation_with(notification)
@@ -131,35 +162,88 @@ module NotifyUser
131
162
  return (self.class.pending_aggregation_with(self).where('id != ?', id).count > 0)
132
163
  end
133
164
 
134
- def deliver
135
- self.mark_as_sent
136
- self.save
165
+ # def deliver
166
+ # unless user_has_unsubscribed?
167
+ # self.mark_as_sent
168
+ # self.save
137
169
 
138
- self.class.delay.deliver_channels(self.id)
139
- end
170
+ # self.class.delay.deliver_channels(self.id)
171
+ # end
172
+ # end
140
173
 
141
174
  def deliver!
142
- self.mark_as_sent
143
- self.save
144
- self.class.deliver_channels(self.id)
175
+ unless user_has_unsubscribed?
176
+ self.mark_as_sent
177
+ self.save
178
+ self.class.deliver_channels(self.id)
179
+ end
145
180
  end
146
181
 
147
182
  # Deliver a single notification across each channel.
148
183
  def self.deliver_channels(notification_id)
149
184
  notification = self.where(id: notification_id).first
150
185
  return unless notification
151
-
152
186
  self.channels.each do |channel_name, options|
153
- channel = (channel_name.to_s + "_channel").camelize.constantize
154
- channel.deliver(notification, options)
187
+ unless unsubscribed_from_channel?(notification.target, channel_name)
188
+ channel = (channel_name.to_s + "_channel").camelize.constantize
189
+ channel.deliver(notification, options)
190
+ end
155
191
  end
156
192
  end
157
193
 
158
194
  # Deliver multiple notifications across each channel as an aggregate message.
159
195
  def self.deliver_channels_aggregated(notifications)
160
196
  self.channels.each do |channel_name, options|
161
- channel = (channel_name.to_s + "_channel").camelize.constantize
162
- channel.deliver_aggregated(notifications, options)
197
+ if options[:aggregate_per] != false && !unsubscribed_from_channel?(notifications.first.target, channel_name)
198
+ channel = (channel_name.to_s + "_channel").camelize.constantize
199
+ channel.deliver_aggregated(notifications, options)
200
+ end
201
+ end
202
+ end
203
+
204
+ #deliver to specific channel methods
205
+
206
+ # Deliver a single notification to a specific channel.
207
+ def self.deliver_notification_channel(notification_id, channel_name)
208
+ notification = self.where(id: notification_id).first
209
+ return unless notification
210
+ channel_options = channels[channel_name.to_sym]
211
+
212
+ channel = (channel_name.to_s + "_channel").camelize.constantize
213
+ unless self.unsubscribed_from_channel?(notification.target, channel_name)
214
+ channel.deliver(notification, channel_options)
215
+ end
216
+ end
217
+
218
+ # Deliver a aggregated notifications to a specific channel.
219
+ def self.deliver_notifications_channel(notifications, channel_name)
220
+ channel_options = channels[channel_name.to_sym]
221
+ channel = (channel_name.to_s + "_channel").camelize.constantize
222
+
223
+ #check if user unsubsribed from channel type
224
+ unless self.unsubscribed_from_channel?(notifications.first.target, channel_name)
225
+ channel.deliver_aggregated(notifications, channel_options)
226
+ end
227
+ end
228
+
229
+ #notifies a single channel for aggregation
230
+ def self.notify_aggregated_channel(notification_id, channel_name)
231
+ notification = self.find(notification_id) # Raise an exception if not found.
232
+
233
+ # Find any pending notifications with the same type and target, which can all be sent in one message.
234
+ notifications = self.pending_aggregation_with(notification)
235
+
236
+ notifications.map(&:mark_as_sent)
237
+ notifications.map(&:save)
238
+
239
+ return if notifications.empty?
240
+
241
+ if notifications.length == 1
242
+ # Despite waiting for more to aggregate, we only got one in the end.
243
+ self.deliver_notification_channel(notifications.first.id, channel_name)
244
+ else
245
+ # We got several notifications while waiting, send them aggregated.
246
+ self.deliver_notifications_channel(notifications, channel_name)
163
247
  end
164
248
  end
165
249
 
@@ -183,5 +267,25 @@ module NotifyUser
183
267
  end
184
268
  end
185
269
 
270
+ private
271
+ def unsubscribed_validation
272
+ errors.add(:target, (" has unsubscribed from this type")) if user_has_unsubscribed?
273
+ end
274
+
275
+ def user_has_unsubscribed?
276
+ #return true if user has unsubscribed
277
+ return true unless NotifyUser::Unsubscribe.has_unsubscribed_from(self.target, self.type).empty?
278
+
279
+ return false
280
+ end
281
+
282
+ def self.unsubscribed_from_channel?(user, type)
283
+ #return true if user has unsubscribed
284
+ return true unless NotifyUser::Unsubscribe.has_unsubscribed_from(user, type).empty?
285
+
286
+ return false
287
+ end
288
+
289
+
186
290
  end
187
291
  end