Wupee is a simple gem which tries to fill the gap of lacking gems to manage notifications in Rails app. Wupee is a opinionated solution which assumes that users needs to:
- be able to receive notifications in the app
- be able to receive notifications by email
- be able to configure if they wants to either receive emails AND notifications or emails or only notifications or nothing
The main object of the solution is the Wupee::Notification
which stores:
- receiver (polymorphic): the recipient of the message
- attached_object (polymorphic): the subject of the notification
- notification_type_id: a reference to a
Wupee::NotificationType
object - is_read: boolean
To use it, add it to your Gemfile:
gem 'wupee'
and bundle:
$ bundle
Run the generator, install migrations and migrate:
$ rails g wupee:install
$ rake wupee:install:migrations
$ rake db:migrate
Running the generator will do a few things:
- add the engine routes to your routes.rb:
# config/routes.rb
mount Wupee::Engine, at: "/wupee"
- create wupee initializer:
# config/initializers/wupee.rb
Wupee.mailer = NotificationsMailer # the class of the mailer you will use to send the emails
Wupee.deliver_when = :now # use :later if you already configured a queuing system
Wupee.receivers = 'User' # class name of your notification receivers
# enable callbacks to create Wupee::NotificationTypeConfiguration object of
# each user when you create a new Wupee::NotificationType
- create a mailer
NotificationsMailer
which inheritates fromWupee::NotificationsMailer
# app/mailers/notifications_mailer.rb
class NotificationsMailer < Wupee::NotificationsMailer
default from: '[email protected]'
layout false
end
- adds wupee to your locale yml file (for email subjects)
# config/locales/en.yml
en:
wupee:
email_subjects:
rails g wupee:notification_type user_has_been_created
Will execute a few things:
- add an entry to your locale yml file :
en:
wupee:
email_subjects:
user_has_been_created: "user_has_been_created"
Feel free to edit the subject, you can put variables, example
...
user_has_been_created: "New user created: %{user_full_name}"
- create a json template for the notification:
json.subject ""
json.body ""
json.url ""
# none of this json attribute are mandatory!
In this template, you have access to the notification variable. You can customize it to fit your need, this is just an example.
- create an empty html template for the notification:
<!-- app/views/wupee/notifications/_user_has_been_created.html.erb -->
- You will have to create your email template as the generator doesn't create it.
For example, if your mailer is named
NotificationsMailer
, your template will take place inapp/views/notifications_mailer/user_has_been_created.html.erb
An object of the class Wupee::NotificationTypeConfiguration
references/stores:
- receiver (polymorphic)
- notification_type (object of class
Wupee::NotificationType
) - value (an enum)
The attribute value can be:
- 'both' : the receiver wants notifications AND emails of the
Wupee::NotificationType
type (default value) - 'nothing' : the receiver doesn't want to receive nothing from the
Wupee::NotificationType
type - 'email' : the receiver wants to receive only emails
- 'notification' : the receiver wants to receive only notifications
Just let the user edit this object to make him able to activate/deactivate notifications or emails.
Including the concern Wupee::Receiver
in your receiver class (probably the User
class) permits a few things:
- get notifications of a user:
@user.notifications
- get notifications_type_configurations of a user:
@user.notifications_type_configurations
- execute an after_create callback to create
Wupee::NotificationTypeConfiguration
for eachWupee::NotificationType
object for the receiver - destroy
Wupee::Notification
andWupee::NotificationTypeConfiguration
associated to the receiver from db if it is destroyed
Including the concern Wupee::AttachedObject
in your attached object classe(s) permits a few things:
- get notifications associated to an attached object:
@attached_object.notifications_as_attached_object
- destroy
Wupee::Notification
associated to the attached object if it is destroyed
Imagine that you want to notify all admin that a new user signed up in your app and that you have a scope admin
in your User
class.
Wupee.notify do |n|
n.attached_object @the_new_user
n.notif_type :user_has_been_created # you can also pass an instance of a Wupee::NotificationType class to this method
n.subject_vars user_full_name: Proc.new { |notification| notification.attached_object.full_name } # variables to be interpolated the fill in the subject of the email (obviously optional)
n.locals extra_data: "something" # extra_data will be accessible in template as @locals[:extra_data]
n.receivers User.admin # you can use the method receiver instead of receivers for clarity if you pass only one instance of a receiver
n.deliver :now # you can overwrite global configuration here, optional
end
You can also use the method notify
this way:
Wupee.notify attached_object: @the_new_user, notif_type: :user_has_been_created, subject_vars: { user_full_name: Proc.new { |notification| notification.attached_object.full_name } }, locals: { extra_data: "Yeahhhhh" }, receivers: User.admin
The method will take care to check receiver's configurations to only send emails to those who want them.
generate Wupee::NotificationTypeConfiguration objects for given Wupee::NotificationType name and for all receivers of given class (default to User)
Example for a Wupee::NotificationType named 'user_destroyed':
rake 'wupee:generate_notification_type_configurations[user_destroyed]' # for User class
rake 'wupee:generate_notification_type_configurations[user_destroyed,Admin]' # for Admin class
In order to make this controller work, you need a method current_user
which return the user currently signed in.
The controller have various actions all scoped for the current user:
wupee/api/notifications#index
: fetch notifications, take an optional parameteris_read
(false by default)wupee/api/notifications#show
: fetch a notificationwupee/api/notifications#update
: mark as read a notificationwupee/api/notifications#update_all
: mark as read all notifications
The class also define 2 methods which you could use (in your views for example):
wants_email?
: return a booleanwants_notification?
: return a boolean
The system relies on the fact that you have an object in db for each couple of [receiver, Wupee::NotificationType
]. Even if the gem provides callbacks to take care of that, be sure that those objects are created otherwise notifications won't be sent for thoses receivers.
What's UP SlEEde
This project rocks and uses MIT-LICENSE.