Manejo de errores, reintentos y orden de llamadas en CRM personalizado (API genérica)

En este documento, se describe el comportamiento de la función de CRM personalizado (API genérica) de CCAI Platform cuando los extremos de tu CRM devuelven respuestas que no son HTTP 200 "Success.". Se diseñó como una referencia de comportamiento para los integradores que configuran los extremos de la cuenta de la API y del registro de la API.

Orden de ejecución y relaciones de alto nivel

Cuando una interacción activa una integración de CRM personalizada, la plataforma llama a tus extremos en este orden:

  1. Operaciones a nivel de la cuenta (cuenta de API): contacto

    Ejemplos:

    • Buscar un contacto

    • Crea un contacto.

    • Actualizar un contacto

  2. Operaciones a nivel de registro (registro de API): ticket o caso

    Ejemplos:

    • Busca un ticket.

    • Crear un ticket

    • Actualizar un ticket

  3. Acciones posteriores a la sesión (si se configuraron)

    Ejemplos:

    • Agrega un comentario o una nota.

    • Sube un archivo adjunto o una transcripción.

    • Aplica las actualizaciones de cierre.

Los pasos anteriores suelen producir IDs que los pasos posteriores pueden usar. Por ejemplo, se puede pasar un contact_id a la creación de tickets cuando se incluye en la plantilla de carga útil del extremo, y se requiere un ticket_id para las acciones posteriores a la sesión en las configuraciones típicas de la API genérica. Ten en cuenta que no todos los extremos están configurados para extraer un ID. Consulta Matiz importante: 2xx + ID faltante en los extremos de extracción de ID.

Matiz importante: 2xx + ID faltante en los extremos de extracción de ID

No todos los extremos de CRM personalizados extraen un ID de la respuesta que reciben. Este comportamiento se aplica solo a los extremos configurados con un response_data_location y (para los extremos de creación) un custom_id_location, por lo general, extremos de búsqueda (que extraen el ID de un registro existente) y extremos de creación (que extraen el ID de un registro recién creado). Los extremos, como los comentarios, los archivos adjuntos y las actualizaciones, no extraen IDs de sus respuestas.

Impacto de la falta de ID en los extremos de extracción de ID

  • Para los extremos de búsqueda: Una respuesta 200 OK sin un registro coincidente (y, por lo tanto, sin ID extraíble) es un comportamiento normal de "no encontrado". Si tu instancia tiene habilitado skip_account_creation o skip_record_creation, la plataforma continuará de forma intencional con un contact_id o ticket_id nulo en lugar de intentar la creación. Este es el comportamiento esperado en esas configuraciones y no es un error de configuración.

  • Para los extremos de creación, una respuesta 200 OK que no incluya el ID recién creado en la ubicación configurada es un problema de configuración o de contrato de respuesta. La solicitud HTTP se realizó correctamente, por lo que no se activarán los reintentos, pero los pasos posteriores pueden continuar con los datos faltantes.

  • En ambos casos, la falla (cuando se trata de una falla) aparece como datos faltantes, en lugar de un error de extremo, lo que puede ser confuso durante la depuración.

Orientación para integradores

  • Para las operaciones de creación, haz que la devolución del ID esperado en la ubicación configurada sea parte de tu contrato de éxito, no solo la devolución de 2xx. Trata un ID faltante como un problema de configuración o de contrato de respuesta que vale la pena investigar.

  • Para las operaciones de búsqueda, es aceptable que se devuelva 200 OK sin coincidencias. Si tu instancia se basa de forma intencional en patrones de "búsqueda sin creación" (por ejemplo, skip_account_creation = true), documenta esa decisión para que los extremos descendentes sepan cómo controlar los IDs faltantes de forma correcta.

  • En las pruebas, verifica lo siguiente:

    • En el caso de los extremos de creación, el ID está presente de forma confiable en la respuesta y en la ubicación exacta configurada en el CRM personalizado.

    • Para los extremos de búsqueda, el comportamiento descendente de la plataforma coincide con la configuración de la marca de omisión de tu instancia.

