package automation import "fmt" // WhitelistedConditionAttributes defines the set of valid condition attributes. // Reference: Chatwoot ConditionValidationService — validates condition keys against whitelisted attributes. var WhitelistedConditionAttributes = map[string]bool{ // Conversation attributes "status": true, "priority": true, "assignee_id": true, "team_id": true, "inbox_id": true, "contact_id": true, "channel_type": true, "labels": true, // Message/content attributes "content": true, "message_type": true, "email": true, // Country/locale attributes (Chatwoot extensions) "country_code": true, "browser_language": true, } // WhitelistedFilterOperators defines the set of valid filter operators. // Reference: Chatwoot filter_operator enum var WhitelistedFilterOperators = map[string]bool{ "equal": true, "not_equal": true, "contains": true, "does_not_contain": true, "is_present": true, "is_not_present": true, "attribute_changed": true, } // WhitelistedQueryOperators defines the set of valid query operators for combining conditions. var WhitelistedQueryOperators = map[string]bool{ "and": true, "or": true, } // WhitelistedActionTypes defines the set of valid automation action types. // Reference: Chatwoot AutomationRule action_name enum var WhitelistedActionTypes = map[string]bool{ "assign_agent": true, "assign_team": true, // Chatwoot: assign conversation to a team "change_status": true, "add_label": true, "remove_label": true, "send_message": true, "send_email_to_contact": true, "mute_conversation": true, "snooze_conversation": true, // Chatwoot: snooze until a specified time "resolve_conversation": true, // Chatwoot: resolve immediately } // ValidateConditions checks that all conditions use valid attributes, filter operators, // and query operators. // Reference: Chatwoot ConditionValidationService — validates condition keys against whitelisted attributes func ValidateConditions(conditions Conditions) error { for i, c := range conditions { // Validate attribute if !WhitelistedConditionAttributes[c.Attribute] { return fmt.Errorf("condition[%d]: invalid attribute '%s'", i, c.Attribute) } // Validate filter operator if !WhitelistedFilterOperators[c.FilterOperator] { return fmt.Errorf("condition[%d]: invalid filter_operator '%s'", i, c.FilterOperator) } // Validate query operator (defaults to "and" if empty) if c.QueryOperator != "" { if !WhitelistedQueryOperators[c.QueryOperator] { return fmt.Errorf("condition[%d]: invalid query_operator '%s'", i, c.QueryOperator) } } // Validate values — attribute_changed requires from/to values if c.FilterOperator == "attribute_changed" { if len(c.Values) == 0 { return fmt.Errorf("condition[%d]: attribute_changed requires at least one value (to)", i) } } // is_present / is_not_present should not need values if c.FilterOperator == "is_present" || c.FilterOperator == "is_not_present" { // Values are optional for presence checks — not enforced } else if len(c.Values) == 0 { return fmt.Errorf("condition[%d]: filter_operator '%s' requires at least one value", i, c.FilterOperator) } } return nil } // ValidateActions checks that all actions use valid action types. // Reference: Chatwoot AutomationRule action_name validation func ValidateActions(actions Actions) error { for i, a := range actions { if !WhitelistedActionTypes[a.ActionName] { return fmt.Errorf("action[%d]: invalid action_name '%s'", i, a.ActionName) } } return nil }