diff --git a/app/models/account.rb b/app/models/account.rb index fead5f0f7..4816494fb 100644 --- a/app/models/account.rb +++ b/app/models/account.rb @@ -40,6 +40,7 @@ class Account < ApplicationRecord 'auto_resolve_ignore_waiting': { 'type': %w[boolean null] }, 'audio_transcriptions': { 'type': %w[boolean null] }, 'auto_resolve_label': { 'type': %w[string null] }, + 'keep_pending_on_bot_failure': { 'type': %w[boolean null] }, 'conversation_required_attributes': { 'type': %w[array null], 'items': { 'type': 'string' } @@ -88,6 +89,7 @@ class Account < ApplicationRecord store_accessor :settings, :audio_transcriptions, :auto_resolve_label store_accessor :settings, :captain_models, :captain_features + store_accessor :settings, :keep_pending_on_bot_failure has_many :account_users, dependent: :destroy_async has_many :agent_bot_inboxes, dependent: :destroy_async diff --git a/lib/webhooks/trigger.rb b/lib/webhooks/trigger.rb index 54bd7499d..ef3410b78 100644 --- a/lib/webhooks/trigger.rb +++ b/lib/webhooks/trigger.rb @@ -36,16 +36,21 @@ class Webhooks::Trigger case @webhook_type when :agent_bot_webhook - conversation = message.conversation - return unless conversation&.pending? - - conversation.open! - create_agent_bot_error_activity(conversation) + update_conversation_status(message) when :api_inbox_webhook update_message_status(error) end end + def update_conversation_status(message) + conversation = message.conversation + return unless conversation&.pending? + return if conversation&.account&.keep_pending_on_bot_failure + + conversation.open! + create_agent_bot_error_activity(conversation) + end + def create_agent_bot_error_activity(conversation) content = I18n.t('conversations.activity.agent_bot.error_moved_to_open') Conversations::ActivityMessageJob.perform_later(conversation, activity_message_params(conversation, content)) diff --git a/spec/lib/webhooks/trigger_spec.rb b/spec/lib/webhooks/trigger_spec.rb index 78bf361c4..79cf92150 100644 --- a/spec/lib/webhooks/trigger_spec.rb +++ b/spec/lib/webhooks/trigger_spec.rb @@ -74,10 +74,11 @@ describe Webhooks::Trigger do context 'when webhook type is agent bot' do let(:webhook_type) { :agent_bot_webhook } + let!(:pending_conversation) { create(:conversation, inbox: inbox, status: :pending, account: account) } + let!(:pending_message) { create(:message, account: account, inbox: inbox, conversation: pending_conversation) } it 'reopens conversation and enqueues activity message if pending' do - conversation.update(status: :pending) - payload = { event: 'message_created', conversation: { id: conversation.id }, id: message.id } + payload = { event: 'message_created', id: pending_message.id } expect(RestClient::Request).to receive(:execute) .with( @@ -92,11 +93,11 @@ describe Webhooks::Trigger do perform_enqueued_jobs do trigger.execute(url, payload, webhook_type) end - end.not_to(change { message.reload.status }) + end.not_to(change { pending_message.reload.status }) - expect(conversation.reload.status).to eq('open') + expect(pending_conversation.reload.status).to eq('open') - activity_message = conversation.reload.messages.order(:created_at).last + activity_message = pending_conversation.reload.messages.order(:created_at).last expect(activity_message.message_type).to eq('activity') expect(activity_message.content).to eq(agent_bot_error_content) end @@ -118,9 +119,52 @@ describe Webhooks::Trigger do end.not_to(change { message.reload.status }) expect(Conversations::ActivityMessageJob).not_to have_been_enqueued - expect(conversation.reload.status).to eq('open') end + + it 'keeps conversation pending when keep_pending_on_bot_failure setting is enabled' do + account.update(keep_pending_on_bot_failure: true) + payload = { event: 'message_created', id: pending_message.id } + + expect(RestClient::Request).to receive(:execute) + .with( + method: :post, + url: url, + payload: payload.to_json, + headers: { content_type: :json, accept: :json }, + timeout: webhook_timeout + ).and_raise(RestClient::ExceptionWithResponse.new('error', 500)).once + + trigger.execute(url, payload, webhook_type) + + expect(Conversations::ActivityMessageJob).not_to have_been_enqueued + expect(pending_conversation.reload.status).to eq('pending') + end + + it 'reopens conversation when keep_pending_on_bot_failure setting is disabled' do + account.update(keep_pending_on_bot_failure: false) + payload = { event: 'message_created', id: pending_message.id } + + expect(RestClient::Request).to receive(:execute) + .with( + method: :post, + url: url, + payload: payload.to_json, + headers: { content_type: :json, accept: :json }, + timeout: webhook_timeout + ).and_raise(RestClient::ExceptionWithResponse.new('error', 500)).once + expect do + perform_enqueued_jobs do + trigger.execute(url, payload, webhook_type) + end + end.not_to(change { pending_message.reload.status }) + + expect(pending_conversation.reload.status).to eq('open') + + activity_message = pending_conversation.reload.messages.order(:created_at).last + expect(activity_message.message_type).to eq('activity') + expect(activity_message.content).to eq(agent_bot_error_content) + end end end