Manejo de errores: descripción general

Cuando un extremo devuelve una respuesta que no es correcta (no es 2xx) o no responde, ocurre lo siguiente:

  • La plataforma puede volver a intentar la solicitud:

    • Una vez de inmediato para algunos estados.

    • Durante un período más largo para los errores que se pueden reintentar.

  • Los pasos posteriores pueden retrasarse mientras la plataforma sigue reintentando un paso anterior.

  • Algunas fallas se consideran no reintentables (por ejemplo, fallas de configuración o validación).

Las reglas de reintento detalladas se describen en Comportamiento de reintento y retirada. La relación entre las fallas y las llamadas descendentes se describe en Reglas de encadenamiento y dependencia.

Reglas de encadenamiento y dependencia

El comportamiento personalizado de CRM se rige por la configuración de CRM de tu instancia, específicamente, los parámetros de configuración documentados en Omitir la creación de cuentas y registros de CRM. En este documento, se hace referencia a esos parámetros de configuración por sus nombres de configuración de backend (skip_account_creation, skip_account_lookup y skip_record_creation), ya que aparecen de esa manera en los siguientes ejemplos de configuración de JSON.

En esos parámetros de configuración, la plataforma está predispuesta a continuar la cadena cuando puede, por ejemplo, creando un contacto anónimo cuando falla la búsqueda y se habilita la creación de cuentas, en lugar de siempre "detenerse de forma forzada".

Impacto de las fallas de la cuenta en las operaciones de registro

El paso de registro (ticket o caso) puede ejecutarse incluso cuando el paso de cuenta no produce un contacto, pero el comportamiento exacto depende de la configuración de la instancia.

Según tu configuración, la plataforma puede hacer lo siguiente:

  • Crea un contacto anónimo como resguardo y continúa con la creación del ticket.

  • Continúa con los pasos de registro sin un contact_id cuando la búsqueda o la creación de la cuenta estén configuradas para omitirse.

Qué significa esto para tus extremos

  • La falta de contact_id en la creación de tickets suele indicar una configuración de instancia en la que la búsqueda o la creación de cuentas están inhabilitadas.

  • Si tu instancia requiere cuentas, trata la falta de contact_id como un indicador que vale la pena investigar, en lugar de insertar tickets sin un contacto de forma silenciosa.

  • Si tu configuración permite de forma intencional la creación de tickets sin un contacto, asegúrate de que el extremo de tu ticket controle ese caso de forma explícita y predecible.

Impacto de los errores de registro en las acciones posteriores a la sesión

En el caso de las configuraciones de API genéricas en las que se configura la búsqueda de tickets, la plataforma no envía llamadas posteriores a la sesión, como call_finished, chat_finished, email_finished, save_call_recording, save_chat_history, update_ticket y done_ticket, hasta que exista un ticket_id.

Si se invoca un extremo posterior a la sesión sin un ticket_id, suele indicar una de las siguientes condiciones:

  • La búsqueda de tickets está inhabilitada para la configuración de la instancia, lo que no es habitual en una configuración típica de API genérica.

  • La plantilla de carga útil omitió la variable ticket_id, que es un problema de configuración que vale la pena investigar.

Qué significa esto para tus extremos

  • Trata la falta de ticket_id en las llamadas posteriores a la sesión como un indicador de configuración que vale la pena investigar, no como un comportamiento esperado que se debe absorber de forma silenciosa.

  • Si tu configuración no requiere de forma intencional la búsqueda de tickets, configura tus extremos posteriores a la sesión para que controlen un ticket_id faltante de forma correcta. Por ejemplo, registra el problema y no realices ninguna operación, o devuelve un mensaje de error claro y bien estructurado en lugar de que se produzca una falla.

Comportamiento de retirada y reintento

Los reintentos se realizan en tres capas:

  1. Reintento inmediato a nivel de HTTP (un segundo intento rápido)

  2. Reintento a nivel del adaptador (recuperación rápida para fallas de red y respuestas transitorias específicas).

  3. Reintentos a nivel de comando (reintentos de cola larga durante días)

