Skip to content

Live chat transfer and chat.transferred - #109

Merged
mpge merged 1 commit into
mainfrom
feat/chat-transfer
Oct 23, 2026
Merged

mpge merged 1 commit into
mainfrom
feat/chat-transfer

Conversation

@mpge

@mpge mpge commented Oct 23, 2026

Copy link
Copy Markdown
Member

Ports escalated-laravel's live chat transfer (ChatController::transfer, ChatSessionService::transferChat), so the plugin can emit chat.transferred (ADR 2026-10-21 event vocabulary), as escalated-go #167 and escalated-phoenix #176 did.

What

  • POST /wp-json/escalated/v1/chat/{session_id}/transfer, with an API token like the other agent chat endpoints (WordPress has no route names; this is the plugin's equivalent of escalated.admin.chat.transfer). Body {agent_id, department_id} (either or both); the shared ChatActionBar body {type, id} is accepted too.
  • Agent given: session and ticket reassigned to that agent. Department only: ticket and session move there, chat goes back to the queue (unassigned, waiting) and chat routing runs again for the new department. Same semantics as Laravel. The ticket is updated directly, as Laravel does, so no separate ticket.assigned/ticket.department_changed fires for the transfer itself (a re-route then accepts through the normal path).
  • 422 for no target, a non-integer or unknown department, an ended chat, or an agent who is not staff or cannot see the ticket in its new department (TicketAccess::allows); 404 unknown session. Response {"message": "Chat transferred.", "session": {...}}.
  • New escalated_chat_transferred action ($session, $from_agent_id, $to_agent_id, $to_department_id). chat.transferred is a workflow trigger ("Chat transferred") and a webhook event offered in the webhook form. Payload: the ticket plus chat {session_id, ticket_id, status, agent_id, department_id, from_agent_id, to_agent_id, to_department_id}, matching Laravel's DispatchWebhook::chatPayload; no visitor email or token.

Note: the plugin's webhooks still do not send the other chat events (chat.started/assigned/message/ended); only workflows get those. Left as is here.

Tests

tests/Test_Chat_Transfer.php through the real REST server and boot hooks: agent transfer (webhook payload + workflow log), department transfer with re-routing, department transfer with no agent (waiting), both, ChatActionBar body, refusals (no token, no target, blank target, unknown/non-integer department, unknown agent, unknown session, ended chat) with no event sent, an agent outside the department under department visibility. All red before (404). Test_Workflow_Wiring now fires chat.transferred too. Full suite in the WP test lib on MySQL 8: 913 tests, 1 failure, the existing Test_Ticket_Access_Migration "separate database" case that needs a second database grant the local harness lacks (fails on main too). Pint clean.

Ports escalated-laravel ChatController::transfer and
ChatSessionService::transferChat as POST chat/{session}/transfer, and
sends chat.transferred to webhooks and workflows.
@mpge
mpge merged commit 48c24b9 into main Oct 23, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant