Files
moreminimore-chat/app/services/conversations/assignment_service.rb
Sojan Jose 35a5f3390c feat: update status on agent bot assignment (#14870)
Assigning a conversation to an Agent Bot now moves it to pending.
Assigning a bot-owned pending conversation to a human opens it again,
while other assignment changes preserve the existing status. This makes
existing Agent Bot ownership behave like an AI handoff without depending
on the assignment dropdown UI work.

Closes:
https://linear.app/chatwoot/issue/CW-7448/apply-agent-bot-assignment-behavior

## Why
Agent Bot ownership should remove conversations from the main open queue
while the bot is handling them. Explicit human takeover should bring a
bot-owned pending conversation back to the open queue and clear the bot
owner.

## What changed
- Agent Bot assignment clears the human assignee and marks the
conversation pending.
- Human assignment clears the Agent Bot owner and opens the conversation
only when it was bot-owned and pending.
- Ordinary human assignment, non-pending bot takeover, and unassignment
preserve the existing conversation status.
- Manual human takeover uses the existing assignment and status events.
Bot-initiated handoffs continue to use the existing bot-handoff event
path.

## Validation
- Assign an open conversation to an Agent Bot through the assignment API
and verify it becomes pending.
- Assign that bot-owned pending conversation to a human and verify it
becomes open.
- Verify ordinary human assignment, non-pending bot takeover, and
unassignment do not force a status change.
2026-08-07 12:08:58 -07:00

53 lines
1.3 KiB
Ruby

class Conversations::AssignmentService
def initialize(conversation:, assignee_id:, assignee_type: nil)
@conversation = conversation
@assignee_id = assignee_id
@assignee_type = assignee_type
end
def perform
agent_bot_assignment? ? assign_agent_bot : assign_agent
end
private
attr_reader :conversation, :assignee_id, :assignee_type
def assign_agent
conversation.with_lock do
if assignee.present? && conversation.assignee_agent_bot_id.present? && conversation.pending?
conversation.status = :open
conversation.waiting_since = Time.current if conversation.waiting_since.blank?
end
conversation.assignee = assignee
conversation.assignee_agent_bot = nil
conversation.save!
end
assignee
end
def assign_agent_bot
return unless agent_bot
conversation.with_lock do
conversation.assignee = nil
conversation.assignee_agent_bot = agent_bot
conversation.status = :pending
conversation.save!
end
agent_bot
end
def assignee
@assignee ||= conversation.account.users.find_by(id: assignee_id)
end
def agent_bot
@agent_bot ||= AgentBot.accessible_to(conversation.account).find_by(id: assignee_id)
end
def agent_bot_assignment?
assignee_type.to_s == 'AgentBot'
end
end