Reintento inmediato a nivel de HTTP (reintento rápido)

Para ciertos estados transitorios, la plataforma realiza hasta 2 intentos en total (1 intento inicial y 1 reintento inmediato). Por lo general, esto se aplica a los siguientes estados de error:

  • 408, 413, 429, 500, 502, 503, 504, 521, 522 y 524.

Reintento a nivel del adaptador (recuperación rápida de la red)

Entre la llamada HTTP y la programación a nivel de comando, una capa de reintento intermedia en el adaptador de CRM (command_runner.js) controla las fallas que no producen una respuesta HTTP o que coinciden con mensajes transitorios específicos:

  • Reincorporación inmediata a la cola: Se activa por errores de TCP o a nivel de socket: ECONNRESET, ENOTFOUND, ESOCKETTIMEDOUT, ETIMEDOUT, ECONNREFUSED, EHOSTUNREACH, EPIPE, EAI_AGAIN. Son fallas de red que ocurren antes de que se reciba una respuesta HTTP.

  • Reintento con retraso de 30 segundos: Se activa cuando el mensaje de error es "Too Early" (HTTP 425), "Service Unavailable" o "Unordered Collection".

  • No se puede reintentar en esta capa: Todo lo demás se incluye en el programa de reintentos a nivel de comando (capa 3).

Por qué es importante para los integradores

Estos errores se producen cuando la plataforma no puede establecer o mantener una conexión TCP con tu extremo, lo que significa que suelen indicar un problema en tu servidor (servidor inactivo, rechazo de conexiones o interrupción de la conexión en medio de la solicitud), no solo en la infraestructura interna. El efecto práctico es que algunas fallas de red se recuperan mucho más rápido que el programa de 7 días a nivel de comando, a menudo en cuestión de segundos.

Reintentos a nivel de comando (~7 días, 14 intentos)

Si una operación falla y se puede reintentar, la plataforma puede reintentarla hasta 14 veces durante aproximadamente 7 días, con este programa:

  10s → 1m → 5m → 30m → 1h → 6h → 6h → 12h → 1d → 1d → 1d → 1d → 1d → 1d

Este comportamiento de reintento de cola larga se puede aplicar a lo siguiente:

  • Operaciones de cuentas

  • Registra operaciones.

  • Operaciones posteriores a la sesión.

Fallas no reintentables

Algunas fallas se consideran no reintentables, por ejemplo:

  • Fallas de configuración o validación (por ejemplo, los extremos requeridos no están configurados o están mal configurados).

  • Son ciertas categorías de errores internos que detecta la plataforma.

Si necesitas asegurarte de que una falla se trate como permanente (sin reintentos), comunícate con el equipo de asistencia o de implementación para confirmar la forma correcta de indicar una falla que no se puede reintentar en tu configuración específica.

Tiempos de espera agotados y fallas de red

La plataforma controla dos rutas distintas:

  1. Tiempos de espera a nivel de la aplicación: Cuando se supera el tiempo de espera de HTTP configurado (se envió la solicitud, pero no se recibió ninguna respuesta), la plataforma genera un error interno que se puede reintentar a nivel del comando (capa 3). Esto significa que la solicitud sigue el programa de retirada estándar (hasta 14 reintentos durante ~7 días).

  2. Errores de nivel de TCP/socket: Cuando la conexión falla a nivel de red antes de que se reciba una respuesta HTTP (por ejemplo, ETIMEDOUT, ESOCKETTIMEDOUT y ECONNREFUSED), la capa de adaptador (capa 2) los detecta y vuelve a poner en cola el comando de inmediato. La recuperación de estas fallas suele ser mucho más rápida, a menudo en cuestión de segundos, en lugar de seguir el programa de 7 días.

Por qué es importante la distinción

  • Un tiempo de espera de la aplicación (el servidor aceptó la conexión, pero no respondió a tiempo) vuelve a intentarlo con más lentitud.

  • Una falla a nivel de la red (no se pudo establecer conexión con tu servidor) se reintenta mucho más rápido.

  • En ambos casos, es posible que la solicitud se haya procesado parcialmente, por lo que los extremos deben ser idempotentes; consulta Crea extremos resilientes (idempotencia y sugerencias de diseño).

