feat: trigger handoff when agent bot is the actor (#8639)
- This PR adds a feature to auto-trigger handoff events when an Agent bot toggles a conversation status from Pending to Open Co-authored-by: Sojan <sojan@pepalo.com>
This commit is contained in:
@@ -60,13 +60,26 @@ class Api::V1::Accounts::ConversationsController < Api::V1::Accounts::BaseContro
|
||||
end
|
||||
|
||||
def toggle_status
|
||||
if params[:status].present?
|
||||
# FIXME: move this logic into a service object
|
||||
if pending_to_open_by_bot?
|
||||
@conversation.bot_handoff!
|
||||
elsif params[:status].present?
|
||||
set_conversation_status
|
||||
@status = @conversation.save!
|
||||
else
|
||||
@status = @conversation.toggle_status
|
||||
end
|
||||
assign_conversation if @conversation.status == 'open' && Current.user.is_a?(User) && Current.user&.agent?
|
||||
assign_conversation if should_assign_conversation?
|
||||
end
|
||||
|
||||
def pending_to_open_by_bot?
|
||||
return false unless Current.user.is_a?(AgentBot)
|
||||
|
||||
@conversation.status == 'pending' && params[:status] == 'open'
|
||||
end
|
||||
|
||||
def should_assign_conversation?
|
||||
@conversation.status == 'open' && Current.user.is_a?(User) && Current.user&.agent?
|
||||
end
|
||||
|
||||
def toggle_priority
|
||||
|
||||
@@ -14,7 +14,7 @@ module AccessTokenAuthHelper
|
||||
render_unauthorized('Invalid Access Token') && return if @access_token.blank?
|
||||
|
||||
@resource = @access_token.owner
|
||||
Current.user = @resource if current_user.is_a?(User)
|
||||
Current.user = @resource if [User, AgentBot].include?(@resource.class)
|
||||
end
|
||||
|
||||
def validate_bot_access_token!
|
||||
|
||||
@@ -21,7 +21,7 @@ class InboxPolicy < ApplicationPolicy
|
||||
|
||||
def show?
|
||||
# FIXME: for agent bots, lets bring this validation to policies as well in future
|
||||
return true if @user.blank?
|
||||
return true if @user.is_a?(AgentBot)
|
||||
|
||||
Current.user.assigned_inboxes.include? record
|
||||
end
|
||||
|
||||
@@ -323,6 +323,9 @@ RSpec.describe 'Conversations API', type: :request do
|
||||
|
||||
describe 'POST /api/v1/accounts/{account.id}/conversations/:id/toggle_status' do
|
||||
let(:conversation) { create(:conversation, account: account) }
|
||||
let(:inbox) { create(:inbox, account: account) }
|
||||
let(:pending_conversation) { create(:conversation, inbox: inbox, account: account, status: 'pending') }
|
||||
let(:agent_bot) { create(:agent_bot, account: account) }
|
||||
|
||||
context 'when it is an unauthenticated user' do
|
||||
it 'returns unauthorized' do
|
||||
@@ -424,6 +427,42 @@ RSpec.describe 'Conversations API', type: :request do
|
||||
# expect(conversation.reload.status).to eq('pending')
|
||||
# end
|
||||
end
|
||||
|
||||
context 'when it is an authenticated bot' do
|
||||
# this test will basically ensure that the status actually changes
|
||||
# regardless of the value to be done
|
||||
it 'returns authorized for arbritrary status' do
|
||||
create(:agent_bot_inbox, inbox: inbox, agent_bot: agent_bot)
|
||||
|
||||
conversation.update!(status: 'open')
|
||||
expect(conversation.reload.status).to eq('open')
|
||||
snoozed_until = (DateTime.now.utc + 2.days).to_i
|
||||
|
||||
post "/api/v1/accounts/#{account.id}/conversations/#{conversation.display_id}/toggle_status",
|
||||
headers: { api_access_token: agent_bot.access_token.token },
|
||||
params: { status: 'snoozed', snoozed_until: snoozed_until },
|
||||
as: :json
|
||||
|
||||
expect(response).to have_http_status(:success)
|
||||
expect(conversation.reload.status).to eq('snoozed')
|
||||
end
|
||||
|
||||
it 'triggers handoff event when moving from pending to open' do
|
||||
create(:agent_bot_inbox, inbox: inbox, agent_bot: agent_bot)
|
||||
allow(Rails.configuration.dispatcher).to receive(:dispatch)
|
||||
|
||||
post "/api/v1/accounts/#{account.id}/conversations/#{pending_conversation.display_id}/toggle_status",
|
||||
headers: { api_access_token: agent_bot.access_token.token },
|
||||
params: { status: 'open' },
|
||||
as: :json
|
||||
|
||||
expect(response).to have_http_status(:success)
|
||||
expect(pending_conversation.reload.status).to eq('open')
|
||||
expect(Rails.configuration.dispatcher).to have_received(:dispatch)
|
||||
.with(Events::Types::CONVERSATION_BOT_HANDOFF, kind_of(Time), conversation: pending_conversation, notifiable_assignee_change: false,
|
||||
changed_attributes: anything, performed_by: anything)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'POST /api/v1/accounts/{account.id}/conversations/:id/toggle_priority' do
|
||||
|
||||
Reference in New Issue
Block a user