rails-alerter 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (89) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +36 -0
  3. data/.rspec +2 -0
  4. data/.ruby-gemset +1 -0
  5. data/.ruby-version +1 -0
  6. data/Appraisals +11 -0
  7. data/Gemfile +4 -0
  8. data/LICENSE +22 -0
  9. data/LICENSE.txt +22 -0
  10. data/README.md +111 -0
  11. data/Rakefile +10 -0
  12. data/alerter.gemspec +60 -0
  13. data/app/builders/alerter/base_builder.rb +26 -0
  14. data/app/builders/alerter/message_builder.rb +16 -0
  15. data/app/builders/alerter/receipt_builder.rb +13 -0
  16. data/app/mailers/alerter/base_mailer.rb +15 -0
  17. data/app/mailers/alerter/message_mailer.rb +12 -0
  18. data/app/models/alerter/mailbox.rb +74 -0
  19. data/app/models/alerter/message.rb +171 -0
  20. data/app/models/alerter/notification_type.rb +20 -0
  21. data/app/models/alerter/preference.rb +19 -0
  22. data/app/models/alerter/receipt.rb +89 -0
  23. data/app/views/alerter/message_mailer/new_message_email.html.erb +20 -0
  24. data/app/views/alerter/message_mailer/new_message_email.text.erb +10 -0
  25. data/db/migrate/20150821000000_create_alerter.rb +65 -0
  26. data/lib/alerter/cleaner.rb +9 -0
  27. data/lib/alerter/engine.rb +31 -0
  28. data/lib/alerter/message_dispatcher.rb +62 -0
  29. data/lib/alerter/models/notifiable.rb +174 -0
  30. data/lib/alerter/version.rb +3 -0
  31. data/lib/generators/alerter/install_generator.rb +37 -0
  32. data/lib/generators/alerter/namespacing_compatibility_generator.rb +24 -0
  33. data/lib/generators/alerter/templates/initializer.rb +29 -0
  34. data/lib/generators/alerter/views_generator.rb +11 -0
  35. data/lib/rails-alerter.rb +71 -0
  36. data/spec/alerter/message_dispatcher_spec.rb +101 -0
  37. data/spec/alerter_spec.rb +8 -0
  38. data/spec/dummy/.gitignore +5 -0
  39. data/spec/dummy/Rakefile +7 -0
  40. data/spec/dummy/app/controllers/application_controller.rb +3 -0
  41. data/spec/dummy/app/controllers/home_controller.rb +4 -0
  42. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  43. data/spec/dummy/app/mailers/.gitkeep +0 -0
  44. data/spec/dummy/app/models/.gitkeep +0 -0
  45. data/spec/dummy/app/models/cylon.rb +4 -0
  46. data/spec/dummy/app/models/duck.rb +3 -0
  47. data/spec/dummy/app/models/user.rb +3 -0
  48. data/spec/dummy/app/views/home/index.html.haml +7 -0
  49. data/spec/dummy/app/views/layouts/application.html.haml +11 -0
  50. data/spec/dummy/config.ru +4 -0
  51. data/spec/dummy/config/application.rb +47 -0
  52. data/spec/dummy/config/boot.rb +10 -0
  53. data/spec/dummy/config/database.yml +24 -0
  54. data/spec/dummy/config/environment.rb +5 -0
  55. data/spec/dummy/config/environments/development.rb +29 -0
  56. data/spec/dummy/config/environments/production.rb +51 -0
  57. data/spec/dummy/config/environments/test.rb +37 -0
  58. data/spec/dummy/config/initializers/alerter.rb +26 -0
  59. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  60. data/spec/dummy/config/initializers/inflections.rb +10 -0
  61. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  62. data/spec/dummy/config/initializers/secret_token.rb +7 -0
  63. data/spec/dummy/config/initializers/session_store.rb +8 -0
  64. data/spec/dummy/config/locales/en.yml +5 -0
  65. data/spec/dummy/config/routes.rb +58 -0
  66. data/spec/dummy/config/sunspot.yml +17 -0
  67. data/spec/dummy/db/migrate/20110228120600_create_users.rb +14 -0
  68. data/spec/dummy/db/migrate/20110306002940_create_ducks.rb +14 -0
  69. data/spec/dummy/db/migrate/20110306015107_create_cylons.rb +14 -0
  70. data/spec/dummy/db/schema.rb +77 -0
  71. data/spec/dummy/public/404.html +26 -0
  72. data/spec/dummy/public/422.html +26 -0
  73. data/spec/dummy/public/500.html +26 -0
  74. data/spec/dummy/public/favicon.ico +0 -0
  75. data/spec/dummy/public/index.html +239 -0
  76. data/spec/dummy/public/robots.txt +5 -0
  77. data/spec/dummy/public/uploads/testfile.txt +1 -0
  78. data/spec/dummy/script/rails +6 -0
  79. data/spec/factories/general.rb +37 -0
  80. data/spec/integration/message_and_receipt_spec.rb +42 -0
  81. data/spec/integration/navigation_spec.rb +8 -0
  82. data/spec/mailers/message_mailer_spec.rb +44 -0
  83. data/spec/models/alerter_models_messageable_spec.rb +311 -0
  84. data/spec/models/mailbox_spec.rb +55 -0
  85. data/spec/models/message_spec.rb +51 -0
  86. data/spec/models/preference_spec.rb +35 -0
  87. data/spec/models/receipt_spec.rb +61 -0
  88. data/spec/spec_helper.rb +54 -0
  89. metadata +330 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: db24886c3f4f6847206d8e304b4491437247e1dc