Matriz de comportamiento de códigos de estado y tiempos de espera (con ejemplos)

En las siguientes tablas y ejemplos, se describe cómo CCAI Platform controla los diferentes códigos de estado HTTP, los tiempos de espera y las fallas de red.

Tabla de resumen de resultados

Las filas relacionadas con el ID en la siguiente tabla solo se aplican a los extremos que están configurados para extraer un ID de la respuesta, como los extremos de búsqueda o creación. La mayoría de los demás extremos no realizan la extracción del ID de respuesta.

Resultado Ejemplos ¿Reintento de HTTP inmediato? ¿Reintentos de cola larga (~7 días)? Impacto posterior
Éxito de un extremo de extracción de ID 2xx + ID esperado presente en la ubicación de respuesta configurada. No No El flujo descendente continúa con el ID extraído.
Búsqueda sin coincidencia 2xx, pero no se encontró ningún registro en la ubicación configurada. No No Comportamiento normal de "no se encontró". Con skip_account_creation o skip_record_creation habilitados, el flujo descendente continúa de forma intencional con IDs nulos.
Cómo crear un pase de 2xx recurrente sin un documento de identidad 2xx de un extremo de creación, pero falta el ID del registro nuevo en la ubicación configurada. No No La etapa posterior puede continuar con los datos faltantes. Trátalo como un problema de configuración o de contrato de respuesta.
Éxito de un extremo que no extrae IDs 2xx de extremos, como acciones de notas, actualizaciones o archivos adjuntos que no extraen IDs. No No La descarga continúa según la cadena de comandos y la configuración de la instancia.
Error transitorio 408, 413, 429, 500, 502, 503, 504, 521, 522 y 524. Sí (dos intentos en total) A menudo, sí Los pasos posteriores pueden retrasarse mientras se producen los reintentos.
Otros errores 400, 401, 403, 404 y 4xx/5xx más. No A menudo, sí Los pasos posteriores pueden retrasarse mientras se realizan los reintentos.
Falla de configuración o validación de configuración incorrecta, extremos faltantes, N/A No La cadena puede detenerse o completarse parcialmente según la configuración.
Falla a nivel de la red (TCP/socket) ECONNRESET, ENOTFOUND, ESOCKETTIMEDOUT, ETIMEDOUT, ECONNREFUSED, EHOSTUNREACH, EPIPE y EAI_AGAIN. N/A No (lo controla la capa 2 del adaptador) El adaptador vuelve a poner en cola de inmediato; la recuperación suele ser rápida (segundos). Es posible que los pasos posteriores se retrasen brevemente.
Tiempo de espera a nivel de la aplicación HTTP timeout exceeded (no se recibió ninguna respuesta). N/A A menudo, sí (capa 3) Los pasos posteriores pueden retrasarse mientras se producen los reintentos a nivel de comando.

Ejemplo práctico con una configuración mínima de la API genérica

Una configuración de API genérica de CRM personalizada de referencia con los tres extremos que ejercita la cadena: buscar o crear contacto, buscar o crear ticket y un comentario posterior a la sesión. Usa esto como punto de partida y adáptalo a las características específicas de tu CRM.

Configuración a nivel de la instancia

{
  "lookup_method": "genericApi",
  "auth_method": "basic",
  "basic_auth_username": "ccai-integration",
  "basic_auth_password": "<secret>",
  "api_request_timeout": 10,
  "case_lookup_url": "https://crm.example.com/api/cases/{RECORD_ID}",
  "contact_lookup_url": "https://crm.example.com/api/contacts/{ACCOUNT_ID}",
  "skip_account_lookup": false,
  "skip_account_creation": false,
  "skip_record_creation": false
}

Formas de respuesta

La forma de la respuesta de tu CRM es específica del cliente. response_data_location es una ruta de acceso de estilo lodash que llega al objeto relevante dentro del cuerpo de la respuesta analizada. No es necesario unir las respuestas en un campo data de nivel superior. En los siguientes ejemplos, se muestran formas planas realistas de forma predeterminada.

