diff --git a/app/models/concerns/activity_message_handler.rb b/app/models/concerns/activity_message_handler.rb index 7fc020e3c..067bccbc1 100644 --- a/app/models/concerns/activity_message_handler.rb +++ b/app/models/concerns/activity_message_handler.rb @@ -32,7 +32,13 @@ module ActivityMessageHandler end def send_automation_activity - content = I18n.t("conversations.activity.status.#{status}", user_name: 'Automation System') + content = if Current.executed_by.instance_of?(AutomationRule) + I18n.t("conversations.activity.status.#{status}", user_name: 'Automation System') + elsif Current.executed_by.instance_of?(Contact) + Current.executed_by = nil + I18n.t('conversations.activity.status.system_auto_open') + end + ::Conversations::ActivityMessageJob.perform_later(self, activity_message_params(content)) if content end diff --git a/app/models/message.rb b/app/models/message.rb index b906f15b3..156b70240 100644 --- a/app/models/message.rb +++ b/app/models/message.rb @@ -257,11 +257,18 @@ class Message < ApplicationRecord # mark resolved bot conversation as pending to be reopened by bot processor service if conversation.inbox.active_bot? conversation.pending! + elsif conversation.inbox.api? + Current.executed_by = sender if reopened_by_contact? + conversation.open! else conversation.open! end end + def reopened_by_contact? + incoming? && !private? && Current.user.class != sender.class && sender.instance_of?(Contact) + end + def execute_message_template_hooks ::MessageTemplates::HookExecutionService.new(message: self).perform end diff --git a/config/locales/en.yml b/config/locales/en.yml index 2ce29994f..9cc48be18 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -129,6 +129,7 @@ en: pending: "Conversation was marked as pending by %{user_name}" snoozed: "Conversation was snoozed by %{user_name}" auto_resolved: "Conversation was marked resolved by system due to %{duration} days of inactivity" + system_auto_open: System reopened the conversation due to a new incoming message. assignee: self_assigned: "%{user_name} self-assigned this conversation" assigned: "Assigned to %{assignee_name} by %{user_name}" diff --git a/spec/controllers/api/v1/accounts/conversations/messages_controller_spec.rb b/spec/controllers/api/v1/accounts/conversations/messages_controller_spec.rb index e518ab185..d0072af8a 100644 --- a/spec/controllers/api/v1/accounts/conversations/messages_controller_spec.rb +++ b/spec/controllers/api/v1/accounts/conversations/messages_controller_spec.rb @@ -80,6 +80,32 @@ RSpec.describe 'Conversation Messages API', type: :request do expect(conversation.messages.last.attachments.first.file.present?).to be(true) expect(conversation.messages.last.attachments.first.file_type).to eq('image') end + + context 'when api inbox' do + let(:api_channel) { create(:channel_api, account: account) } + let(:api_inbox) { create(:inbox, channel: api_channel, account: account) } + let(:inbox_member) { create(:inbox_member, user: agent, inbox: api_inbox) } + let(:conversation) { create(:conversation, inbox: api_inbox, account: account) } + + it 'reopens the conversation with new incoming message' do + create(:message, conversation: conversation, account: account) + conversation.resolved! + + params = { content: 'test-message', private: false, message_type: 'incoming' } + + post api_v1_account_conversation_messages_url(account_id: account.id, conversation_id: conversation.display_id), + params: params, + headers: agent.create_new_auth_token, + as: :json + + expect(response).to have_http_status(:success) + expect(conversation.reload.status).to eq('open') + expect(Conversations::ActivityMessageJob) + .to(have_been_enqueued.at_least(:once) + .with(conversation, { account_id: conversation.account_id, inbox_id: conversation.inbox_id, message_type: :activity, + content: 'System reopened the conversation due to a new incoming message.' })) + end + end end context 'when it is an authenticated agent bot' do