4
+ data.tar.gz: 3ec40c899dbb26fdbe9862807ab96942a0733b42
5
+ SHA512:
6
+ metadata.gz: e0ee4dc0c52768b6cd8d5a4984befde66bd1e8ddd163e8b0bc379f5129c0d4cf01d5191906f0c2e8ebfb221141821814cff8024a31e2f6d9884cffa4bf31e7e7
7
+ data.tar.gz: 6030051ea01e9c5369d501c8d0e8d15c5be5909f083450b588216b75c49f95faee8f99fd0a160c448730e57352501bcfcc351113e3a450224fa75658dcf1335d
@@ -0,0 +1,36 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/dummy/db/*.sqlite3
15
+ spec/dummy/log/*.log
16
+ spec/dummy/log/*.lck
17
+ spec/dummy/tmp/
18
+ spec/dummy/.project
19
+ spec/reports
20
+ test/tmp
21
+ test/version_tmp
22
+ tmp
23
+ *.bundle
24
+ *.so
25
+ *.o
26
+ *.a
27
+ mkmf.log
28
+ log/*.log
29
+ pkg/
30
+ **.tmp_*
31
+ .idea
32
+ .project
33
+ .document
34
+ .settings/
35
+ .yardoc/*
36
+ .rvmrc
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format d
@@ -0,0 +1 @@
1
+ alerter
@@ -0,0 +1 @@
1
+ 2.2
@@ -0,0 +1,11 @@
1
+ appraise "rails3.2" do
2
+ gem "rails", "~> 3.2.17"
3
+ end
4
+
5
+ appraise "rails4.0" do
6
+ gem "rails", "~> 4.0.4"
7
+ end
8
+
9
+ appraise "rails4.1" do
10
+ gem "rails", "~> 4.1.0"
11
+ end
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in alerter.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015 DaKaZ
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 Michael Kazmier
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,111 @@
1
+ # Alerter
2
+
3
+ ### This is ALPHA software
4
+
5
+ We are still building out the mailers for everything except email...
6
+
7
+ ## Overview
8
+
9
+ Alerter is a Rails gem for managing notifications within a standard Rails app. Notifications are getting more complex
10
+ as applications now typically have multiple faces (web, mobile, social, etc) and users are requesting varying
11
+ delivery methods for notifications (in-app, mobile push, email, text, social, etc).
12
+
13
+ Alter is largely derived from the outstanding Mailboxer app (https://github.com/mailboxer/mailboxer) but solving a
14
+ very different problem: Notifications
15
+
16
+ Alerter provides 4 basic functions:
17
+ * Extend your user object with acts-as-notifiable
18
+ * Manage multiple Notification Types (these are application specific, ex: Billing, Support, Sales, Achievement, etc)
19
+ * Send and track delivery state for the notification providing a full audit history
20
+ * Provide notification preferences for users
21
+ * Allow users to specify which methods (email, text, none, etc) they would like be notified on for different Notification Types
22
+
23
+
24
+ We need help with testing and documention, please jump in!
25
+
26
+ ## Installation
27
+
28
+ Add this line to your application's Gemfile:
29
+
30
+ gem 'rails-alerter'
31
+
32
+ And then execute:
33
+
34
+ $ bundle install
35
+
36
+ Run the install script
37
+
38
+ $ rails g alerter:install
39
+
40
+ Migrate the DB
41
+
42
+ $ rake db:migrate
43
+
44
+ Generate your own email templates
45
+
46
+ $ rails g alerter:views
47
+
48
+ In your model:
49
+
50
+ class User < ActiveRecord::Base
51
+ acts_as_notifiable
52
+ end
53
+
54
+ ## Usage
55
+
56
+ Alerter uses a `Alerter::Message` object that requires a short_msg and long_msg to accomidate different delivery
57
+ platforms. You can configure the maximum length of these in the initializer:
58
+
59
+ Alerter.setup do |config|
60
+ config.short_msg_length = 144 # Up to String length for your DB
61
+ config.long_msg_length = 512 # Any length you want
62
+ ...
63
+ end
64
+
65
+
66
+ How can I send a message to a user?
67
+
68
+ #Send a message to beta
69
+ Alerter::Message.notify_all(beta, "Short Message", "Long Message")
70
+
71
+ Or you can include an array of recipients
72
+
73
+ recipients = [ alice, john, steve ]
74
+ Alerter::Message.notify_all(recipients, "Short Message", "Long Message")
75
+
76
+ How can I retrieve my conversations?
77
+
78
+ #alfa wants to retrieve all his messages (read and unread)
79
+ alfa.mailbox.inbox
80
+
81
+ #alfa gets the last message (chronologically, the first in the inbox)
82
+ message = alfa.mailbox.inbox.first
83
+
84
+ # get only unread messages
85
+ alfa.mailbox.inbox.unread
86
+
87
+ You can mark a message as read, unread or deleted or one or more users
88
+
89
+ # for user alpha
90
+ message.mark_as_read(alfa)
91
+ message.mark_as_unread(alfa)
92
+ message.mark_as_deleted(alfa)
93
+
94
+
95
+ You can change the way in which emails, SMS or mobile Push notifications are delivered by specifying a custom implementation of the mailer
96
+
97
+ Alerter.setup do |config|
98
+ config.email_message_mailer = CustomEmailMessageMailer
99
+ config.sms_message_mailer = CustomSmsMessageMailer
100
+ config.push_message_mailer = CustomPushMessageMailer
101
+ ...
102
+ end
103
+
104
+
105
+ ## Contributing
106
+
107
+ 1. Fork it ( https://github.com/[my-github-username]/alerter/fork )
108
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
109
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
110
+ 4. Push to the branch (`git push origin my-new-feature`)
111
+ 5. Create a new Pull Request
@@ -0,0 +1,10 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+
4
+ require "bundler/gem_tasks"
5
+
6
+ require 'appraisal'
7
+ require 'rspec/core'
8
+ require 'rspec/core/rake_task'
9
+ RSpec::Core::RakeTask.new(:spec)
10
+ task :default => :spec
@@ -0,0 +1,60 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'alerter/version'
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = "rails-alerter"
8
+ s.version = Alerter::VERSION
9
+
10
+ s.authors = ["Michael Kazmier"]
11
+ s.summary = "Messaging system for rails apps."
12
+ s.description = "Many apps need to send basic notifications to users, often using multiple " +
13
+ "delivery methods (like email, push notifications, SMS, twitter, etc). This gem is designed to " +
14
+ "make that process easy and track the state of the notification in a centralized fashion."
15
+ s.email = [ "dakazmier@gmail.com" ]
16
+ s.homepage = "https://github.com/DaKaZ/alerter"
17
+ s.files = `git ls-files`.split("\n")
18
+ s.license = 'MIT'
19
+
20
+ # Gem dependencies
21
+ #
22
+ # SQL foreign keys
23
+ s.add_runtime_dependency('foreigner', '>= 0.9.1')
24
+
25
+ # Development Gem dependencies
26
+ s.add_runtime_dependency('rails', '>= 3.2.0')
27
+
28
+ if RUBY_ENGINE == "rbx" && RUBY_VERSION >= "2.1.0"
29
+ # Rubinius has it's own dependencies
30
+ s.add_runtime_dependency 'rubysl'
31
+ s.add_development_dependency 'racc'
32
+ end
33
+ # Specs
34
+ s.add_development_dependency 'pry'
35
+ s.add_development_dependency 'pry-rails'
36
+ s.add_development_dependency 'rspec-rails', '~> 3.0'
37
+ s.add_development_dependency 'rspec-its', '~> 1.1'
38
+ s.add_development_dependency 'rspec-collection_matchers', '~> 1.1'
39
+ s.add_development_dependency('appraisal', '~> 1.0.0')
40
+ s.add_development_dependency('shoulda-matchers')
41
+ s.add_development_dependency('simplecov')
42
+ # Fixtures
43
+ #if RUBY_VERSION >= '1.9.2'
44
+ # s.add_development_dependency('factory_girl', '>= 3.0.0')
45
+ #else
46
+ #s.add_development_dependency('factory_girl', '~> 2.6.0')
47
+ #end
48
+ s.add_development_dependency('factory_girl', '~> 3.3.0')
49
+ # Population
50
+ s.add_development_dependency('forgery', '>= 0.3.6')
51
+ # Integration testing
52
+ s.add_development_dependency('capybara', '>= 0.3.9')
53
+ # Testing database
54
+ if RUBY_PLATFORM == 'java'
55
+ s.add_development_dependency('jdbc-sqlite3')
56
+ s.add_development_dependency('activerecord-jdbcsqlite3-adapter', '1.3.0.rc1')
57
+ else
58
+ s.add_development_dependency('sqlite3')
59
+ end
60
+ end
@@ -0,0 +1,26 @@
1
+ class Alerter::BaseBuilder
2
+
3
+ attr_reader :params
4
+
5
+ def initialize(params)
6
+ @params = params.with_indifferent_access
7
+ end
8
+
9
+ def build
10
+ klass.new.tap do |object|
11
+ params.keys.each do |field|
12
+ object.send("#{field}=", get(field)) unless get(field).nil?
13
+ end
14
+ end
15
+ end
16
+
17
+ protected
18
+
19
+ def get(key)
20
+ respond_to?(key, true) ? send(key) : params[key]
21
+ end
22
+
23
+ def recipients
24
+ Array(params[:recipients]).uniq
25
+ end
26
+ end
@@ -0,0 +1,16 @@
1
+ class Alerter::MessageBuilder < Alerter::BaseBuilder
2
+
3
+ protected
4
+
5
+ def klass
6
+ Alerter::Message
7
+ end
8
+
9
+ def short_msg
10
+ params[:short_msg] || ''
11
+ end
12
+
13
+ def long_msg
14
+ params[:long_msg] || ''
15
+ end
16
+ end
@@ -0,0 +1,13 @@
1
+ class Alerter::ReceiptBuilder < Alerter::BaseBuilder
2
+
3
+ protected
4
+
5
+ def klass
6
+ Alerter::Receipt
7
+ end
8
+
9
+ def mailbox_type
10
+ params.fetch(:mailbox_type, 'inbox')
11
+ end
12
+
13
+ end
@@ -0,0 +1,15 @@
1
+ class Alerter::BaseMailer < ActionMailer::Base
2
+ default :from => Alerter.default_from
3
+
4
+ private
5
+
6
+ def set_subject()
7
+ @subject ||= Alerter.default_subject
8
+ strip_tags(@subject)
9
+ end
10
+
11
+ def strip_tags(text)
12
+ ::Alerter::Cleaner.instance.strip_tags(text)
13
+ end
14
+
15
+ end
@@ -0,0 +1,12 @@
1
+ class Alerter::MessageMailer < Alerter::BaseMailer
2
+ #Sends and email with the message
3
+ def send_email(message, receiver)
4
+ @message = message
5
+ @receiver = receiver
6
+ set_subject
7
+ mail :to => receiver.send(Alerter.email_method),
8
+ :subject => @subject,
9
+ :template_name => 'new_message_email'
10
+ end
11
+
12
+ end
@@ -0,0 +1,74 @@
1
+ class Alerter::Mailbox
2
+ attr_reader :notifiable
3
+
4
+ #Initializer method
5
+ def initialize(notifiable)
6
+ @notifiable = notifiable
7
+ end
8
+
9
+ #Returns the messages for the messageable
10
+ def all_messages(options = {})
11
+ #:type => nil is a hack not to give Messages as Notifications
12
+ messages = Alerter::Message.receipts(@notifiable).where(:type => nil).order("alerter_messages.created_at DESC")
13
+ if options[:read] == false || options[:unread]
14
+ messages = messages.unread
15
+ end
16
+
17
+ messages
18
+ end
19
+
20
+ #Returns the conversations for the messageable
21
+ #
22
+ #Options
23
+ #
24
+ #* :mailbox_type
25
+ # * "inbox"
26
+ # * "trash"
27
+ #
28
+ #* :read=false
29
+ #* :unread=true
30
+ #
31
+ def messages(options = {})
32
+ messages = get_messages(options[:mailbox_type])
33
+
34
+ if options[:read] == false || options[:unread]
35
+ messages = messages.unread #(notifiable)
36
+ end
37
+
38
+ messages
39
+ end
40
+
41
+ #Returns the messages in the inbox of notifiable
42
+ #
43
+ #Same as conversations({:mailbox_type => 'inbox'})
44
+ def inbox(options={})
45
+ options = options.merge(:mailbox_type => 'inbox')
46
+ messages(options)
47
+ end
48
+
49
+ def trash(options={})
50
+ options = options.merge(:mailbox_type => 'trash')
51
+ messages(options)
52
+ end
53
+
54
+
55
+ #Returns all the receipts of notifiable from Messages
56
+ def receipts(options = {})
57
+ Alerter::Receipt.where(options).recipient(notifiable)
58
+ end
59
+
60
+
61
+ private
62
+
63
+ def get_messages(mailbox)
64
+ case mailbox
65
+ when 'inbox'
66
+ Alerter::Message.inbox(notifiable)
67
+ when 'trash'
68
+ Alerter::Message.trash(notifiable)
69
+ end
70
+
71
+ end
72
+
73
+
74
+ end