Por ejemplo, un CRM que anida recursos en data.contact establecería response_data_location: "data.contact" y un cuerpo de respuesta de { "contact": { "id": "c_99812" } }; el resto de la configuración no se modifica.

Extremo 1: contact_find_endpoint

Busca un contacto por número de teléfono o correo electrónico.

{
  "request_url": "https://crm.example.com/api/contacts/search?phone={PHONE_NUMBER}&email={EMAIL}",
  "request_method": "GET",
  "request_parameters": {},
  "response_data_location": "data"
}

Listo: Se encontró el contacto

200 OK
Content-Type: application/json
{ "id": "c_42018", "first_name": "Jane", "last_name": "Doe" }

No se encontró el contacto

404 Not Found

La plataforma trata 404 como "no encontrado" (no como un error). Si skip_account_creation es falso, el flujo continúa hacia contact_create_endpoint.

Patrón alternativo de no encontrado: también es válido

200 OK
{}

Algunos CRM devuelven 200 OK con datos vacíos en lugar de 404 cuando no coincide ningún registro. La plataforma controla ambos de manera equivalente: ambos activan el siguiente paso (creación, si está habilitada).

Falla transitoria

503 Service Unavailable
}

Activa el reintento de HTTP inmediato de la capa 1 (2 intentos en total). Si sigue fallando, se recurre a los reintentos a nivel de comando de la capa 3.

Extremo 2: contact_create_endpoint

Crea un contacto. El campo custom_id_location le indica a la plataforma dónde encontrar el ID del contacto nuevo dentro de la respuesta.

{
  "request_url": "https://crm.example.com/api/contacts",
  "request_method": "POST",
  "request_parameters": {
    "first_name": "{FIRST_NAME}",
    "last_name": "{LAST_NAME}",
    "email": "{EMAIL}",
    "phone": "{PHONE_NUMBER}",
    "external_session_id": "{SESSION_TYPE}-{SESSION_ID}"
  },
  "response_data_location": "data",
  "custom_id_location": "id"
}

Creación correcta

201 Created
{ "id": "c_99812", "first_name": "John", "last_name": "Doe" }

2xx, pero falta el ID en la ubicación configurada

200 OK
{}

El extremo devolvió 200 OK sin id en la ubicación configurada. La plataforma registra una advertencia y reenvía un contact_id nulo de forma descendente (no se genera ninguna excepción ni se realiza ningún reintento). Trata esto como un olor de configuración: response_data_location y custom_id_location deberían producir de manera confiable un ID para cualquier 2xx que tu extremo devuelva desde esta ruta.

Extremo 3: case_create_endpoint

Crea un ticket. El contact_id del paso anterior está disponible como {ACCOUNT_ID}.

{
  "request_url": "https://crm.example.com/api/cases",
  "request_method": "POST",
  "request_parameters": {
    "subject": "{TICKET_SUBJECT}",
    "description": "{TICKET_DESCRIPTION}",
    "contact_id": "{ACCOUNT_ID}",
    "channel": "{CHANNEL}",
    "external_session_id": "{SESSION_TYPE}-{SESSION_ID}"
  },
  "response_data_location": "data",
  "custom_id_location": "id"
}

Creación correcta

201 Created
{ "id": "case_77103", "status": "new" }

Con response_data_location: "data", la plataforma resuelve la ruta de acceso al cuerpo de la respuesta analizada. Luego, lee el campo en custom_id_location: "id" → ticket_id = "case_77103", que fluye a la sesión posterior.

Extremo 4: case_comment_endpoint

Este extremo agrega un comentario de resumen de la sesión al ticket después de que finaliza la llamada o el chat. La variable RECORD_ID lleva el ticket_id producido en el paso 3.

{
  "request_url": "https://crm.example.com/api/cases/{RECORD_ID}/comments",
  "request_method": "POST",
  "request_parameters": {
    "body": "{COMMENT_BODY}",
    "agent_email": "{AGENT_EMAIL}",
    "channel": "{CHANNEL}",
    "duration": "{CALL_DURATION}",
    "external_session_id": "{SESSION_TYPE}-{SESSION_ID}"
  }
}

