Handoff a asesor humano en Agentforce Voice — enrutamiento end-to-end desde el bot hasta la cola
El Reto
Cuando el bot de Voz llega a su límite, la llamada debe transferirse a un humano sin cortar, sin perder contexto y con enrutamiento por skills.
En resumen
- En Agentforce Voice el handoff no es un solo botón: es un contrato entre el .agent (End Action tipo Escalate), un OmniChannelFlow (Route Work) y la operación humana (Service Presence + Queue + Skills).
- Existen dos rutas fundamentalmente distintas — no son alternativas del mismo punto: (a) Handoff interno — OmniChannelFlow con Route Work enruta a agent/queue/flow ID dentro de Salesforce. (b) Transferencia externa — el .agent invoca una GenAiFunction → Apex → Toolkit API que setea un contact attribute en Amazon Connect y dispara un Quick Connect cuyo Contact Flow ejecuta el bloque 'Transfer to phone number'.
- El OmniChannelFlow no acepta números telefónicos como target (verificado en voice_rest_route_call.htm). El Agent Script DSL v2 no expone un End Action 'TransferToNumber'. La transferencia externa vive en el motor del proveedor de telefonía, no en Salesforce.
- El path recomendado por default es OmniChannelFlow — mantiene contexto, skill matching, reporting nativo y warm transfer. Transfer to Number se reserva para overflow legacy, partners externos sin acceso a Salesforce, callbacks específicos o números de emergencia — el contexto no viaja y la VoiceCall se cierra al transferir.
- La receta cubre paso a paso ambas rutas — 9 pasos para OmniChannelFlow (Service Presence → Configuration → Queue → Skills → OmniChannelFlow → End Action → prueba → métricas) y 8 pasos para Transfer to Number (verificar service quota AWS → Contact Flow → Quick Connect → habilitación en Queue → Apex invocable → GenAiFunction → activar .agent → prueba end-to-end).
- Solo Amazon Connect está verificado end-to-end en docs oficiales. Genesys Cloud CX, NICE CXone y BYOC resuelven Transfer to Number dentro de su propio flow engine — requieren consulta con el partner.
Síntoma
El agente de Voz llega a un punto donde debe transferir. El cliente termina en un beep, la llamada cae al IVR general, o el asesor humano contesta sin ver el registro de la Voice Call ni la transcripción parcial. En algunos casos, la llamada se cuelga silenciosamente porque no hay agente disponible con el skill correcto y no se definió fallback.
Causa raíz
En Agentforce Voice, la escalación es una coreografía de tres piezas que trabajan por separado: (a) el .agent debe declarar el End Action correcto y pasar el contexto adecuado, (b) el OmniChannelFlow debe existir y estar publicado con la lógica de Route Work, (c) la operación humana (Presence Status, Presence Configuration, Queue, Skills, licencias) debe estar lista para aceptar la llamada. Si cualquiera falla, la llamada muere.
Impacto
Sin un handoff limpio, el ROI del agente de Voz colapsa: cada caso que no puede contener genera una segunda llamada del cliente o un ticket manual, más el costo de reputación de cortar la conversación. Además pierde la promesa central del canal: escalación con contexto, no reinicio.
Un handoff limpio en Agentforce Voice no lo resuelve una sola configuración. Es una cadena de siete piezas — algunas del bot, otras del canal, otras de la operación humana. Si entiendes lo que hace cada una, el step-by-step se vuelve mecánico.
- Dónde vive la lógica de ruteoOmniChannelFlow en Salesforce (Route Work action). Declarativo, visual, con skill matching y branches de fallback.Contact Flow de Amazon Connect (bloque 'Transfer to phone number'). Vive fuera de Salesforce, en la consola del proveedor de telefonía.
- Cómo se dispara desde el .agentEnd Action tipo Escalate con parameter omniFlowApiName. El runtime de Voice pasa la Voice Call al OmniFlow al ejecutarse.No hay End Action nativo para transferir a número (Agent Script DSL v2, verificado hasta 2026-08). Hay que exponer una GenAiFunction → Apex invocable que llame la Toolkit API de Amazon Connect para setear un contact attribute y disparar un Quick Connect predefinido.
- Destino que aceptaAgent ID, Queue ID o Flow ID. Solo destinos dentro de Salesforce.Cualquier número telefónico en formato E.164. Sujeto al service quota de países permitidos en Amazon Connect (allowlist por país).
- Contexto que viaja al destinoCompleto. Transcripción, Voice Call record, Contact, campos capturados. El asesor humano abre el registro y lo ve todo.Nulo por default. Transcripción y campos capturados NO viajan por SIP. Si el destino es otro Amazon Connect / SF Voice, el contact attribute puede persistir vía CTR sync — cualquier otro caso, el destino recibe la llamada 'a ciegas'.
- Vida de la VoiceCall recordSigue viva. Se reasigna OwnerId al asesor, se puebla IsAcceptedByAgent, TimeToRoute, HoldTime. Reporting nativo cuenta la historia.Se cierra cuando el bot cuelga su rama. En Salesforce solo sobreviven TotalHoldDuration y campos del CTR sync. El leg externo vive en Amazon Connect, no en Salesforce.
- Cold vs warmWarm por naturaleza. El asesor acepta con contexto visible antes de escuchar la llamada.Cold por default. El bloque 'Transfer to phone number' es un bridge inmediato. Warm transfer solo se implementa con Consult desde un softphone humano — no desde el bot.
- Fallback si el destino no contestaBranch del OmniChannelFlow puede rerroutear a otra Queue, mandar notification, o pasar a IVR.Branches nativos del bloque de Amazon Connect: Success | Call Failed | Timeout | Error. La lógica de fallback vive en el Contact Flow del proveedor.
- Proveedores de telefonía soportadosAmazon Connect (SCV HVCC) + cualquier Service Cloud Voice partner telephony y Bring Your Own Channel — la Route Work action es agnóstica al proveedor.Amazon Connect verificado end-to-end en docs oficiales. Genesys Cloud CX, NICE CXone y BYOC resuelven la transferencia externa dentro de su propio flow engine — sin path oficial de Salesforce documentado. Verificar con el partner respectivo.
- Casos donde tiene sentidoEl default. Cualquier caso donde el asesor humano vive en Salesforce y debe ver la conversación del bot.Overflow a IVR legacy, redirección a un partner externo sin acceso a Salesforce, número de emergencia, o cierre de llamada a un número de callback específico del cliente.
Cliente marca al número del Contact Center
│
▼
Voice Call flow inicial ──► Agentforce Voice Bot
│
│ (planner evalúa turno)
│
┌─────┴─────┐
│ │
(bot puede resolver) (escalar)
│ │
▼ ▼
Continúa turno Topic "Escalación a humano"
│
▼
End Action · Escalate
│
▼
OmniChannelFlow (Route Work)
│
┌───────────┴───────────┐
│ │
Queue destino (fallback branch)
+ Requested Skills si no hay match
│ │
▼ ▼
Presence Configuration Otra Queue / IVR
+ Presence Status
│
Asesor disponible con
Presence Status "Available for Voice"
y skill match
│
▼
OmniChannel Widget · alerta al asesor
│
(asesor Accept)
│
▼
Voice Call reasignada
Owner = User (asesor)
Asesor ve: transcripción parcial,
campos capturados, Contact, Voice Call record
Leyenda
- End Action · Escalate — Acción terminal declarada en el topic del .agent. No responde texto — invoca el runtime del canal Voice para que ejecute el OmniChannelFlow declarado.
- OmniChannelFlow — Flow con trigger OmniChannel. Único punto donde vive la lógica de routing (Queue/Skill/Priority/Fallback).
- Presence Status + Configuration — Combinación que decide si un asesor puede recibir una Voice Call en un momento dado. Ambas deben incluir el canal Voice.
- Owner reasignado — Al aceptar, la Voice Call queda con OwnerId = asesor. A partir de ese momento el reporting nativo dice la verdad.
Crear el Service Presence Status para Voz
Setup → Service Presence Statuses → New. Label: 'Disponible para Voz'. Developer Name: 'Available_For_Voice'. Status Option: Online. En Service Channels agregar 'Voice Call' (channel developer name: sfdc_voice). Guardar.
Screenshot pendiente
Crear la Presence Configuration
Setup → Presence Configurations → New. Label: 'Contact Center Voice'. Capacity: 100. En Assigned Users agregar los Users (o Profiles) del contact center. Guardar. Luego editar y en Assigned Presence Statuses agregar 'Disponible para Voz'.
Screenshot pendiente
Crear (o preparar) la Queue destino con canal Voice
Setup → Queues → New. Label: 'Cola Protección Familiar Voz'. Developer Name: 'Queue_ProteccionFamiliar_Voice'. En Supported Objects agregar 'Voice Call'. En Queue Members agregar los Users que deben recibir escalaciones de este agente. Guardar.
Screenshot pendiente
Crear Skills (opcional, si vas a usar Skill-Based Routing)
Setup → Skills → New. Ejemplos: 'Español', 'Producto Protección Familiar', 'Escalación N2'. Luego, en cada User que debe recibir handoff, ir al registro y agregar los Skills en la related list.
Screenshot pendiente
Construir el OmniChannelFlow
Flow Builder → New Flow → OmniChannel Flow. Object: Voice Call. En el start element se recibe implícitamente el RecordId de la Voice Call. Agregar action 'Route Work': Routing Type = Queue-Based (o Skill-Based), Queue Id = Id de 'Queue_ProteccionFamiliar_Voice', Priority = 1, Push Timeout = 30 segundos. Opcional: agregar branch de fallback para rerroutear si no hay agente en X segundos. Guardar como 'Voice_Escalate_ProteccionFamiliar' y activar.
Screenshot pendiente
Declarar el End Action Escalate en el .agent
Abrir el bundle del .agent en VS Code (Agent Script DSL v2). En el topic de escalación (ej. 'Escalación a humano') agregar el End Action: endAction: escalate con parameter omniFlowApiName='Voice_Escalate_ProteccionFamiliar'. Antes del End Action, el bot debe emitir el mensaje verbatim al cliente ('Espera un momento, te estoy transfiriendo con un humano'). Guardar. Publicar y activar el bundle.
Comando
sf agent validate authoring-bundle --json --api-name ProteccionFamiliarVoice
sf agent publish authoring-bundle --json --api-name ProteccionFamiliarVoice --skip-retrieve
sf agent activate --json --api-name ProteccionFamiliarVoiceScreenshot pendiente
Asignar el Permission Set / Presence al asesor
Cada asesor humano necesita: (a) licencia Service Cloud Voice asignada, (b) el Permission Set del Contact Center, (c) acceso a la Presence Configuration (asignada al Profile o directamente al User), (d) el Presence Status 'Disponible para Voz' habilitado. Verificar login al Service Console con OmniChannel Widget visible y estado 'Disponible para Voz' seleccionable.
Screenshot pendiente
Prueba end-to-end del handoff
Con al menos un asesor logueado en el Service Console y en estado 'Disponible para Voz': marcar al número del agente desde un teléfono de prueba. Conversar hasta forzar el topic de escalación. Verificar (a) el bot dice el mensaje verbatim de transferencia, (b) el asesor recibe alerta en OmniChannel Widget en menos de los segundos configurados en Push Timeout, (c) al aceptar, el asesor recibe la llamada y ve el Voice Call record con transcripción parcial y campos capturados.
Screenshot pendiente
Instrumentar métricas de handoff
Crear reportes sobre Voice Call filtrando IsAcceptedByAgent, TimeToRoute, TimeInQueue, HoldTime. Recomendamos KPIs: 'Tasa de handoff exitoso' (aceptado / escalados), 'Tiempo promedio hasta aceptación', 'Tasa de fallback' (llamadas que cayeron en branch de fallback por no encontrar agente).
Screenshot pendiente
