From 96da27f1f6fe27e6c0dac8b241840a150b53dde6 Mon Sep 17 00:00:00 2001 From: Sojan Jose Date: Fri, 1 May 2020 14:53:43 +0530 Subject: [PATCH 1/5] Feature: User Notification Objects (#752) Co-authored-by: Pranav Raj S --- app/builders/notification_builder.rb | 32 +++++++++++ .../api/v1/accounts/contacts_controller.rb | 5 -- .../v1/accounts/notifications_controller.rb | 21 +++++++ .../notification_subscriptions_controller.rb | 18 ++++++ app/dispatchers/async_dispatcher.rb | 3 +- app/dispatchers/sync_dispatcher.rb | 2 +- .../settings/profile/EmailNotifications.vue | 4 +- app/listeners/action_cable_listener.rb | 48 ++++++++-------- app/listeners/email_notification_listener.rb | 12 ---- app/listeners/notification_listener.rb | 29 ++++++++++ .../conversation_notifications_mailer.rb | 4 +- app/models/account_user.rb | 3 +- app/models/conversation.rb | 24 +++----- app/models/message.rb | 4 +- app/models/notification.rb | 47 +++++++++++++++ app/models/notification_setting.rb | 8 +-- app/models/notification_subscription.rb | 26 +++++++++ app/models/user.rb | 9 +-- .../email_notification_service.rb | 20 +++++++ .../notification/push_notification_service.rb | 17 ++++++ ...l.erb => conversation_assignment.html.erb} | 0 ...tml.erb => conversation_creation.html.erb} | 0 config/routes.rb | 2 + .../20200422130153_create_notifications.rb | 34 +++++++++++ db/schema.rb | 27 +++++++++ .../v1/accounts/contacts_controller_spec.rb | 6 +- .../notification_settings_controller_spec.rb | 4 +- .../accounts/notifications_controller_spec.rb | 57 +++++++++++++++++++ ...ification_subscriptions_controller_spec.rb | 31 ++++++++++ spec/factories/notifications.rb | 10 ++++ spec/listeners/action_cable_listener_spec.rb | 18 +++--- ..._spec.rb => notification_listener_spec.rb} | 10 ++-- .../conversation_notifications_mailer_spec.rb | 8 +-- spec/models/account_user_spec.rb | 4 +- spec/models/conversation_spec.rb | 24 +++++--- 35 files changed, 461 insertions(+), 110 deletions(-) create mode 100644 app/builders/notification_builder.rb create mode 100644 app/controllers/api/v1/accounts/notifications_controller.rb create mode 100644 app/controllers/api/v1/notification_subscriptions_controller.rb delete mode 100644 app/listeners/email_notification_listener.rb create mode 100644 app/listeners/notification_listener.rb create mode 100644 app/models/notification.rb create mode 100644 app/models/notification_subscription.rb create mode 100644 app/services/notification/email_notification_service.rb create mode 100644 app/services/notification/push_notification_service.rb rename app/views/mailers/agent_notifications/conversation_notifications_mailer/{conversation_assigned.html.erb => conversation_assignment.html.erb} (100%) rename app/views/mailers/agent_notifications/conversation_notifications_mailer/{conversation_created.html.erb => conversation_creation.html.erb} (100%) create mode 100644 db/migrate/20200422130153_create_notifications.rb create mode 100644 spec/controllers/api/v1/accounts/notifications_controller_spec.rb create mode 100644 spec/controllers/api/v1/notification_subscriptions_controller_spec.rb create mode 100644 spec/factories/notifications.rb rename spec/listeners/{email_notification_listener_spec.rb => notification_listener_spec.rb} (87%) diff --git a/app/builders/notification_builder.rb b/app/builders/notification_builder.rb new file mode 100644 index 000000000..d41debe0c --- /dev/null +++ b/app/builders/notification_builder.rb @@ -0,0 +1,32 @@ +class NotificationBuilder + pattr_initialize [:notification_type!, :user!, :account!, :primary_actor!] + + def perform + return unless user_subscribed_to_notification? + + build_notification + end + + private + + def secondary_actor + Current.user + end + + def user_subscribed_to_notification? + notification_setting = user.notification_settings.find_by(account_id: account.id) + return true if notification_setting.public_send("email_#{notification_type}?") + return true if notification_setting.public_send("push_#{notification_type}?") + + false + end + + def build_notification + user.notifications.create!( + notification_type: notification_type, + account: account, + primary_actor: primary_actor, + secondary_actor: secondary_actor + ) + end +end diff --git a/app/controllers/api/v1/accounts/contacts_controller.rb b/app/controllers/api/v1/accounts/contacts_controller.rb index 9d95f69aa..a3713660b 100644 --- a/app/controllers/api/v1/accounts/contacts_controller.rb +++ b/app/controllers/api/v1/accounts/contacts_controller.rb @@ -4,11 +4,6 @@ class Api::V1::Accounts::ContactsController < Api::BaseController before_action :check_authorization before_action :fetch_contact, only: [:show, :update] - skip_before_action :authenticate_user!, only: [:create] - skip_before_action :set_current_user, only: [:create] - skip_before_action :check_subscription, only: [:create] - skip_around_action :handle_with_exception, only: [:create] - def index @contacts = current_account.contacts end diff --git a/app/controllers/api/v1/accounts/notifications_controller.rb b/app/controllers/api/v1/accounts/notifications_controller.rb new file mode 100644 index 000000000..5d9a5ea54 --- /dev/null +++ b/app/controllers/api/v1/accounts/notifications_controller.rb @@ -0,0 +1,21 @@ +class Api::V1::Accounts::NotificationsController < Api::BaseController + protect_from_forgery with: :null_session + + before_action :fetch_notification, only: [:update] + + def index + @notifications = current_user.notifications.where(account_id: current_account.id) + render json: @notifications + end + + def update + @notification.update(read_at: DateTime.now.utc) + render json: @notification + end + + private + + def fetch_notification + @notification = current_user.notifications.find(params[:id]) + end +end diff --git a/app/controllers/api/v1/notification_subscriptions_controller.rb b/app/controllers/api/v1/notification_subscriptions_controller.rb new file mode 100644 index 000000000..17608e793 --- /dev/null +++ b/app/controllers/api/v1/notification_subscriptions_controller.rb @@ -0,0 +1,18 @@ +class Api::V1::NotificationSubscriptionsController < Api::BaseController + before_action :set_user + + def create + notification_subscription = @user.notification_subscriptions.create(notification_subscription_params) + render json: notification_subscription + end + + private + + def set_user + @user = current_user + end + + def notification_subscription_params + params.require(:notification_subscription).permit(:subscription_type, subscription_attributes: {}) + end +end diff --git a/app/dispatchers/async_dispatcher.rb b/app/dispatchers/async_dispatcher.rb index 72e44a1c2..a5ff03937 100644 --- a/app/dispatchers/async_dispatcher.rb +++ b/app/dispatchers/async_dispatcher.rb @@ -9,8 +9,7 @@ class AsyncDispatcher < BaseDispatcher end def listeners - listeners = [EmailNotificationListener.instance, ReportingListener.instance, WebhookListener.instance] - listeners << EventListener.instance + listeners = [EventListener.instance, ReportingListener.instance, WebhookListener.instance] listeners << SubscriptionListener.instance if ENV['BILLING_ENABLED'] listeners end diff --git a/app/dispatchers/sync_dispatcher.rb b/app/dispatchers/sync_dispatcher.rb index 509a42727..9f7adc02c 100644 --- a/app/dispatchers/sync_dispatcher.rb +++ b/app/dispatchers/sync_dispatcher.rb @@ -5,6 +5,6 @@ class SyncDispatcher < BaseDispatcher end def listeners - [ActionCableListener.instance, AgentBotListener.instance] + [ActionCableListener.instance, AgentBotListener.instance, NotificationListener.instance] end end diff --git a/app/javascript/dashboard/routes/dashboard/settings/profile/EmailNotifications.vue b/app/javascript/dashboard/routes/dashboard/settings/profile/EmailNotifications.vue index 5e4cbe227..a11b6d5bd 100644 --- a/app/javascript/dashboard/routes/dashboard/settings/profile/EmailNotifications.vue +++ b/app/javascript/dashboard/routes/dashboard/settings/profile/EmailNotifications.vue @@ -12,7 +12,7 @@ v-model="selectedNotifications" class="email-notification--checkbox" type="checkbox" - value="conversation_creation" + value="email_conversation_creation" @input="handleInput" />