En el caso de las instancias de API genéricas con case_lookup_url configurado, la plataforma no enviará este extremo hasta que el paso de creación del ticket se complete correctamente, por lo que la falta de RECORD_ID aquí significa un problema de configuración, no un estado transitorio.

Variación: Creación de cuentas inhabilitada

Este ejemplo es muy similar al anterior, que se proporcionó para una configuración de API genérica mínima, excepto que, en este caso, tu instancia no permite crear contactos en el CRM. Mientras se ejecuta la búsqueda de cuentas, no se ejecuta la creación.

Cambio en la configuración de la instancia

{
  "skip_account_creation": true,
  "skip_account_lookup": false
}

Los cambios en la configuración de la instancia incluyen los siguientes comportamientos:

  • El paso de la cuenta solo llama a contact_find_endpoint. Si no se encuentra ningún contacto, no se llama a contact_create_endpoint.

  • El paso de registro recibe un contact_id nulo. La plataforma procede a crear el ticket sin un contact_id: {ACCOUNT_ID} se resuelve como vacío, y el campo contact_id se quita de tu carga útil de case_create_endpoint por completo.

  • Esto significa que tu extremo de creación de tickets debe poder crear tickets sin un contact_id en esta configuración. Si tu CRM requiere un contacto asociado para cada ticket, esta configuración no es compatible.

Patrón defensivo en case_create_endpoint

Sin un contact_id, tu CRM tiene menos contexto sobre el emisor de la llamada del que tendría normalmente. Puedes usar el ayudante =DEFAULT_VALUE para capturar cualquier información de identificación que esté disponible en la solicitud y pasarla como un indicador de resguardo:

"request_parameters": {
  "subject": "{TICKET_SUBJECT}",
  "contact_id": "{ACCOUNT_ID}",
  "contact_origin": "=DEFAULT_VALUE(\"{EMAIL}\", \"{PHONE_NUMBER}\", \"anonymous\")"
}

El ayudante =DEFAULT_VALUE elige el primer valor no vacío, por lo que tu CRM recibe un correo electrónico o un número de teléfono cuando hay uno disponible, y la cadena literal "anonymous" solo cuando no hay ninguno, lo que es útil para marcar los tickets que no tienen información de contacto de identificación adjunta.

Variación: flujo de tickets solo de búsqueda (sin creación de registros)

Las operaciones de la cuenta se ejecutan con normalidad, pero la creación de tickets está inhabilitada. La integración solo adjunta comentarios a los tickets existentes que se muestran en la búsqueda.

Cambio en la configuración de la instancia

{
  "skip_record_creation": true,
  "case_lookup_url": "https://crm.example.com/api/cases/{RECORD_ID}"
}

Los cambios abarcan los siguientes comportamientos:

  • El paso de registro llama a case_find_endpoint y usa el ticket que se muestra. Si no se encuentra ningún ticket, la cadena se detiene en el paso de registro: no se invoca case_create_endpoint.

  • Los extremos posteriores a la sesión (case_comment_endpoint, case_update_endpoint y similares) solo se envían cuando se busca un ticket correctamente. La protección ready? del lado de Rails garantiza que estos comandos permanezcan en cola (y, con el tiempo, venzan) si no se materializa ningún ticket_id.

  • Implicación práctica: En esta configuración, tus extremos posteriores a la sesión solo recibirán sesiones vinculadas a un ticket conocido. No necesitas controlar la rama "missing ticket_id".

La plataforma expone SESSION_TYPE y SESSION_ID como variables de plantilla. La forma más limpia de aplicar el patrón de clave compuesta es integrarlo directamente en cada cuerpo de solicitud relevante; tus extremos tendrán la clave canónica con la que trabajar, sin lógica adicional de tu parte:

"request_parameters": {
  "...your fields...": "...",
  "ccai_session_key": "{SESSION_TYPE}-{SESSION_ID}"
}

