From 7c21cef467ea1d3a556dc2ed5d0db033bfc5d883 Mon Sep 17 00:00:00 2001 From: Tejaswini Chile Date: Wed, 8 Feb 2023 12:05:22 +0530 Subject: [PATCH] Added event for conversation opened (#6412) --- .../dashboard/helper/automationHelper.js | 11 ++ .../mixins/automations/methodsMixin.js | 3 + .../settings/automation/constants.js | 109 ++++++++++++++++++ app/listeners/automation_rule_listener.rb | 17 +++ .../automation_rule_listener_spec.rb | 64 ++++++++++ 5 files changed, 204 insertions(+) diff --git a/app/javascript/dashboard/helper/automationHelper.js b/app/javascript/dashboard/helper/automationHelper.js index 6bafb6b45..302a202f5 100644 --- a/app/javascript/dashboard/helper/automationHelper.js +++ b/app/javascript/dashboard/helper/automationHelper.js @@ -165,6 +165,17 @@ export const getDefaultConditions = eventName => { }, ]; } + if (eventName === 'conversation_opened') { + return [ + { + attribute_key: 'browser_language', + filter_operator: 'equal_to', + values: '', + query_operator: 'and', + custom_attribute_type: '', + }, + ]; + } return [ { attribute_key: 'status', diff --git a/app/javascript/dashboard/mixins/automations/methodsMixin.js b/app/javascript/dashboard/mixins/automations/methodsMixin.js index 1387868c5..bbdb3dfd6 100644 --- a/app/javascript/dashboard/mixins/automations/methodsMixin.js +++ b/app/javascript/dashboard/mixins/automations/methodsMixin.js @@ -284,6 +284,9 @@ export default { this.automationTypes.conversation_updated.conditions.push( ...manifestedCustomAttributes ); + this.automationTypes.conversation_opened.conditions.push( + ...manifestedCustomAttributes + ); }, }, }; diff --git a/app/javascript/dashboard/routes/dashboard/settings/automation/constants.js b/app/javascript/dashboard/routes/dashboard/settings/automation/constants.js index 260288e8b..1f3414809 100644 --- a/app/javascript/dashboard/routes/dashboard/settings/automation/constants.js +++ b/app/javascript/dashboard/routes/dashboard/settings/automation/constants.js @@ -308,6 +308,111 @@ export const AUTOMATIONS = { }, ], }, + conversation_opened: { + conditions: [ + { + key: 'browser_language', + name: 'Browser Language', + attributeI18nKey: 'BROWSER_LANGUAGE', + inputType: 'search_select', + filterOperators: OPERATOR_TYPES_1, + }, + { + key: 'mail_subject', + name: 'Email Subject', + attributeI18nKey: 'MAIL_SUBJECT', + inputType: 'plain_text', + filterOperators: OPERATOR_TYPES_2, + }, + { + key: 'country_code', + name: 'Country', + attributeI18nKey: 'COUNTRY_NAME', + inputType: 'search_select', + filterOperators: OPERATOR_TYPES_1, + }, + { + key: 'referer', + name: 'Referrer Link', + attributeI18nKey: 'REFERER_LINK', + inputType: 'plain_text', + filterOperators: OPERATOR_TYPES_2, + }, + { + key: 'assignee_id', + name: 'Assignee', + attributeI18nKey: 'ASSIGNEE_NAME', + inputType: 'search_select', + filterOperators: OPERATOR_TYPES_3, + }, + { + key: 'team_id', + name: 'Team', + attributeI18nKey: 'TEAM_NAME', + inputType: 'search_select', + filterOperators: OPERATOR_TYPES_3, + }, + { + key: 'inbox_id', + name: 'Inbox', + attributeI18nKey: 'INBOX', + inputType: 'multi_select', + filterOperators: OPERATOR_TYPES_1, + }, + ], + actions: [ + { + key: 'assign_agent', + name: 'Assign to agent', + attributeI18nKey: 'ASSIGN_AGENT', + }, + { + key: 'assign_team', + name: 'Assign a team', + attributeI18nKey: 'ASSIGN_TEAM', + }, + { + key: 'assign_agent', + name: 'Assign an agent', + attributeI18nKey: 'ASSIGN_AGENT', + }, + { + key: 'send_email_to_team', + name: 'Send an email to team', + attributeI18nKey: 'SEND_EMAIL_TO_TEAM', + }, + { + key: 'send_message', + name: 'Send a message', + attributeI18nKey: 'SEND_MESSAGE', + }, + { + key: 'send_email_transcript', + name: 'Send an email transcript', + attributeI18nKey: 'SEND_EMAIL_TRANSCRIPT', + }, + { + key: 'mute_conversation', + name: 'Mute conversation', + attributeI18nKey: 'MUTE_CONVERSATION', + }, + { + key: 'snooze_conversation', + name: 'Snooze conversation', + attributeI18nKey: 'MUTE_CONVERSATION', + }, + { + key: 'send_webhook_event', + name: 'Send Webhook Event', + attributeI18nKey: 'SEND_WEBHOOK_EVENT', + }, + { + key: 'send_attachment', + name: 'Send Attachment', + attributeI18nKey: 'SEND_ATTACHMENT', + }, + ], + }, }; export const AUTOMATION_RULE_EVENTS = [ @@ -323,6 +428,10 @@ export const AUTOMATION_RULE_EVENTS = [ key: 'message_created', value: 'Message Created', }, + { + key: 'conversation_opened', + value: 'Conversation Opened', + }, ]; export const AUTOMATION_ACTION_TYPES = [ diff --git a/app/listeners/automation_rule_listener.rb b/app/listeners/automation_rule_listener.rb index 4e78abcc6..3a88963a2 100644 --- a/app/listeners/automation_rule_listener.rb +++ b/app/listeners/automation_rule_listener.rb @@ -33,6 +33,23 @@ class AutomationRuleListener < BaseListener end end + def conversation_opened(event_obj) + return if performed_by_automation?(event_obj) + + conversation = event_obj.data[:conversation] + account = conversation.account + changed_attributes = event_obj.data[:changed_attributes] + + return unless rule_present?('conversation_opened', account) + + rules = current_account_rules('conversation_opened', account) + + rules.each do |rule| + conditions_match = ::AutomationRules::ConditionsFilterService.new(rule, conversation, { changed_attributes: changed_attributes }).perform + AutomationRules::ActionService.new(rule, account, conversation).perform if conditions_match.present? + end + end + def message_created(event_obj) message = event_obj.data[:message] diff --git a/spec/listeners/automation_rule_listener_spec.rb b/spec/listeners/automation_rule_listener_spec.rb index 1da7225bd..0517f99d6 100644 --- a/spec/listeners/automation_rule_listener_spec.rb +++ b/spec/listeners/automation_rule_listener_spec.rb @@ -420,6 +420,70 @@ describe AutomationRuleListener do end end + describe '#conversation_opened' do + before do + conversation.update!(status: :open, team_id: team.id) + automation_rule.update!( + event_name: 'conversation_opened', + name: 'Call actions conversation opened', + description: 'Add labels, assign team after conversation updated', + conditions: [{ attribute_key: 'team_id', filter_operator: 'equal_to', values: [team.id], query_operator: nil }.with_indifferent_access] + ) + end + + let!(:event) do + Events::Base.new('conversation_opened', Time.zone.now, { conversation: conversation.reload }) + end + + context 'when rule matches' do + it 'triggers automation rule to add label' do + expect(conversation.labels).to eq([]) + listener.conversation_opened(event) + conversation.reload + + expect(conversation.labels.pluck(:name)).to contain_exactly('support', 'priority_customer') + end + + it 'triggers automation rule to assign best agents' do + expect(conversation.assignee).to be_nil + listener.conversation_opened(event) + conversation.reload + + expect(conversation.assignee).to eq(user_1) + end + + it 'triggers automation rule send email transcript to the mentioned email' do + mailer = double + expect(TeamNotifications::AutomationNotificationMailer).to receive(:conversation_creation) + listener.conversation_opened(event) + conversation.reload + + allow(mailer).to receive(:conversation_transcript) + end + + it 'triggers automation rule send email to the team' do + message_delivery = instance_double(ActionMailer::MessageDelivery) + + expect(TeamNotifications::AutomationNotificationMailer).to receive(:conversation_creation).with( + conversation, team, + 'Please pay attention to this conversation, its from high priority customer' + ).and_return(message_delivery) + allow(message_delivery).to receive(:deliver_now) + + listener.conversation_opened(event) + end + + it 'triggers automation rule send message to the contacts' do + expect(conversation.messages).to be_empty + expect(TeamNotifications::AutomationNotificationMailer).to receive(:conversation_creation) + listener.conversation_opened(event) + conversation.reload + + expect(conversation.messages.first.content).to eq('Send this message.') + end + end + end + describe '#message_created event based on case in-sensitive filter' do before do automation_rule.update!(