chore: Add activity message for conversation resolutions by Captain (#11492)
Currently, when Captain resolves a conversation, the same activity message used for auto-resolution is shown. This has caused confusion for users. With this change, a distinct activity message will be displayed specifically for resolutions performed by Captain, improving clarity. Fixes https://linear.app/chatwoot/issue/CW-4289/incorrect-activity-message-for-conversations-resolved-by-captain-auto#comment-d2991763 Co-authored-by: Pranav <pranav@chatwoot.com>
This commit is contained in:
@@ -80,6 +80,8 @@ module ActivityMessageHandler
|
|||||||
def automation_status_change_activity_content
|
def automation_status_change_activity_content
|
||||||
if Current.executed_by.instance_of?(AutomationRule)
|
if Current.executed_by.instance_of?(AutomationRule)
|
||||||
I18n.t("conversations.activity.status.#{status}", user_name: I18n.t('automation.system_name'))
|
I18n.t("conversations.activity.status.#{status}", user_name: I18n.t('automation.system_name'))
|
||||||
|
elsif Current.executed_by.instance_of?(Captain::Assistant) && resolved?
|
||||||
|
I18n.t('conversations.activity.captain.resolved', user_name: Current.executed_by.name)
|
||||||
elsif Current.executed_by.instance_of?(Contact)
|
elsif Current.executed_by.instance_of?(Contact)
|
||||||
Current.executed_by = nil
|
Current.executed_by = nil
|
||||||
I18n.t('conversations.activity.status.system_auto_open')
|
I18n.t('conversations.activity.status.system_auto_open')
|
||||||
|
|||||||
@@ -153,6 +153,8 @@ en:
|
|||||||
delivery_status:
|
delivery_status:
|
||||||
error_code: 'Error code: %{error_code}'
|
error_code: 'Error code: %{error_code}'
|
||||||
activity:
|
activity:
|
||||||
|
captain:
|
||||||
|
resolved: 'Conversation was marked resolved by %{user_name} due to inactivity'
|
||||||
status:
|
status:
|
||||||
resolved: 'Conversation was marked resolved by %{user_name}'
|
resolved: 'Conversation was marked resolved by %{user_name}'
|
||||||
contact_resolved: 'Conversation was resolved by %{contact_name}'
|
contact_resolved: 'Conversation was resolved by %{contact_name}'
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ class Captain::InboxPendingConversationsResolutionJob < ApplicationJob
|
|||||||
|
|
||||||
def perform(inbox)
|
def perform(inbox)
|
||||||
# limiting the number of conversations to be resolved to avoid any performance issues
|
# limiting the number of conversations to be resolved to avoid any performance issues
|
||||||
|
Current.executed_by = inbox.captain_assistant
|
||||||
resolvable_conversations = inbox.conversations.pending.where('last_activity_at < ? ', Time.now.utc - 1.hour).limit(Limits::BULK_ACTIONS_LIMIT)
|
resolvable_conversations = inbox.conversations.pending.where('last_activity_at < ? ', Time.now.utc - 1.hour).limit(Limits::BULK_ACTIONS_LIMIT)
|
||||||
resolvable_conversations.each do |conversation|
|
resolvable_conversations.each do |conversation|
|
||||||
resolution_message = conversation.inbox.captain_assistant.config['resolution_message']
|
resolution_message = conversation.inbox.captain_assistant.config['resolution_message']
|
||||||
@@ -15,6 +16,8 @@ class Captain::InboxPendingConversationsResolutionJob < ApplicationJob
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
conversation.resolved!
|
conversation.resolved!
|
||||||
|
ensure
|
||||||
|
Current.reset
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -9,8 +9,10 @@ RSpec.describe Captain::InboxPendingConversationsResolutionJob, type: :job do
|
|||||||
let!(:recent_pending_conversation) { create(:conversation, inbox: inbox, last_activity_at: 10.minutes.ago, status: :pending) }
|
let!(:recent_pending_conversation) { create(:conversation, inbox: inbox, last_activity_at: 10.minutes.ago, status: :pending) }
|
||||||
let!(:open_conversation) { create(:conversation, inbox: inbox, last_activity_at: 1.hour.ago, status: :open) }
|
let!(:open_conversation) { create(:conversation, inbox: inbox, last_activity_at: 1.hour.ago, status: :open) }
|
||||||
|
|
||||||
|
let!(:captain_assistant) { create(:captain_assistant, account: inbox.account) }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
create(:captain_inbox, inbox: inbox, captain_assistant: create(:captain_assistant, account: inbox.account))
|
create(:captain_inbox, inbox: inbox, captain_assistant: captain_assistant)
|
||||||
stub_const('Limits::BULK_ACTIONS_LIMIT', 2)
|
stub_const('Limits::BULK_ACTIONS_LIMIT', 2)
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -27,14 +29,34 @@ RSpec.describe Captain::InboxPendingConversationsResolutionJob, type: :job do
|
|||||||
expect(open_conversation.reload.status).to eq('open')
|
expect(open_conversation.reload.status).to eq('open')
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'creates an outgoing message for each resolved conversation' do
|
it 'creates exactly one outgoing message with configured content' do
|
||||||
# resolution message + system message
|
custom_message = 'This is a custom resolution message.'
|
||||||
expect { perform_enqueued_jobs { described_class.perform_later(inbox) } }
|
captain_assistant.update!(config: { 'resolution_message' => custom_message })
|
||||||
.to change { resolvable_pending_conversation.messages.reload.count }.by(2)
|
|
||||||
|
|
||||||
resolved_conversation_messages = resolvable_pending_conversation.messages.map(&:content)
|
expect do
|
||||||
expect(resolved_conversation_messages).to include(
|
perform_enqueued_jobs { described_class.perform_later(inbox) }
|
||||||
'Resolving the conversation as it has been inactive for a while. Please start a new conversation if you need further assistance.'
|
end.to change { resolvable_pending_conversation.messages.outgoing.reload.count }.by(1)
|
||||||
|
|
||||||
|
outgoing_message = resolvable_pending_conversation.messages.outgoing.last
|
||||||
|
expect(outgoing_message.content).to eq(custom_message)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'creates an outgoing message with default auto resolution message if not configured' do
|
||||||
|
captain_assistant.update!(config: {})
|
||||||
|
|
||||||
|
perform_enqueued_jobs { described_class.perform_later(inbox) }
|
||||||
|
outgoing_message = resolvable_pending_conversation.messages.outgoing.last
|
||||||
|
expect(outgoing_message.content).to eq(
|
||||||
|
I18n.t('conversations.activity.auto_resolution_message')
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'adds the correct activity message after resolution by Captain' do
|
||||||
|
perform_enqueued_jobs { described_class.perform_later(inbox) }
|
||||||
|
activity_message = resolvable_pending_conversation.messages.activity.last
|
||||||
|
expect(activity_message).not_to be_nil
|
||||||
|
expect(activity_message.content).to eq(
|
||||||
|
I18n.t('conversations.activity.captain.resolved', user_name: captain_assistant.name)
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user