Para la misma llamada, cada reintento de cada extremo de la cadena (cuenta > registro > posterior a la sesión) producirá el mismo ccai_session_key. Úsala como el ancla de anulación de duplicación en la lógica de creación o actualización o inserción de tu CRM; por ejemplo, una actualización o inserción en (ccai_session_key, endpoint_kind) absorberá de forma segura los reintentos sin producir registros duplicados.

Compila extremos resilientes (idempotencia y sugerencias de diseño)

Debido a que las solicitudes se pueden repetir (reintento inmediato y reintentos durante días), tus extremos deben ser idempotentes:

  • Usa un identificador de interacción compuesto estable como tu clave de idempotencia:

    • Combina el tipo de sesión con el ID de sesión, por ejemplo, call-12345 o chat-12345.

    • No dependas solo de call_id o chat_id. Los IDs de voz y chat pueden superponerse porque cada secuencia puede comenzar en 1.

  • Si recibes lo que parece ser una solicitud duplicada, haz lo siguiente:

    • Examina la carga útil para determinar si realmente es un duplicado. Algunos extremos compartidos, como los de comentarios o notas, se pueden usar con varios tipos de comandos.

    • En el caso de las operaciones de creación, no deberían producirse solicitudes duplicadas en condiciones normales de éxito, pero pueden ocurrir si el CRM procesó la solicitud y, luego, devolvió un error o se agotó el tiempo de espera antes de que la plataforma recibiera una respuesta exitosa.

    • Cuando se confirme una solicitud de creación duplicada, devuelve el ID del registro creado anteriormente en lugar de otro registro.

  • Controla los IDs faltantes de forma explícita:

    • La falta de un contact_id en la creación de tickets suele indicar una configuración en la que la búsqueda o la creación de cuentas están inhabilitadas. Si tu instancia requiere cuentas, investiga en lugar de crear tickets sin contactos de forma silenciosa.

    • No se espera que falte un ticket_id en las llamadas posteriores a la sesión en las configuraciones típicas de la API genérica en las que se configura la búsqueda de tickets. Verifica la configuración de búsqueda de tickets y las plantillas de carga útil antes de tratar la solicitud como una operación no-op normal.

  • Para las actualizaciones, es preferible establecer campos con valores específicos en lugar de incrementar los contadores, de modo que las llamadas repetidas sean seguras.

Solución de problemas y observabilidad

Cuando depures una integración de CRM personalizada, ten en cuenta estos patrones:

  • Llamadas repetidas al mismo extremo:

    • Compara las marcas de tiempo con el programa de reintentos en Reintentos a nivel de comando (~7 días, 14 intentos).

    • Correlaciona los eventos con el identificador de sesión compuesto, como el tipo de sesión + el ID de sesión de llamada o chat.

    • Los registros exportados de CCAI Platform pueden ayudar a mostrar el ID de la sesión de llamada o chat junto con los eventos de la API para la trazabilidad.

    • Verifica si tu extremo muestra de forma coherente un error que se puede reintentar (por ejemplo, 500) en lugar de una falla de configuración que no se puede reintentar.

  • Reintentos que "no se detendrán":

    • Inspecciona las respuestas de error que devuelve tu extremo.

    • Si tu intención era que se produjera una falla permanente, comunícate con el equipo de asistencia para obtener orientación sobre cómo indicar un error no reintentable para tu configuración.

  • Nunca se llamó al extremo:

    • Verifica lo siguiente:

      • Los pasos upstream (cuenta/registro) se completaron correctamente y produjeron los IDs necesarios.

      • El extremo está configurado y habilitado correctamente en la configuración de tu CRM personalizado.

    • Un extremo mal configurado o inhabilitado, o una falla anterior en la cadena, puede impedir que se ejecuten ciertos pasos.

  • Correlacionar registros:

    • Registra la solicitud y la respuesta completas de tu lado, incluido el ID de interacción (call_id/chat_id).

    • Usa ese ID para correlacionar tus registros de CRM con el comportamiento de la plataforma a lo largo del tiempo (en especial, durante los reintentos).