feat: Add support for conversation attribute automation conditions in message event (#4518)

Co-authored-by: Pranav Raj S <pranav@chatwoot.com>
This commit is contained in:
Tejaswini Chile
2022-04-21 20:52:23 +05:30
committed by GitHub
parent b082b0e58c
commit 2acb48bbe0
7 changed files with 255 additions and 37 deletions

View File

@@ -9,6 +9,7 @@ class Messages::MessageBuilder
@user = user
@message_type = params[:message_type] || 'outgoing'
@attachments = params[:attachments]
@automation_rule = @params&.dig(:content_attributes, :automation_rule_id)
return unless params.instance_of?(ActionController::Parameters)
@in_reply_to = params.to_unsafe_h&.dig(:content_attributes, :in_reply_to)
@@ -64,6 +65,10 @@ class Messages::MessageBuilder
@params[:external_created_at].present? ? { external_created_at: @params[:external_created_at] } : {}
end
def automation_rule_id
@automation_rule.present? ? { content_attributes: { automation_rule_id: @automation_rule } } : {}
end
def message_sender
return if @params[:sender_type] != 'AgentBot'
@@ -82,6 +87,6 @@ class Messages::MessageBuilder
items: @items,
in_reply_to: @in_reply_to,
echo_id: @params[:echo_id]
}.merge(external_created_at)
}.merge(external_created_at).merge(automation_rule_id)
end
end

View File

