From cd11efea1de5d7f1ed85b7ae64fccdf26c08405f Mon Sep 17 00:00:00 2001 From: Sojan Jose Date: Wed, 23 Jun 2021 19:29:27 +0530 Subject: [PATCH] feat: Add CSAT Message Template Hooks (#2494) --- app/models/inbox.rb | 4 +- .../hook_execution_service.rb | 31 ++++++++++-- .../message_templates/template/csat_survey.rb | 24 +++++++++ config/locales/en.yml | 1 + .../hook_execution_service_spec.rb | 49 +++++++++++++++++++ .../template/csat_survey_spec.rb | 13 +++++ 6 files changed, 115 insertions(+), 7 deletions(-) create mode 100644 app/services/message_templates/template/csat_survey.rb create mode 100644 spec/services/message_templates/template/csat_survey_spec.rb diff --git a/app/models/inbox.rb b/app/models/inbox.rb index 15e21e150..3de590cd2 100644 --- a/app/models/inbox.rb +++ b/app/models/inbox.rb @@ -67,11 +67,11 @@ class Inbox < ApplicationRecord end def facebook? - channel.class.name.to_s == 'Channel::FacebookPage' + channel_type == 'Channel::FacebookPage' end def web_widget? - channel.class.name.to_s == 'Channel::WebWidget' + channel_type == 'Channel::WebWidget' end def inbox_type diff --git a/app/services/message_templates/hook_execution_service.rb b/app/services/message_templates/hook_execution_service.rb index 9700ff78b..ee116f462 100644 --- a/app/services/message_templates/hook_execution_service.rb +++ b/app/services/message_templates/hook_execution_service.rb @@ -5,11 +5,7 @@ class MessageTemplates::HookExecutionService return if inbox.agent_bot_inbox&.active? return if conversation.campaign.present? - # TODO: let's see whether this is needed and remove this and related logic if not - # ::MessageTemplates::Template::OutOfOffice.new(conversation: conversation).perform if should_send_out_of_office_message? - - ::MessageTemplates::Template::Greeting.new(conversation: conversation).perform if should_send_greeting? - ::MessageTemplates::Template::EmailCollect.new(conversation: conversation).perform if inbox.enable_email_collect && should_send_email_collect? + trigger_templates end private @@ -17,6 +13,14 @@ class MessageTemplates::HookExecutionService delegate :inbox, :conversation, to: :message delegate :contact, to: :conversation + def trigger_templates + # TODO: let's see whether this is needed and remove this and related logic if not + # ::MessageTemplates::Template::OutOfOffice.new(conversation: conversation).perform if should_send_out_of_office_message? + ::MessageTemplates::Template::Greeting.new(conversation: conversation).perform if should_send_greeting? + ::MessageTemplates::Template::EmailCollect.new(conversation: conversation).perform if inbox.enable_email_collect && should_send_email_collect? + ::MessageTemplates::Template::CsatSurvey.new(conversation: conversation).perform if should_send_csat_survey? + end + def should_send_out_of_office_message? inbox.out_of_office? && conversation.messages.today.template.empty? && inbox.out_of_office_message.present? end @@ -41,4 +45,21 @@ class MessageTemplates::HookExecutionService def contact_has_email? contact.email end + + def csat_enabled_inbox? + # for now csat only available in web widget channel + return unless inbox.web_widget? + return unless inbox.csat_survey_enabled? + + true + end + + def should_send_csat_survey? + return unless conversation.resolved? + return unless csat_enabled_inbox? + # only send CSAT once in a conversation + return if conversation.messages.where(content_type: :input_csat).present? + + true + end end diff --git a/app/services/message_templates/template/csat_survey.rb b/app/services/message_templates/template/csat_survey.rb new file mode 100644 index 000000000..4171367c7 --- /dev/null +++ b/app/services/message_templates/template/csat_survey.rb @@ -0,0 +1,24 @@ +class MessageTemplates::Template::CsatSurvey + pattr_initialize [:conversation!] + + def perform + ActiveRecord::Base.transaction do + conversation.messages.create!(csat_survey_message_params) + end + end + + private + + delegate :contact, :account, to: :conversation + delegate :inbox, to: :message + + def csat_survey_message_params + { + account_id: @conversation.account_id, + inbox_id: @conversation.inbox_id, + message_type: :template, + content_type: :input_csat, + content: I18n.t('conversations.templates.csat_input_message_body') + } + end +end diff --git a/config/locales/en.yml b/config/locales/en.yml index b4bd4357c..2e7e85d03 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -82,6 +82,7 @@ en: greeting_message_body: "%{account_name} typically replies in a few hours." ways_to_reach_you_message_body: "Give the team a way to reach you." email_input_box_message_body: "Get notified by email" + csat_input_message_body: "Please rate the conversation" reply: email_subject: "New messages on this conversation" transcript_subject: "Conversation Transcript" diff --git a/spec/services/message_templates/hook_execution_service_spec.rb b/spec/services/message_templates/hook_execution_service_spec.rb index 435d6b4d3..0c20f643d 100644 --- a/spec/services/message_templates/hook_execution_service_spec.rb +++ b/spec/services/message_templates/hook_execution_service_spec.rb @@ -87,6 +87,55 @@ describe ::MessageTemplates::HookExecutionService do end end + context 'when CSAT Survey' do + let(:csat_survey) { double } + let(:conversation) { create(:conversation) } + + before do + allow(::MessageTemplates::Template::CsatSurvey).to receive(:new).and_return(csat_survey) + allow(csat_survey).to receive(:perform).and_return(true) + end + + it 'calls ::MessageTemplates::Template::CsatSurvey when a conversation is resolved in an inbox with survey enabled' do + conversation.inbox.update(csat_survey_enabled: true) + + conversation.resolved! + + expect(::MessageTemplates::Template::CsatSurvey).to have_received(:new).with(conversation: conversation) + expect(csat_survey).to have_received(:perform) + end + + it 'will not call ::MessageTemplates::Template::CsatSurvey when Csat is not enabled' do + conversation.inbox.update(csat_survey_enabled: false) + + conversation.resolved! + + expect(::MessageTemplates::Template::CsatSurvey).not_to have_received(:new).with(conversation: conversation) + expect(csat_survey).not_to have_received(:perform) + end + + it 'will not call ::MessageTemplates::Template::CsatSurvey if its not a website widget' do + api_channel = create(:channel_api) + conversation = create(:conversation, inbox: create(:inbox, channel: api_channel)) + conversation.inbox.update(csat_survey_enabled: true) + + conversation.resolved! + + expect(::MessageTemplates::Template::CsatSurvey).not_to have_received(:new).with(conversation: conversation) + expect(csat_survey).not_to have_received(:perform) + end + + it 'will not call ::MessageTemplates::Template::CsatSurvey if another Csat was already sent' do + conversation.inbox.update(csat_survey_enabled: true) + conversation.messages.create!(message_type: 'outgoing', content_type: :input_csat, account: conversation.account, inbox: conversation.inbox) + + conversation.resolved! + + expect(::MessageTemplates::Template::CsatSurvey).not_to have_received(:new).with(conversation: conversation) + expect(csat_survey).not_to have_received(:perform) + end + end + # TODO: remove this if this hook is removed # context 'when it is after working hours' do # it 'calls ::MessageTemplates::Template::OutOfOffice' do diff --git a/spec/services/message_templates/template/csat_survey_spec.rb b/spec/services/message_templates/template/csat_survey_spec.rb new file mode 100644 index 000000000..e02c93520 --- /dev/null +++ b/spec/services/message_templates/template/csat_survey_spec.rb @@ -0,0 +1,13 @@ +require 'rails_helper' + +describe ::MessageTemplates::Template::CsatSurvey do + context 'when this hook is called' do + let(:conversation) { create(:conversation) } + + it 'creates the out of office messages' do + described_class.new(conversation: conversation).perform + expect(conversation.messages.template.count).to eq(1) + expect(conversation.messages.template.first.content_type).to eq('input_csat') + end + end +end