feat: Add support for labels in automations (#11658)
- Add support for using labels as an action event for automation - Fix duplicated conversation_updated event dispatch for labels Fixes https://github.com/chatwoot/chatwoot/issues/8539 and multiple issues around duplication related to label change events. --------- Co-authored-by: Muhsin Keloth <muhsinkeramam@gmail.com>
This commit is contained in:
@@ -104,6 +104,7 @@ export default function useAutomationValues() {
|
||||
contacts: contacts.value,
|
||||
customAttributes: getters['attributes/getAttributes'].value,
|
||||
inboxes: inboxes.value,
|
||||
labels: labels.value,
|
||||
statusFilterOptions: statusFilterOptions.value,
|
||||
priorityOptions: priorityOptions.value,
|
||||
messageTypeOptions: messageTypeOptions.value,
|
||||
|
||||
@@ -124,6 +124,7 @@ export const getConditionOptions = ({
|
||||
customAttributes,
|
||||
inboxes,
|
||||
languages,
|
||||
labels,
|
||||
statusFilterOptions,
|
||||
teams,
|
||||
type,
|
||||
@@ -150,6 +151,7 @@ export const getConditionOptions = ({
|
||||
country_code: countries,
|
||||
message_type: messageTypeOptions,
|
||||
priority: priorityOptions,
|
||||
labels: generateConditionOptions(labels, 'title'),
|
||||
};
|
||||
|
||||
return conditionFilterMaps[type];
|
||||
|
||||
@@ -177,7 +177,8 @@
|
||||
"REFERER_LINK": "Referrer Link",
|
||||
"ASSIGNEE_NAME": "Assignee",
|
||||
"TEAM_NAME": "Team",
|
||||
"PRIORITY": "Priority"
|
||||
"PRIORITY": "Priority",
|
||||
"LABELS": "Labels"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,6 +68,12 @@ export const AUTOMATIONS = {
|
||||
inputType: 'plain_text',
|
||||
filterOperators: OPERATOR_TYPES_6,
|
||||
},
|
||||
{
|
||||
key: 'labels',
|
||||
name: 'LABELS',
|
||||
inputType: 'multi_select',
|
||||
filterOperators: OPERATOR_TYPES_3,
|
||||
},
|
||||
],
|
||||
actions: [
|
||||
{
|
||||
@@ -186,6 +192,12 @@ export const AUTOMATIONS = {
|
||||
inputType: 'multi_select',
|
||||
filterOperators: OPERATOR_TYPES_1,
|
||||
},
|
||||
{
|
||||
key: 'labels',
|
||||
name: 'LABELS',
|
||||
inputType: 'multi_select',
|
||||
filterOperators: OPERATOR_TYPES_3,
|
||||
},
|
||||
],
|
||||
actions: [
|
||||
{
|
||||
@@ -308,6 +320,12 @@ export const AUTOMATIONS = {
|
||||
inputType: 'multi_select',
|
||||
filterOperators: OPERATOR_TYPES_1,
|
||||
},
|
||||
{
|
||||
key: 'labels',
|
||||
name: 'LABELS',
|
||||
inputType: 'multi_select',
|
||||
filterOperators: OPERATOR_TYPES_3,
|
||||
},
|
||||
],
|
||||
actions: [
|
||||
{
|
||||
@@ -424,6 +442,12 @@ export const AUTOMATIONS = {
|
||||
inputType: 'multi_select',
|
||||
filterOperators: OPERATOR_TYPES_1,
|
||||
},
|
||||
{
|
||||
key: 'labels',
|
||||
name: 'LABELS',
|
||||
inputType: 'multi_select',
|
||||
filterOperators: OPERATOR_TYPES_3,
|
||||
},
|
||||
],
|
||||
actions: [
|
||||
{
|
||||
|
||||
@@ -36,7 +36,7 @@ class AutomationRule < ApplicationRecord
|
||||
|
||||
def conditions_attributes
|
||||
%w[content email country_code status message_type browser_language assignee_id team_id referer city company inbox_id
|
||||
mail_subject phone_number priority conversation_language]
|
||||
mail_subject phone_number priority conversation_language labels]
|
||||
end
|
||||
|
||||
def actions_attributes
|
||||
|
||||
@@ -10,6 +10,8 @@ module Labelable
|
||||
end
|
||||
|
||||
def add_labels(new_labels = nil)
|
||||
return if new_labels.blank?
|
||||
|
||||
new_labels = Array(new_labels) # Make sure new_labels is an array
|
||||
combined_labels = labels + new_labels
|
||||
update!(label_list: combined_labels)
|
||||
|
||||
@@ -297,8 +297,6 @@ class Conversation < ApplicationRecord
|
||||
previous_labels, current_labels = previous_changes[:label_list]
|
||||
return unless (previous_labels.is_a? Array) && (current_labels.is_a? Array)
|
||||
|
||||
dispatcher_dispatch(CONVERSATION_UPDATED, previous_changes)
|
||||
|
||||
create_label_added(user_name, current_labels - previous_labels)
|
||||
create_label_removed(user_name, previous_labels - current_labels)
|
||||
end
|
||||
|
||||
@@ -151,13 +151,36 @@ class AutomationRules::ConditionsFilterService < FilterService
|
||||
" #{table_name}.additional_attributes ->> '#{attribute_key}' #{filter_operator_value} #{query_operator} "
|
||||
when 'standard'
|
||||
if attribute_key == 'labels'
|
||||
" tags.id #{filter_operator_value} #{query_operator} "
|
||||
build_label_query_string(query_hash, current_index, query_operator)
|
||||
else
|
||||
" #{table_name}.#{attribute_key} #{filter_operator_value} #{query_operator} "
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def build_label_query_string(query_hash, current_index, query_operator)
|
||||
case query_hash['filter_operator']
|
||||
when 'equal_to'
|
||||
return " 1=0 #{query_operator} " if query_hash['values'].blank?
|
||||
|
||||
value_placeholder = "value_#{current_index}"
|
||||
@filter_values[value_placeholder] = query_hash['values'].first
|
||||
" tags.name = :#{value_placeholder} #{query_operator} "
|
||||
when 'not_equal_to'
|
||||
return " 1=0 #{query_operator} " if query_hash['values'].blank?
|
||||
|
||||
value_placeholder = "value_#{current_index}"
|
||||
@filter_values[value_placeholder] = query_hash['values'].first
|
||||
" tags.name != :#{value_placeholder} #{query_operator} "
|
||||
when 'is_present'
|
||||
" tags.id IS NOT NULL #{query_operator} "
|
||||
when 'is_not_present'
|
||||
" tags.id IS NULL #{query_operator} "
|
||||
else
|
||||
" tags.id #{filter_operation(query_hash, current_index)} #{query_operator} "
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def base_relation
|
||||
@@ -166,7 +189,21 @@ class AutomationRules::ConditionsFilterService < FilterService
|
||||
).joins(
|
||||
'LEFT OUTER JOIN messages on messages.conversation_id = conversations.id'
|
||||
)
|
||||
|
||||
# Only add label joins when label conditions exist
|
||||
if label_conditions?
|
||||
records = records.joins(
|
||||
'LEFT OUTER JOIN taggings ON taggings.taggable_id = conversations.id AND taggings.taggable_type = \'Conversation\''
|
||||
).joins(
|
||||
'LEFT OUTER JOIN tags ON taggings.tag_id = tags.id'
|
||||
)
|
||||
end
|
||||
|
||||
records = records.where(messages: { id: @options[:message].id }) if @options[:message].present?
|
||||
records
|
||||
end
|
||||
|
||||
def label_conditions?
|
||||
@rule.conditions.any? { |condition| condition['attribute_key'] == 'labels' }
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user