@@ -64,6 +64,13 @@ export const AUTOMATIONS = {
inputType: 'plain_text',
filterOperators: OPERATOR_TYPES_2,
},
{
key: 'inbox_id',
name: 'Inbox',
attributeI18nKey: 'INBOX',
inputType: 'multi_select',
filterOperators: OPERATOR_TYPES_1,
},
],
actions: [
{
@@ -149,6 +156,13 @@ export const AUTOMATIONS = {
inputType: 'plain_text',
filterOperators: OPERATOR_TYPES_2,
},
{
key: 'inbox_id',
name: 'Inbox',
attributeI18nKey: 'INBOX',
inputType: 'multi_select',
filterOperators: OPERATOR_TYPES_1,
},
],
actions: [
{
@@ -247,6 +261,13 @@ export const AUTOMATIONS = {
inputType: 'search_select',
filterOperators: OPERATOR_TYPES_3,
},
{
key: 'inbox_id',
name: 'Inbox',
attributeI18nKey: 'INBOX',
inputType: 'multi_select',
filterOperators: OPERATOR_TYPES_1,
},
],
actions: [
{

View File

@@ -36,7 +36,7 @@ class AutomationRuleListener < BaseListener
return unless rule_present?('message_created', account)
@rules.each do |rule|
conditions_match = ::AutomationRules::ConditionsFilterService.new(rule, message.conversation, { message: message }).message_conditions
conditions_match = ::AutomationRules::ConditionsFilterService.new(rule, message.conversation, { message: message }).perform
::AutomationRules::ActionService.new(rule, account, message.conversation).perform if conditions_match.present?
end
end

View File

@@ -27,7 +27,7 @@ class AutomationRule < ApplicationRecord
scope :active, -> { where(active: true) }
CONDITIONS_ATTRS = %w[content email country_code status message_type browser_language assignee_id team_id referer city company].freeze
CONDITIONS_ATTRS = %w[content email country_code status message_type browser_language assignee_id team_id referer city company inbox_id].freeze
ACTIONS_ATTRS = %w[send_message add_label send_email_to_team assign_team assign_best_agents send_attachments].freeze
private

View File

@@ -56,7 +56,7 @@ class AutomationRules::ActionService
end
def send_message(message)
params = { content: message[0], private: false }
params = { content: message[0], private: false, content_attributes: { automation_rule_id: @rule.id } }
mb = Messages::MessageBuilder.new(nil, @conversation, params)
mb.perform
end

View File

@@ -14,36 +14,33 @@ class AutomationRules::ConditionsFilterService < FilterService
end
def perform
conversation_filters = @filters['conversations']
contact_filters = @filters['contacts']
@conversation_filters = @filters['conversations']
@contact_filters = @filters['contacts']
@message_filters = @filters['messages']
@rule.conditions.each_with_index do |query_hash, current_index|
conversation_filter = conversation_filters[query_hash['attribute_key']]
contact_filter = contact_filters[query_hash['attribute_key']]
if conversation_filter
@query_string += conversation_query_string('conversations', conversation_filter, query_hash.with_indifferent_access, current_index)
elsif contact_filter
@query_string += conversation_query_string('contacts', contact_filter, query_hash.with_indifferent_access, current_index)
elsif custom_attribute(query_hash['attribute_key'], @account)
# send table name according to attribute key right now we are supporting contact based custom attribute filter
@query_string += custom_attribute_query(query_hash.with_indifferent_access, 'contacts', current_index)
end
apply_filter(query_hash, current_index)
end
records = base_relation.where(@query_string, @filter_values.with_indifferent_access)
records.any?
end
def message_conditions
message_filters = @filters['messages']
def apply_filter(query_hash, current_index)
conversation_filter = @conversation_filters[query_hash['attribute_key']]
contact_filter = @contact_filters[query_hash['attribute_key']]
message_filter = @message_filters[query_hash['attribute_key']]
@rule.conditions.each_with_index do |query_hash, current_index|
current_filter = message_filters[query_hash['attribute_key']]
@query_string += message_query_string(current_filter, query_hash.with_indifferent_access, current_index)
if conversation_filter
@query_string += conversation_query_string('conversations', conversation_filter, query_hash.with_indifferent_access, current_index)
elsif contact_filter
@query_string += contact_query_string(contact_filter, query_hash.with_indifferent_access, current_index)
elsif message_filter
@query_string += message_query_string(message_filter, query_hash.with_indifferent_access, current_index)
elsif custom_attribute(query_hash['attribute_key'], @account)
# send table name according to attribute key right now we are supporting contact based custom attribute filter
@query_string += custom_attribute_query(query_hash.with_indifferent_access, 'contacts', current_index)
end
records = Message.where(id: @options[:message].id).where(@query_string, @filter_values.with_indifferent_access)
records.any?
end
def message_query_string(current_filter, query_hash, current_index)
@@ -59,16 +56,18 @@ class AutomationRules::ConditionsFilterService < FilterService
end
# This will be used in future for contact automation rule
def contact_conditions(_contact)
conversation_filters = @filters['conversations']
def contact_query_string(current_filter, query_hash, current_index)
attribute_key = query_hash['attribute_key']
query_operator = query_hash['query_operator']
@rule.conditions.each_with_index do |query_hash, current_index|
current_filter = conversation_filters[query_hash['attribute_key']]
@query_string += conversation_query_string(current_filter, query_hash.with_indifferent_access, current_index)
filter_operator_value = filter_operation(query_hash, current_index)
case current_filter['attribute_type']
when 'additional_attributes'
" contacts.additional_attributes ->> '#{attribute_key}' #{filter_operator_value} #{query_operator} "
when 'standard'
" contacts.#{attribute_key} #{filter_operator_value} #{query_operator} "
end
records = base_relation.where(@query_string, @filter_values.with_indifferent_access)
records.any?
end
def conversation_query_string(table_name, current_filter, query_hash, current_index)
@@ -91,6 +90,12 @@ class AutomationRules::ConditionsFilterService < FilterService
private
def base_relation
Conversation.where(id: @conversation.id).joins('LEFT OUTER JOIN contacts on conversations.contact_id = contacts.id')
records = Conversation.where(id: @conversation.id).joins(
'LEFT OUTER JOIN contacts on conversations.contact_id = contacts.id'
).joins(
'LEFT OUTER JOIN messages on messages.conversation_id = conversations.id'
)
records = records.where(messages: { id: @options[:message].id }) if @options[:message].present?
records
end
end