diff --git a/app/models/account.rb b/app/models/account.rb
index dad5bc18d..df79ee6c1 100644
--- a/app/models/account.rb
+++ b/app/models/account.rb
@@ -85,7 +85,7 @@ class Account < ApplicationRecord
store_accessor :settings, :auto_resolve_after, :auto_resolve_message, :auto_resolve_ignore_waiting
- store_accessor :settings, :audio_transcriptions, :auto_resolve_label, :conversation_required_attributes
+ store_accessor :settings, :audio_transcriptions, :auto_resolve_label
store_accessor :settings, :captain_models, :captain_features
has_many :account_users, dependent: :destroy_async
diff --git a/app/models/conversation.rb b/app/models/conversation.rb
index ac0985416..ca53238e8 100644
--- a/app/models/conversation.rb
+++ b/app/models/conversation.rb
@@ -167,6 +167,10 @@ class Conversation < ApplicationRecord
agent_last_seen_at.present? ? messages.created_since(agent_last_seen_at) : messages
end
+ def assignee_unread_messages
+ assignee_last_seen_at.present? ? messages.created_since(assignee_last_seen_at) : messages
+ end
+
def unread_incoming_messages
unread_messages.where(account_id: account_id).incoming.last(10)
end
diff --git a/app/models/custom_attribute_definition.rb b/app/models/custom_attribute_definition.rb
index 4154da3b8..70956c108 100644
--- a/app/models/custom_attribute_definition.rb
+++ b/app/models/custom_attribute_definition.rb
@@ -45,7 +45,6 @@ class CustomAttributeDefinition < ApplicationRecord
belongs_to :account
after_update :update_widget_pre_chat_custom_fields
after_destroy :sync_widget_pre_chat_custom_fields
- after_destroy :cleanup_conversation_required_attributes
private
@@ -57,13 +56,6 @@ class CustomAttributeDefinition < ApplicationRecord
::Inboxes::UpdateWidgetPreChatCustomFieldsJob.perform_later(account, self)
end
- def cleanup_conversation_required_attributes
- return unless conversation_attribute? && account.conversation_required_attributes&.include?(attribute_key)
-
- account.conversation_required_attributes = account.conversation_required_attributes - [attribute_key]
- account.save!
- end
-
def attribute_must_not_conflict
model_keys = attribute_model.to_sym == :conversation_attribute ? :conversation : :contact
return unless attribute_key.in?(STANDARD_ATTRIBUTES[model_keys])
@@ -71,3 +63,5 @@ class CustomAttributeDefinition < ApplicationRecord
errors.add(:attribute_key, I18n.t('errors.custom_attribute_definition.key_conflict'))
end
end
+
+CustomAttributeDefinition.include_mod_with('Concerns::CustomAttributeDefinition')
diff --git a/app/presenters/messages/search_data_presenter.rb b/app/presenters/messages/search_data_presenter.rb
index 7d0638add..7a6260686 100644
--- a/app/presenters/messages/search_data_presenter.rb
+++ b/app/presenters/messages/search_data_presenter.rb
@@ -51,7 +51,6 @@ class Messages::SearchDataPresenter < SimpleDelegator
def additional_attributes_data
{
- campaign_id: additional_attributes&.dig('campaign_id'),
automation_rule_id: content_attributes&.dig('automation_rule_id')
}
end
diff --git a/app/services/messages/markdown_renderers/whats_app_renderer.rb b/app/services/messages/markdown_renderers/whats_app_renderer.rb
index 8f98218cf..3b4517b4b 100644
--- a/app/services/messages/markdown_renderers/whats_app_renderer.rb
+++ b/app/services/messages/markdown_renderers/whats_app_renderer.rb
@@ -1,4 +1,9 @@
class Messages::MarkdownRenderers::WhatsAppRenderer < Messages::MarkdownRenderers::BaseMarkdownRenderer
+ def initialize
+ super
+ @list_item_number = 0
+ end
+
def strong(_node)
out('*', :children, '*')
end
@@ -15,13 +20,20 @@ class Messages::MarkdownRenderers::WhatsAppRenderer < Messages::MarkdownRenderer
out(node.url)
end
- def list(_node)
+ def list(node)
+ @list_type = node.list_type
+ @list_item_number = @list_type == :ordered_list ? node.list_start : 0
out(:children)
cr
end
def list_item(_node)
- out('- ', :children)
+ if @list_type == :ordered_list
+ out("#{@list_item_number}. ", :children)
+ @list_item_number += 1
+ else
+ out('- ', :children)
+ end
cr
end
diff --git a/app/views/public/api/v1/portals/sitemap.xml.erb b/app/views/public/api/v1/portals/sitemap.xml.erb
index d3e2b8301..1ea828165 100644
--- a/app/views/public/api/v1/portals/sitemap.xml.erb
+++ b/app/views/public/api/v1/portals/sitemap.xml.erb
@@ -1,9 +1,9 @@
-
+
<% @portal.articles.where(status: :published).each do |article| %>
-
+ <%= @help_center_url %><%= generate_article_link(@portal.slug, article.slug, false, false) %>
- <%= article.updated_at.strftime("%Y-%m-%d") %>
-
+ <%= article.updated_at.to_date.iso8601 %>
+
<% end %>
-
\ No newline at end of file
+
diff --git a/config/features.yml b/config/features.yml
index 703d3cb8c..e03690d74 100644
--- a/config/features.yml
+++ b/config/features.yml
@@ -237,3 +237,7 @@
- name: captain_tasks
display_name: Captain Tasks
enabled: true
+- name: conversation_required_attributes
+ display_name: Required Conversation Attributes
+ enabled: false
+ premium: true
diff --git a/enterprise/app/controllers/enterprise/api/v1/accounts_settings.rb b/enterprise/app/controllers/enterprise/api/v1/accounts_settings.rb
new file mode 100644
index 000000000..bdcbfc1d3
--- /dev/null
+++ b/enterprise/app/controllers/enterprise/api/v1/accounts_settings.rb
@@ -0,0 +1,7 @@
+module Enterprise::Api::V1::AccountsSettings
+ private
+
+ def permitted_settings_attributes
+ super + [{ conversation_required_attributes: [] }]
+ end
+end
diff --git a/enterprise/app/models/enterprise/concerns/account.rb b/enterprise/app/models/enterprise/concerns/account.rb
index cae32e86c..01693ac79 100644
--- a/enterprise/app/models/enterprise/concerns/account.rb
+++ b/enterprise/app/models/enterprise/concerns/account.rb
@@ -2,6 +2,8 @@ module Enterprise::Concerns::Account
extend ActiveSupport::Concern
included do
+ store_accessor :settings, :conversation_required_attributes
+
has_many :sla_policies, dependent: :destroy_async
has_many :applied_slas, dependent: :destroy_async
has_many :custom_roles, dependent: :destroy_async
diff --git a/enterprise/app/models/enterprise/concerns/custom_attribute_definition.rb b/enterprise/app/models/enterprise/concerns/custom_attribute_definition.rb
new file mode 100644
index 000000000..ad359f8a0
--- /dev/null
+++ b/enterprise/app/models/enterprise/concerns/custom_attribute_definition.rb
@@ -0,0 +1,16 @@
+module Enterprise::Concerns::CustomAttributeDefinition
+ extend ActiveSupport::Concern
+
+ included do
+ after_destroy :cleanup_conversation_required_attributes
+ end
+
+ private
+
+ def cleanup_conversation_required_attributes
+ return unless conversation_attribute? && account.conversation_required_attributes&.include?(attribute_key)
+
+ account.conversation_required_attributes = account.conversation_required_attributes - [attribute_key]
+ account.save!
+ end
+end
diff --git a/enterprise/app/services/enterprise/billing/handle_stripe_event_service.rb b/enterprise/app/services/enterprise/billing/handle_stripe_event_service.rb
index 10887a1d7..a5f03cddf 100644
--- a/enterprise/app/services/enterprise/billing/handle_stripe_event_service.rb
+++ b/enterprise/app/services/enterprise/billing/handle_stripe_event_service.rb
@@ -22,7 +22,7 @@ class Enterprise::Billing::HandleStripeEventService
].freeze
# Additional features available starting with the Business plan
- BUSINESS_PLAN_FEATURES = %w[sla custom_roles csat_review_notes].freeze
+ BUSINESS_PLAN_FEATURES = %w[sla custom_roles csat_review_notes conversation_required_attributes].freeze
# Additional features available only in the Enterprise plan
ENTERPRISE_PLAN_FEATURES = %w[audit_logs disable_branding saml].freeze
diff --git a/enterprise/config/premium_features.yml b/enterprise/config/premium_features.yml
index 9465a6e11..64275503d 100644
--- a/enterprise/config/premium_features.yml
+++ b/enterprise/config/premium_features.yml
@@ -6,3 +6,4 @@
- custom_roles
- captain_integration
- csat_review_notes
+- conversation_required_attributes
diff --git a/lib/integrations/openai/openai_prompts/fix_spelling_grammar.liquid b/lib/integrations/openai/openai_prompts/fix_spelling_grammar.liquid
index 520487357..2a0e8c6d2 100644
--- a/lib/integrations/openai/openai_prompts/fix_spelling_grammar.liquid
+++ b/lib/integrations/openai/openai_prompts/fix_spelling_grammar.liquid
@@ -10,8 +10,9 @@ Important guidelines:
- Ensure the output remains appropriate for customer support
Super Important:
-- If the message has some markdown formatting, keep the formatting as it is.
+- If the message has some markdown formatting, keep the formatting as it is.
- Block quotes (lines starting with >) contain quoted text from the customer's previous message. Preserve this quoted text exactly as written (do not modify the customer's words inside the block quote), but DO improve the agent's reply that follows the block quote.
- Ensure the output is in the user's original language
+- If the message contains a signature block (text after a `--` line), preserve the signature exactly as written without any modification. Do not add a signature if one is not already present.
Output only the corrected message, with no preamble, tags, or explanation.
diff --git a/lib/integrations/openai/openai_prompts/improve.liquid b/lib/integrations/openai/openai_prompts/improve.liquid
index 7e3d35e82..8730d1b0f 100644
--- a/lib/integrations/openai/openai_prompts/improve.liquid
+++ b/lib/integrations/openai/openai_prompts/improve.liquid
@@ -38,6 +38,7 @@ Do NOT use the context to fill in gaps or add information the agent didn't inclu
- Keep the improved message at a similar length to the draft (brief stays brief)
- Preserve any markdown formatting
- Block quotes (lines starting with `>`) contain quoted customer text—keep this unchanged, only improve the agent's reply
+- If the message contains a signature block (text after a `--` line), preserve the signature exactly as written without any modification. Do not add a signature if one is not already present.
- Output in the same language as the draft
- Output only the improved message, no commentary
diff --git a/lib/integrations/openai/openai_prompts/tone_rewrite.liquid b/lib/integrations/openai/openai_prompts/tone_rewrite.liquid
index c140a93df..6b62617f0 100644
--- a/lib/integrations/openai/openai_prompts/tone_rewrite.liquid
+++ b/lib/integrations/openai/openai_prompts/tone_rewrite.liquid
@@ -28,8 +28,9 @@ Important guidelines:
- Do not remove critical details or instructions
Super Important:
-- If the message has some markdown formatting, keep the formatting as it is.
+- If the message has some markdown formatting, keep the formatting as it is.
- Block quotes (lines starting with >) contain quoted text from the customer's previous message. Preserve this quoted text exactly as written (do not modify the customer's words inside the block quote), but DO improve the agent's reply that follows the block quote.
- Ensure the output is in the user's original language
+- If the message contains a signature block (text after a `--` line), preserve the signature exactly as written without any modification. Do not add a signature if one is not already present.
Output only the rewritten message without any preamble, tags or explanation.
diff --git a/public/brand-assets/logo.svg b/public/brand-assets/logo.svg
index 438f2b4b0..63adcde76 100644
--- a/public/brand-assets/logo.svg
+++ b/public/brand-assets/logo.svg
@@ -1,15 +1,5 @@
-
-
\ No newline at end of file
+
diff --git a/public/brand-assets/logo_dark.svg b/public/brand-assets/logo_dark.svg
index a0f7ac881..679ae4687 100644
--- a/public/brand-assets/logo_dark.svg
+++ b/public/brand-assets/logo_dark.svg
@@ -1,13 +1,5 @@
-
-