Llamadas a la API de WhatsApp Cloud Chattigo
Especificación de la API de gráficos
Versión: 1.00
Contexto
WhatsApp Business Calling tiene como objetivo agregar el canal de comunicación VoIP además de la mensajería de texto entre los consumidores de WhatsApp y las empresas en WhatsApp. Los consumidores usarían la aplicación de WhatsApp de manera similar al actual producto de Llamadas entre Consumidores. Sin embargo, las empresas interactúan con WhatsApp a través de la interfaz Graph API para la señalización y conexión inicial de la llamada.
Arquitectura
Apis de configuración de Llamadas
Utiliza estas API para ver y gestionar la configuración relacionada con las llamadas para los números de teléfono de tu empresa. Por defecto, las llamadas no están habilitadas en un número de teléfono del negocio.
Actualizar
| Descripción | Actualizar la configuración de llamadas para un número de teléfono. |
|---|---|
| Endpoint | POST calls/v21.0/{did}/settings |
| Cuerpo de la solicitud | { “calling”: { “status”: “ENABLED”, “call_icon_visibility”: “DEFAULT”, “call_hours”: { “status”: “ENABLED”, “timezone_id”: “America/Manaus”, “weekly_operating_hours”: [ { “day_of_week”: “MONDAY”, “open_time”: “0400”, “close_time”: “1020” }, { “day_of_week”: “TUESDAY”, “open_time”: “0108”, “close_time”: “1020” } ], “holiday_schedule”: [ { “date”: “2026-01-01”, “start_time”: “0000”, “end_time”: “2359 } ] }, “callback_permission_status”: “ENABLED” } } |
| Respuesta | { “success”: true } |
| Respuesta de error | { “error”: { “message”: “<Error Message>”, “type”: “<Exception Type>”, “code”: <Exception Code>, “fbtrace_id”: “<Trace ID>” } } |
| Permisos de la aplicación | gestión empresarial de whatsapp Se requiere acceso avanzado para utilizar la API en nombre de los clientes empresariales finales. |
| Parámetros del punto final | did: Este es un número de teléfono registrado en la plataforma de WhatsApp Business. |
| Opciones | Parámetros anidados bajo el nodo “calling”: status: [ENABLED, DISABLED] Indica si la función de llamadas está habilitada para el número. call_icon_visibility (opcional): [DEFAULT, DISABLE_ALL] Esto controla la visualización del ícono de llamada en las aplicaciones cliente de WhatsApp para consumidores. Consulta los detalles sobre el comportamiento. Supported consumer client versions: Versiones compatibles de la aplicación cliente para consumidores: Android 2.24.10.x y superior iOS 2.24.10.x y superior call_hours (opcional):Especifica el horario de llamadas que se aplicará a todas las llamadas entrantes al negocio. Todos los valores de los campos en call_hours serán reemplazados por los valores enviados en el cuerpo de la solicitud de esta API. status[Obligatorio] :[ENABLED, DISABLED] Si la empresa tiene necesidades específicas de horario que deben aplicarse. Establecido en ENABLED. Se aplicará según los datos proporcionados en los campos siguientes. Si se establece en DISABLED, se asumirá que el negocio está disponible para recibir llamadas las 24 horas del día, los 7 días de la semana. timezone_id [Obligatorio]: Zona horaria del negocio. Se enumeran los valores compatibles. aquí.Ejemplo : América/Menominee, Asia/Singapur weekly_operating_hours [Requerido]: Horario de atención para cada día de la semana. **day_of_week[Requerido]**LUNES,MARTES, MIÉRCOLES, JUEVES, VIERNES, SÁBADO, DOMINGO] |
| Detalles de la respuesta | success: operación exitosa |
| Detalles | Llama a esta API para habilitar o deshabilitar la función de llamadas y configurar los ajustes relacionados con las llamadas. Estado de llamadas (Calling Status): Cuando una empresa establece el estado de llamadas como habilitado (ENABLED), los clientes de WhatsApp mostrarán el ícono de llamada en las conversaciones con la empresa y en el perfil del chat empresarial. El ícono de llamada se ocultará cuando el estado de llamadas esté deshabilitado (DISABLED). Las actualizaciones del ícono de llamada en chats existentes serán casi en tiempo real cuando el número de teléfono de la empresa esté en los contactos del usuario. De lo contrario, las actualizaciones serán en tiempo real para un número limitado de usuarios en conversación con la empresa, y eventuales (hasta unos días) para el resto. Consulta las instrucciones para forzar la visualización del ícono de llamada. Elegibilidad para llamadas (Calling Eligibility): Para habilitar las llamadas, la empresa debe tener un límite de mensajería de 1000 conversaciones iniciadas por la empresa en un período continuo de 24 horas (o más) en cualquiera de sus números de teléfono. Ver instrucciones sobre cómo verificar esto. Números empresariales previamente registrados mediante formulario de Google: Los números empresariales que fueron registrados previamente usando el formulario de Google se configuran automáticamente con el estado de llamadas habilitado. No es necesario realizar ninguna acción para esos números. Próximamente se eliminará el formulario de Google en favor de esta API de autoservicio. Visibilidad del ícono de llamada (Call Icon Visibility): Cuando el estado de llamadas está habilitado, puedes controlar adicionalmente la visualización del ícono de llamada mediante el parámetro "visibilidad del icono de llamada". El comportamiento para las opciones compatibles es el siguiente: DEFAULT El ícono de llamada se muestra en todos los puntos de entrada de llamadas (menú del chat e información del negocio). |
| Posibles errores | Errores de permisos/autorización Estado inválido Horario inválido para las horas de llamada semanales La fecha festiva indicada en call_hours es una fecha pasada Zona horaria inválida en call_hours weekly_operating_hours en call_hours no puede estar vacío Formato de fecha inválido en holiday_schedule para call_hours No se permiten más de 2 entradas en el horario weekly_operating_hours de call_hours No se permite un horario superpuesto en call_hours Más detalles sobre los códigos de error de Cloud API aquí. |
Obtener configuración
| Descripción | Obtener la configuración de llamadas para un número de teléfono. |
|---|---|
| endpoint | GET calls/v21.0/{did}/settings |
| Respuesta | { “calling”: { “status”: “ENABLED”, “call_icon_visibility”: “DEFAULT”, “call_hours”: { “status”: “ENABLED”, “timezone_id”: “America/Manaus”, “weekly_operating_hours”: [ { “day_of_week”: “MONDAY”, “open_time”: “0400”, “close_time”: “1020” }, { “day_of_week”: “TUESDAY”, “open_time”: “0108”, “close_time”: “1020” } ], “holiday_schedule”: [ { “date”: “2026-01-01”, “start_time”: “0000”, “end_time”: “2359” } ] }, “callback_permission_status”: “ENABLED” }, <Other non-calling feature configuration…> } |
| Respuesta de error | { “error”: { “message”: “<Error Message>”, “type”: “<Exception Type>”, “code”: <Exception Code>, “fbtrace_id”: “<Trace ID>” } } |
| Permisos de la aplicación | whatsapp_business_management Se requiere acceso avanzado para utilizar la API en nombre de los clientes empresariales finales. |
| Parámetros del punto final | did: Este es un número de teléfono registrado en la plataforma de WhatsApp Business. |
| Detalles de la respuesta | calling: Configuraciones relacionadas con la función de llamadas que la empresa configuró previamente. estado: [ENABLED, DISABLED] call_icon_visibility (opcional): [DEFAULT, DISABLE_ALL] horas_de_llamada (opcional): status : [ENABLED, DISABLED] timezone_id: Zona horaria del negocio. Se enumeran los valores admitidos aquí.Ejemplo : América/Menominee, Asia/Singapur weekly_operating_hours: Horario de atención para cada día de la semana.. day_of_week LUNES |
| Detalles | Las empresas llaman a esta API para verificar la configuración de sus funciones de llamadas. Esta API también puede devolver información sobre otras configuraciones de funciones de la Cloud API. |
| Posibles errores | Errores de permisos/autorización Más detalles sobre los códigos de error de la Cloud API.aquí. |
| Lanzamiento de objetivo | Beta |
Iniciar desde el Consumidor
Proceso de Pre-aceptación
| Descripción | Responda a una llamada iniciada por el usuario mediante la preaceptación de la llamada. La preaceptación facilita la configuración de la llamada y evita…recorte de audioproblemas |
|---|---|
| Endpoint | POST calls/v21.0/{did}/signaling |
| Cuerpo de la solicitud | { “messaging_product”: “whatsapp”, “call_id”: “wacid.ABGGFjFVU2AfAgo6V-Hc5eCgK5Gh”, “action”: “pre_accept”, “session” : { “sdp_type” : “answer”, “sdp” : “<<RFC 4566 SDP>>” } } } |
| Respuesta | { “messaging_product”: “whatsapp”, “success” : true } |
| Respuesta de error | { “error”: { “message”: “<Error Message>”, “type”: “<Exception Type>”, “code”: <Exception Code>, } } |
| Parámetros del punto final | did: Este es un número de teléfono registrado en la plataforma empresarial WhatsApp. |
| Opciones | call_id: Id de la llamada, del webhook que recibió previamente para esta llamada action: [pre_accept, accept, reject, terminate] session: Indica la información de conexión/evento correspondiente a esta sesión de llamada. Requiere dos parámetros. sdp: Información SDP del dispositivo en el otro extremo de la llamada. Ejemplo de estructura enapéndice. Sdp debe cumplir con RFC 4566. sdp_type: “answer” - para indicar la respuesta de sdp |
| Detalles de la respuesta | success: ¿la operación es exitosa? |
| Detalles | Las empresas llaman a esta API para iniciar el proceso de configuración de la llamada proporcionando una respuesta SDP. La preaceptación es opcional, pero muy recomendable para optimizar el proceso de configuración de la llamada y permitir que la conexión con los medios se preestablezca antes de aceptar la llamada, pero sin medios. Una vez que la llamada sea aceptada, los medios comienzan a fluir inmediatamente ya que la conexión ya está establecida. La conexión webrtc se establecería antes de aceptar la llamada, así que asegúrese de enviar el contenido multimedia solo después de recibir 200 OK para su llamada de aceptación. Si el contenido multimedia se transmite demasiado pronto, los consumidores no escucharán las primeras palabras. Si se transmite demasiado tarde, los consumidores no escucharán nada. |
| Posibles errores | ID de llamada no válido ID de número de teléfono no válido Error relacionado con su método de pago Información de conexión no válida, por ejemplo, sdp, ice, etc. Aceptar/Rechazar una llamada que ya está en curso/completada/fallida Errores de permisos/autorización Más detalles sobre los códigos de error de la API de Cloud aquí. |
Aceptar
| Descripción | Responder a una llamada iniciada por el usuario aceptando una llamada previa preaceptado llamar |
|---|---|
| Endpoint | POST calls/v21.0/{did}/signaling |
| Cuerpo de la solicitud | { “messaging_product”: “whatsapp”, “call_id”: “wacid.ABGGFjFVU2AfAgo6V-Hc5eCgK5Gh”, “action”: “accept”, “session” : { “sdp_type” : “answer”, “sdp” : “<<RFC 4566 SDP>>” }, “biz_opaque_callback_data”: “random data”, } } |
| Respuesta | { “messaging_product”: “whatsapp”, “success” : true } |
| Respuesta de error | { “error”: { “message”: “<Error Message>”, “type”: “<Exception Type>”, “code”: <Exception Code>, } } |
| Parámetros del punto final | did: Este es un número de teléfono registrado en la plataforma empresarial WhatsApp. |
| Opciones | call_id: Id de la llamada, del webhook que recibió previamente para esta llamada action: [pre_accept, accept, reject, terminate] Sesión: Indica la información de conexión/evento correspondiente a esta sesión de llamada. Requiere dos parámetros. sdp: Información SDP del dispositivo en el otro extremo de la llamada. Ejemplo de estructura enapéndice. Sdp debe cumplir con RFC 4566. sdp_type: “answer” - para indicar la respuesta de sdp biz_opaque_callback_data [Opcional]: Una cadena arbitraria, útil para seguimiento. Cualquier aplicación suscrita a la llama al webhook. El campo en la cuenta de WhatsApp Business puede obtener esta cadena, ya que está incluida en el objeto “llamadas” dentro del siguienteTerminar webhookcarga útil. La API de Cloud no procesa este campo, simplemente lo devuelve como parte deTerminar webhook Máximo 512 caracteres. |
| Detalles de la respuesta | éxito: ¿la operación es exitosa? |
| Detalles | Las empresas llaman a esta API para conectarse a una llamada proporcionando el SDP de un agente. La empresa dispone de un tiempo determinado (30-60 segundos) para responder a la llamada del usuario mediante el webhook entrante con la llamada API de preaceptación o aceptación. Si la empresa no responde, la llamada se finaliza en el lado del consumidor con el mensaje “No respondida” y se envía un webhook de finalización a la empresa. |
| Posibles errores | ID de llamada no válido ID de número de teléfono no válido Error relacionado con su método de pago Información de conexión no válida, por ejemplo, sdp, ice, etc. Aceptar/Rechazar una llamada que ya está en curso/completada/fallida Errores de permisos/autorización La respuesta SDP proporcionada en aceptar no coincide con la respuesta SDP proporcionada en el preaceptar API para el mismo ID de llamada Más detalles sobre los códigos de error de la API de Cloud aquí. |
Rechazar
| Descripción | Responder a una llamada iniciada por el usuario rechazando la llamada |
|---|---|
| Endpoint | POST calls/v21.0/{did}/signaling |
| Cuerpo de la solicitud | { “messaging_product”: “whatsapp”, “call_id”: “wacid.ABGGFjFVU2AfAgo6V-Hc5eCgK5Gh”, “action”: “reject” } |
| Respuesta | { “messaging_product”: “whatsapp”, “success” : true } |
| Respuesta de error | { “error”: { “message”: “<Error Message>”, “type”: “<Exception Type>”, “code”: <Exception Code>, } } |
| Parámetros del punto final | did: Este es un número de teléfono registrado en la plataforma empresarial WhatsApp. |
| Opciones | call_id: Id de la llamada, del webhook que recibió previamente para esta llamada action: [accept, reject, terminate] |
| Detalles de la respuesta | success: ¿la operación es exitosa? |
| Detalles | Las empresas llaman a esta API para rechazar una llamada. Normalmente, la empresa dispone de cierto tiempo (30-60 s) para responder a la llamada del usuario mediante el webhook entrante con la llamada API de rechazo. Si la empresa no responde, la llamada se finalizará en el lado del consumidor con el mensaje “No respondida” y se le enviará un webhook de finalización. |
| Posibles errores | ID de llamada no válido ID de número de teléfono no válido Información de conexión no válida, por ejemplo, sdp, ice, etc. Aceptar/Rechazar una llamada que ya está en curso/completada/fallida Errores de permisos/autorización Más detalles sobre los códigos de error de la API de Cloud aquí. |
Colgar
| Descripción | Finalizar la llamada |
|---|---|
| Endpoint | POST calls/v21.0/{did}/signaling |
| Cuerpo de la solicitud | { “messaging_product”: “whatsapp”, “call_id”: “wacid.ABGGFjFVU2AfAgo6V-Hc5eCgK5Gh”, “action” : “terminate” } |
| Respuesta | { “messaging_product”: “whatsapp”, “success” : true } |
| Respuesta de error | { “error”: { “message”: “<Error Message>”, “type”: “<Exception Type>”, “code”: <Exception Code>, } } |
| Parámetros del punto final | did: Este es un número de teléfono registrado en la plataforma empresarial WhatsApp. |
| Detalles | La empresa debe llamar a esta API para finalizar una llamada. Esto debe realizarse incluso si hay un paquete RTCP BYE en la ruta de medios. Esto ayuda a obtener precios más precisos. Cuando un consumidor finaliza la llamada, no es necesario invocar esta API. Se enviará un webhook de finalización luego del procesamiento exitoso de esta API. |
| Opciones | call_id: Id de la llamada action: [accept, reject, terminate] |
| Detalles de la respuesta | success: ¿la operación es exitosa? |
Llamadas a webhooks
Webhooks de Llamadas: La estructura de los webhooks es similar a la estructura de los webhooks utilizados para Mensajería en la API de la Nube.
Una sección “calls” en la sección “value” del webhook contiene campos relacionados con las llamadas.
Conectar:Recibir notificación.
Este webhook se envía en tiempo casi real, cuando la empresa recibe una llamada entrante. El webhook también incluye la información para establecer una conexión a través de WebRTC.
- Este webhook se envía para señalar a la empresa que establezca la conexión de llamada WebRTC utilizando la acción /calls=connect.
- Este webhook contiene la nueva información SDP para ayudar a establecer la conexión WebRTC.
{
"object": "whatsapp_business_account",
"entry": [
{
"id": "whatsapp-business-account-id",
"changes": [
{
"value": {
"messaging_product": "whatsapp",
"metadata": {
"display_phone_number": "16315553601",
"phone_number_id": "phone-number-id"
},
"contacts": [
{
"profile": {
"name": "callee name"
},
"wa_id": "16315553602"
}
],
"calls": [
{
"id": "wacid.ABGGFjFVU2AfAgo6V-Hc5eCgK5Gh",
"to": "16315553601",
"from": "16315553602",
"event": "connect",
"timestamp": "1671644824",
"direction": "BUSINESS_INITIATED",
"session": {
"sdp_type": "offer",
"sdp": "<<RFC 4566 SDP>>"
}
}
]
},
"field": "calls"
}
]
}
]
}
| Nombre del campo | Descripción |
|---|---|
| id | ID único creado para una llamada |
| to | Destinatario de la llamada |
| from | Llamador de la llamada |
| event | El evento sobre el cual este webhook notifica al oyente |
| timestamp | Marca de tiempo del evento del webhook |
| session | Indica información de conexión/evento correspondiente a esta sesión de llamada. Contendrá los dos parámetros siguientes. |
| sdp | Datos del protocolo de descripción de sesión para el dispositivo en el otro extremo de la llamada. Sdp debe cumplir con RFC 4566 |
| sdp_type | Tipo de SDP. El valor es “oferta” para llamadas iniciadas por el usuario. |
| contacts | Información del perfil del destinatario. Contiene su nombre de perfil de WhatsApp y su ID de WhatsApp. |
Terminada: Recibir notificación.
Este webhook se envía cuando la llamada ha sido terminada por cualquier razón, ya sea por el destinatario o el remitente. El hook contiene el ID de la llamada que fue terminada. Esto se genera ya sea cuando el consumidor cuelga o cuando la empresa llama a la Graph API
/calls con la acción=terminate.
{
"object": "whatsapp_business_account",
"entry": [
{
"id": "whatsapp-business-account-id",
"changes": [
{
"value": {
"messaging_product": "whatsapp",
"metadata": {
"display_phone_number": "16505553602",
"phone_number_id": "phone-number-id"
},
"calls": [
{
"id": "wacid.ABGGFjFVU2AfAgo6V-Hc5eCgK5Gh",
"to": "16315553601",
"from": "16315553602",
"event": "terminate",
"direction": "[BUSINESS_INITIATED|USER_INITIATED]",
"biz_opaque_callback_data": "random data",
"timestamp": "1671644824",
"status": "[FAILED | COMPLETED]",
"start_time": "1671644824",
"end_time": "1671644944",
"duration": 120
}
],
"errors": [
{
"code": 222, //INT_CODE,
"message": "ERROR_TITLE",
"href": "ERROR_HREF",
"error_data": {
"details": "ERROR_DETAILS"
}
}
]
},
"field": "calls"
}
]
}
]
}
| Nombre del campo | Descripción |
|---|---|
| id | ID único creado para una llamada |
| to | Destinatario de la llamada |
| from | Llamador de la llamada |
| event | El evento sobre el cual este webhook notifica al oyente |
| direction | Dirección de la llamada respecto del Negocio |
| timestamp | Marca de tiempo del evento del webhook |
| status | Estado final de la llamada Completada: Si la llamada se completó, la llamada rechazada por el destinatario también cuenta como completada. Fallido: Si la llamada falla a mitad de la conexión por cualquier motivo |
| start_time | [Opcional] Hora de inicio de la llamada. Solo aparece cuando la otra persona contestó la llamada. |
| end_time | [Opcional] Hora de finalización de la llamada. Solo aparece cuando la otra persona contestó la llamada. |
| duration | [Opcional] Duración de la llamada en segundos. Solo aparece cuando la otra persona contesta la llamada. |
| errors | Este campo existe si el estado es fallido e incluye más detalles sobre el error. |
| biz_opaque_callback_data | [Opcional] Solo estará disponible si se proporciona a través de Nuevas solicitudes de API de llamadas o Aceptar solicitudes de llamadas |
Mensajes con CTA de Llamada
Enviar mensaje interactivo con Botón.
| Descripción | Enviar un mensaje interactivo con el botón de llamada de WhatsApp |
|---|---|
| endpoint | POST /v21.0/{did}/messages |
| Cuerpo de la solicitud | { “messaging_product”: “whatsapp”, “recipient_type”: “individual”, “to”: “14085551234”, “type”: “interactive”, “interactive” : { “type” : “voice_call”, “body” : { “text”: “You can call us on WhatsApp now for faster service!” }, “action”: { “name”: “voice_call”, “parameters”: { “display_text”: “Call on WhatsApp”, “ttl_minutes”: 100, } } } } |
| Respuesta | Ver respuesta exitosa en la documentación |
| Respuesta de error | { “error”: { “message”: “<Error Message>”, “type”: “<Exception Type>”, “code”: <Exception Code>, } } |
| Parámetros del punto final | hizo:Este es un número de teléfono registrado en la plataforma empresarial WhatsApp. interactive.type y interactive.body son obligatorios interactive.type debe establecerse en “voice_call” interactive.body.text es el texto del mensaje interactive.header es opcional interactive.footer no está permitido interactive.action.name es obligatorio y su valor debe ser voice_call La clave interactive.action.parameters es opcional. El valor predeterminado de “display_text” es “Llamar ahora”. La longitud máxima permitida es de 20 caracteres. ttl_minutes (opcional) Es el tiempo de vida del botón de CTA en minutos. Transcurrido este tiempo, el botón no podrá utilizarse para iniciar una llamada a la empresa. El valor esperado es un valor entero entre 1 y 43200 (30 días) El valor predeterminado de “ttl_minutes” es (7 días) 10080 |
| Detalles | La empresa llama a esta API para enviar un mensaje a los consumidores y notificarles sobre la asistencia mediante un botón integrado en el mensaje. Al hacer clic en el botón, se inicia una llamada de WhatsApp al número de la empresa que envió el mensaje. Este comportamiento es similar al de un consumidor que hace clic en el icono de teléfono/llamada en la barra de título del chat. El botón para llamar por WhatsApp a otro número no es compatible. |
| Limitaciones | Enviar este mensaje a usuarios en versiones anteriores de la aplicación generará un webhook de error con un código de error.131026 |
| Opciones | Ver documentación pública Para más detalles |
| Detalles de la respuesta | Ver respuesta exitosa en la documentación |
Crear Plantilla con Botón
La API existente para crear plantillas se ha extendido para admitir un nuevo tipo de botón ‘LLAMADA DE VOZ’ que activará una llamada de WhatsApp cuando sea clicado por un consumidor de WhatsApp. En general, este botón se puede usar en cualquier lugar donde sea posible el botón de número de teléfono existente.
| Descripción | Crea una nueva plantilla de mensaje con el botón de llamada de WhatsApp |
|---|---|
| Endpoint | POST /message_templates/v21.0/{did} |
| Cuerpo de la solicitud | { “name”: “<NAME>”, “category”: “<CATEGORY>”, “language”: “<LANGUAGE>”, “components”: [ { “type”: “BODY”, “text”: “You can call us on WhatsApp now for faster service!” }, { “type”: “BUTTONS”, “buttons”: [ { “type”: “VOICE_CALL”, “text”: “Call Now” }, { “type”: “URL”, “text”: “Contact Support”, “url”: “https://www.luckyshrub.com/support" } ] } ] } |
| Respuesta | Ver respuesta exitosa en la documentación |
| Respuesta de error | { “error”: { “message”: “<Error Message>”, “type”: “<Exception Type>”, “code”: <Exception Code>, } } |
| Parámetros del punto final | El único campo compatible con el tipo de botón VOICE_CALL es “texto”, que indica la etiqueta del botón que se muestra en las aplicaciones cliente de consumo de WhatsApp. |
| Detalles | La empresa llama a esta API para enviar un mensaje de plantilla al consumidor para concientizarlo sobre el soporte de llamada mediante un botón en línea integrado en el mensaje. |
| Opciones | Ver documentación pública Para más detalles |
| Detalles de la respuesta | Ver respuesta exitosa en la documentación |
Códigos de Error de Llamadas
Códigos de error específicos de llamadas se detallan a continuación.
| Código | Descripción | Posibles soluciones | Código de estado HTTP |
|---|---|---|---|
| 138000 Llamadas no habilitadas | Las API de llamadas no están habilitadas para este número de teléfono | Las API de llamadas de WhatsApp CloudAPI actualmente solo están disponibles para determinados socios de la plataforma WhatsApp Business. Comuníquese con el equipo de WhatsApp Business para obtener más información. | 401 No autorizado |
| 138001 Receptor no llamable | El receptor no puede recibir llamadas Las razones pueden incluir: El número de teléfono del destinatario no es un número de teléfono de WhatsApp. El destinatario no ha aceptado nuestros nuevos Términos de Servicio y Política de Privacidad. Destinatario que utiliza una versión antigua de WhatsApp; debe utilizar la siguiente versión de WhatsApp o superior: El destinatario utiliza un cliente no compatible. Los clientes compatibles actualmente son Android, iOS, SMB Android y SMB iOS. | Confirme con el destinatario que acepta que usted se comunique con él a través de WhatsApp y que está usando la última versión de WhatsApp. | 400 Solicitud incorrecta |
| 138002 Límite de llamadas concurrentes | Límite alcanzado para llamadas simultáneas máximaspara el número dado | Inténtelo nuevamente más tarde o reduzca la frecuencia o cantidad de llamadas API que realiza la aplicación. | 429 Demasiadas solicitudes |
| 138003 Llamada duplicada | Ya hay una llamada en curso con el receptor | Inténtelo de nuevo más tarde cuando finalice la llamada actual. | 400 Solicitud incorrecta |
| 138004 Error de conexión | Error al conectar la llamada | Inténtelo de nuevo más tarde o investigue los parámetros de conexión proporcionados a la API. | 500 |
| 138005 Límite de velocidad de llamadas excedido | Se alcanzó el límite máximo de llamadas que se pueden iniciar desde el número de teléfono comercial | Inténtelo nuevamente más tarde o reduzca la frecuencia o cantidad de llamadas API que realiza la aplicación. | 429 Demasiadas solicitudes |
| 131009 | No se admite el tipo de mensaje interactivo “voice_call”. Tipos admitidos [‘button’, ‘list’]. | Asegúrese de que el remitente esté en uno de lospaíses apoyados. | 400 Solicitud incorrecta |
| 131044 | Se envía un webhook de error en las llamadas iniciadas por el usuario cuando no hay un método de pago válido adjunto | Esto es similar a “Problema de pago por elegibilidad empresarial” error en la mensajería. | 400 Solicitud incorrecta |
| 138006 No se encontró ningún permiso de llamada aprobado | No aprobadopermiso de llamadadel destinatario | Asegúrese de que el consumidor haya aceptado el permiso de llamada | 401 No autorizado |
| 138007 Error de tiempo de espera de conexión | No se pudo conectar la llamada debido a un tiempo de espera | La empresa no aplicó la oferta/respuesta SDP de Cloud API a tiempo. La API de conexión no fue invocada con la respuesta SDP a tiempo | 500 |
| 138009 Límite de solicitud de permiso de llamada alcanzado | Se alcanzó el límite para el envío de solicitudes de permiso de llamada para el par de empresa y consumidor indicado | Cuando una empresa envía más solicitudes de permiso de llamada por período, se limita su frecuencia. Una llamada conectada con un consumidor restablecerá los límites. | 400 |
| 138010 Llamadas iniciadas por empresa por límite de permiso aprobado alcanzado | Límite alcanzado para llamadas iniciadas por empresa por solicitud de permiso aprobada, para el par de empresa y consumidor determinado | Cuando una empresa intenta realizar más llamadas que el límite por solicitud de permiso de llamada aprobada, limitaremos la velocidad de las llamadas iniciadas por la empresa. | 400 |
| 138011 No se puede enviar la solicitud de permiso de llamada | No se puede enviar un mensaje de solicitud de permiso de llamada | Se intentó enviar un mensaje de solicitud de permiso de llamada sin una apertura ventana de atención al cliente | 400 Solicitud incorrecta |
| 100 Parámetro inválido | La llamada GraphAPI que está realizando tiene un parámetro no válido. | Los detalles exactos del error se enumerarán en la sección error_data de la carga de respuesta. Si se trata de un error relacionado con la validación SDP, el problema exacto se incluirá en los detalles. | 400 Solicitud incorrecta |
| 138012 Se alcanzó el límite de llamadas iniciadas por empresas | Se alcanzó el límite máximo de llamadas comerciales permitidas en 24 horas. Actualmente, se permiten 5 llamadas comerciales conectadas en 24 horas. | Los detalles exactos del error se enumerarán en la sección error_data de la carga de respuesta. Los detalles incluirán una marca de tiempo cuando se permitirá la próxima llamada. | 400 |
| 2593138 Obtener permiso de llamada para el número de teléfono del consumidor: se alcanzó el límite de API | Se alcanzó el límite de solicitudes a la API de estado de permiso de llamada de búsqueda. | Inténtelo de nuevo más tarde o reduzca la frecuencia o cantidad de solicitudes a la API que realiza la aplicación. | 429 Demasiadas solicitudes |
Soporte DTMF
El lanzamiento alfa de llamadas de Cloud API admite tonos DTMF. La intención es que las aplicaciones BSP puedan admitir sistemas y características basados en IVR para las empresas participantes en el Alfa.
Los consumidores pueden presionar los botones en la aplicación cliente y los tonos DTMF se inyectan en el flujo RTP de WebRTC establecido como parte de la conexión VoIP. El flujo WebRTC cumple con RFC 4733 para la transferencia de dígitos DTMF a través de la carga útil RTP. El flujo WebRTC ofrecido por la API de la Nube de WhatsApp cumple con lo mismo. Específicamente, no hay un webhook para transmitir dígitos DTMF.
Envío de dígitos DTMF en el cliente
Como parte de este flujo de trabajo, las aplicaciones cliente de WhatsApp se mejoran para tener un teclado de marcación para llamadas con números de teléfono comerciales de CloudAPI. Los consumidores pueden presionar los botones en el teclado de marcación de la aplicación cliente y enviar los tonos DTMF.
USAR: Este teclado de marcación sólo admite casos de uso de DTMF. No se muestra para llamadas de consumidor a consumidor y no cambia ningún otro comportamiento de llamadas. Por ejemplo, el teclado de marcación no se puede usar para marcar un número e iniciar una llamada o mensaje en WhatsApp.
Conexión WebRTC
Cuando un consumidor presiona un dígito en el teclado de marcación en el cliente, el DTMF equivalente se inyecta en el WebRTC. Los valores de los tonos son dígitos del 0 al 9, # y * (ref). La duración es de 500ms y el intervalo entre tonos es de 100ms para todos los tonos.
Diagrama de secuencia DTMF
Llamada de Consumidor a Empresa
Llamadas iniciadas por la empresa
Resumen del producto
Esta sección detalla específicamente la interfaz de la API para una llamada iniciada por la empresa a un consumidor de WhatsApp.Obtención de permiso para llamar
Para realizar una llamada a un usuario, una empresa debe obtener primero el permiso del usuario para realizar la llamada. Un permiso puede ser temporal o permanente. Una empresa puede obtener permiso para llamar de un usuario de cualquiera de las siguientes maneras:
- Envío de una solicitud de permiso de llamada al usuario: el usuario selecciona el tipo de permiso, ya sea temporal o permanente.
- El usuario proporciona un permiso de devolución de llamada.
- A partir de junio de 2025, el permiso se seleccionará automáticamente como temporal.
Nota: Tenga en cuenta que el permiso permanente aún no está disponible y su lanzamiento está previsto para el 30 de junio de 2025. Actualmente, los permisos temporales son la única opción disponible para los usuarios.
Cuando el consumidor lo otorga, un permiso de llamada permite a la empresa llamar al usuario sujeto a las siguientes restricciones (por par empresa + consumidor) para proteger a los usuarios de WhatsApp de llamadas no deseadas.
| Descripción | Límites | |
|---|---|---|
| Duración del permiso | Período de tiempo que la empresa tiene para llamar al usuario desde el momento en que el usuario aprueba el permiso de llamada. | Si el permiso es temporal - 7 días. Si el permiso es permanente - sin límite de duración. |
| Límites de llamadas | Número de llamadas conectadas que una empresa puede hacer al usuario. Las llamadas fallidas no seS cuentan para este límite. | 5 llamadas conectadas cada 24 horas. Se aplica a permisos temporales y permanentes. Un total posible de 35 llamadas en 7 días para permisos temporales. |
Permisos permanentes
Cómo empezar a probar los permisos permanentes:
- Los socios podrán empezar a integrar y probar los permisos permanentes a partir del 29 de mayo de 2025.
- Para habilitar los permisos permanentes en números de teléfono comerciales de prueba/desarrollo, por favor, envíe un ticket de soporte en nuestro canal de Soporte Directo con el tipo de ticket “Llamadas WA-Biz” y el asunto “Habilitar permisos permanentes en los números de prueba de socios”.
- Este acceso anticipado está destinado únicamente a fines de prueba e integración, y no para usuarios reales.
- Una vez habilitado para el acceso anticipado, los mensajes de solicitud de permiso de llamada enviados por el número habilitado incluirán la opción de permiso permanente en la interfaz de usuario del cliente.
- Las versiones mínimas de cliente requeridas se compartirán pronto.
- Durante el período de acceso anticipado, cuando se seleccione un permiso permanente, seguirá caducando después de 7 días.
Solicitud de permiso al usuario
Una empresa puede solicitar de forma proactiva un permiso de llamada a un usuario enviando un mensaje de solicitud de permiso de llamada. El mensaje de solicitud de permiso de llamada se puede enviar como:
- Un mensaje interactivo de formato libre o
- Un mensaje de plantilla
Un consumidor puede aprobar, rechazar o no responder a una solicitud de permiso de llamada. Un usuario también puede cambiar su respuesta (es decir, rechazar una solicitud de permiso concedida o conceder una solicitud de permiso rechazada) en cualquier momento antes de que caduque la solicitud de permiso de llamada.
La solicitud de permiso de llamada caduca cuando ocurre cualquiera de lo siguiente:
- Cuando el consumidor interactúa con una nueva solicitud de permiso de llamada subsiguiente a la empresa
- 7 días después de que el consumidor haya aceptado o rechazado el permiso
- 7 días después de que se haya entregado el permiso si el consumidor no responde a la solicitud
Para garantizar una experiencia de usuario óptima en torno a las llamadas iniciadas por la empresa, se aplican los siguientes límites:
- El envío de un mensaje de solicitud de permiso de llamada está sujeto a las siguientes restricciones:
- Una empresa puede enviar un máximo de 1 solicitud de permiso en 24 horas y 2 solicitudes de permiso en 7 días. Este límite se restablece cuando se realiza una llamada conectada entre la empresa y el consumidor (la llamada puede ser iniciada por el usuario o por la empresa).
- Las llamadas iniciadas por la empresa sin respuesta, es decir, las llamadas perdidas o rechazadas por el usuario, activan el siguiente comportamiento en la aplicación de usuario de WhatsApp:
- 2 llamadas consecutivas sin respuesta (Experiencia de usuario) resultan en un mensaje del sistema para reconsiderar un permiso aprobado.
- 4 llamadas consecutivas sin respuesta (Experiencia de usuario) resultan en la revocación automática de un permiso aprobado. El usuario puede volver a actualizar esto si así lo desea.
Solicitudes de permiso
Los mensajes de solicitud de permiso de llamada se pueden enviar a los usuarios de las siguientes dos maneras:
- Mensaje de formato libre de permiso de llamada: Permite a la empresa enviar una solicitud de permiso de llamada en respuesta a un mensaje del usuario sujeto a la ventana de atención al cliente. Un cuerpo de texto será opcional (pero muy recomendado) en este caso y las secciones de encabezado y pie de página no serán compatibles. El cuerpo se puede utilizar para proporcionar contexto sobre la solicitud de llamada. No es necesaria una ventana de conversación abierta, solo es suficiente una ventana de atención al cliente.
- Mensaje de plantilla de permiso de llamada: Permite a las empresas iniciar una conversación con una solicitud de llamada. El contexto (es decir, el cuerpo del texto) será obligatorio en este caso. La plantilla también admitirá las secciones de encabezado y pie de página para personalizar aún más la solicitud de permiso.
Solicitud de permiso
API: Envío de un mensaje de solicitud de permiso de llamada de formato libre
| Descripción | Enviar un mensaje para solicitar permiso de llamada al usuario |
|---|---|
| Endpoint | POST /v21.0/{did}/messages |
| Cuerpo de la solicitud | { “messaging_product”: “whatsapp”, “recipient_type”: “individual”, “to”: “<phone number> or <wa_id>”, “type”: “interactive”, “interactive”: { “type”: “call_permission_request”, “action”: { “name”: “call_permission_request” }, “body”: { “text”: “We would like to call you to help support your query on Order No: ON-12345.” } } } |
| Respuesta | { “messaging_product”: “whatsapp”, “contacts”: [{ “input”: “+1-408-555-1234”, “wa_id”: “14085551234”, }] “messages”: [{ “id”: “wamid.gBGGFlaCmZ9plHrf2Mh-o”, }] } |
| Respuesta de error | { “error”: { “message”: “<Error Message>”, “type”: “<Exception Type>”, “code”: <Exception Code>, } } |
| Parámetros del punto final | ID de número de teléfono Este es un ID para cada número de teléfono registrado en la plataforma comercial de WhatsApp.Más detalles aquí |
| Opciones | Para: Número al que se realiza la llamada. Se requieren los códigos de país. Más información sobre las llamadas aceptadas. formatos aquí. Tipo: Este será un nuevo tipo de mensaje interactivo, más detalles sobre los mensajes interactivos.aquí Interactivo: El mensaje de solicitud de permisos de llamada es un tipo de mensaje interactivo. Solo los campos “type” y “action.name” son obligatorios. El nombre de la acción debe ser “call_permission_request”. cuerpo: campo opcional para proporcionar a los usuarios más contexto para la solicitud de llamada. Consulte las simulaciones anteriores para ver cómo se representará esto en el dispositivo cliente de WhatsApp. |
| Detalles de la respuesta | Según la respuesta normal de la API de envío de mensajes. Detalles aquí |
| Detalles | Las empresas llamarán a esta API para enviar un mensaje de solicitud de permiso de llamada a una cuenta de usuario de WhatsApp. Este mensaje requiere una conversación abierta con la cuenta de usuario. Más información sobre cómo abrir conversaciones. aquí. **Nota:**Las empresas no pueden editar el contenido del mensaje interactivo de solicitud de permiso de llamada. |
| Posibles errores | ID de número de teléfono no válido Errores de permisos/autorización Límite de velocidad alcanzado Enviar este mensaje a usuarios en versiones anteriores de la aplicación generará un webhook de error con un código de error.131026 Llamadas no habilitadas Más detalles sobre los códigos de error de la API de Cloud aquí. |
API: Creación de una nueva plantilla con solicitud de permiso de llamada
| Descripción | Creación de una plantilla de mensaje de solicitud de permiso de llamada |
|---|---|
| Endpoint | POST /message_templates/v21.0/{did} |
| Cuerpo de la solicitud | { “name”: “sample_cpr_template”, “language”: “en”, “category”: “[MARKETING |
| Respuesta | { “id”: “<ID>”, “status”: “<STATUS>”, “category”: “<CATEGORY>” } |
| Respuesta de error | { “error”: { “message”: “<Error Message>”, “type”: “<Exception Type>”, “code”: <Exception Code>, “error_subcode”: <Error subcode>, “is_transient”: false, “error_user_title”: “<Error Title>”, “error_user_msg”: “<Error Message>” } } |
| Parámetros del punto final | whatsapp-business-account-id: este es un ID para la cuenta comercial de WhatsApp para este número.Más detalles aquí |
| Detalles de la respuesta | Id: Id de la plantilla Estado: Estado de la plantilla Categoría: La categoría de plantilla que usted designó, o que le asignamos. |
| Detalles | Las empresas pueden llamar a esta API para crear una plantilla de mensaje de solicitud de permiso de llamada. Puede encontrar más información sobre cómo crear y gestionar plantillas aquí. Los medios no son compatibles con esta plantilla. Componentes: Para mensajes de plantilla de solicitud de permisos de llamada cuerpo: este componente es obligatorio para los tipos de plantilla call_permission_request y solo admite contenido de texto Los componentes de encabezado/pie de página son opcionales Categoría: solo se admiten Marketing y Utilidades tipo: “call_permission_request” identifica la plantilla como una plantilla de solicitud de permiso de llamada Tras crear la plantilla, las empresas pueden enviar un mensaje al usuario para iniciar una conversación con una solicitud de permiso de llamada. Para obtener más información sobre cómo enviar mensajes para una plantilla, consulte aquí. |
| Posibles errores | ID de cuenta empresarial de WhatsApp no válido Errores de permisos/autorización Alertas de validación de componentes/estructura de plantilla Más detalles sobre los códigos de error de la API de Cloud para los mensajes de plantilla aquí. |
| Parámetros del punto final | whatsapp-business-account-id: este es el ID de la cuenta comercial de WhatsApp para la que se creará esta plantilla. Más detalles aquí |
API: Envío de mensaje de plantilla de solicitud de permiso de llamada
| Descripción | Enviar un mensaje para solicitar permiso de llamada al usuario |
|---|---|
| Endpoint | POST /v21.0/{did}/messages |
| Cuerpo de la solicitud | { “messaging_product”: “whatsapp”, “recipient_type”: “individual”, “to”: “{user number}”, “type”: “template”, “template”: { “name”: “sample_cpr_template”, “language”: { “policy”: “deterministic”, “code”: “en_US” }, “components”: [ { “type”: “header”, “parameters”: [ { “type”: “text”, “text”: “ON-12345” } ] }, { “type”: “body”, “parameters”: [ { “type”: “text”, “text”: “ON-12345” }, { “type”: “text”, “text”: “Avocados” } ] } ] } } |
| Respuesta | { “messaging_product”: “whatsapp”, “contacts”: [{ “input”: “+1-408-555-1234”, “wa_id”: “+1-408-555-1234”, }] “messages”: [{ “id”: “wamid.gBGGFlaCmZ9plHrf2Mh-o”, }] } |
| Respuesta de error | { “error”: { “message”: “<Error Message>”, “type”: “<Exception Type>”, “code”: <Exception Code>, } } |
| Parámetros del punto final | ID de número de teléfono Este es un ID para cada número de teléfono registrado en la plataforma comercial de WhatsApp.Más detalles aquí |
| Opciones | Para obtener más detalles sobre cómo enviar mensajes de plantilla, consulte la documentación.aquí Los componentes pueden variar según los parámetros establecidos en la creación de la plantilla. |
| Detalles de la respuesta | Según la respuesta normal de la API de envío de mensajes. Detalles aquí |
| Detalles | Las empresas llamarán a esta API para enviar un mensaje de solicitud de permiso de llamada a una cuenta de usuario de WhatsApp. Este mensaje se cobrará según el asignado categoría de plantilla. **Nota:**Las empresas no pueden editar el contenido del componente de permiso de llamada. |
| Posibles errores | ID de número de teléfono no válido Errores de permisos/autorización Límite de velocidad alcanzado Enviar este mensaje a usuarios en versiones anteriores de la aplicación generará un webhook de error con un código de error.131026 Llamadas no habilitadas Más detalles sobre los códigos de error de la API de Cloud aquí. |
API: Obtener el estado actual del permiso de llamada
| Descripción | Obtener el estado del permiso de llamada para un número de teléfono de consumidor determinado. |
|---|---|
| Endpoint | GET /calls/v21.0/{did}/call_permissions?user_wa_id={user_whatsapp_id} |
| Respuesta | { “messaging_product”: “whatsapp”, “permission”: { “status”: “temporary”, “expiration_time”: 1745343479 }, “actions”: [ { “action_name”: “send_call_permission_request”, “can_perform_action”: true, “limits”: [ { “time_period”: “PT24H”, “max_allowed”: 1, “current_usage”: 0, }, { “time_period”: “P7D”, “max_allowed”: 2, “current_usage”: 1, } ] }, { “action_name”: “start_call”, “can_perform_action”: false, “limits”: [ { “time_period”: “PT24H”, “max_allowed”: 5, “current_usage”: 5, “limit_expiration_time”: 1745622600, } ] } } } |
| Respuesta de error | { “error”: { “message”: “<Error Message>”, “type”: “<Exception Type>”, “code”: <Exception Code>, “fbtrace_id”: “<Trace ID>” } } |
| Permisos de la aplicación | mensajería empresarial de WhatsApp |
| Parámetros del punto final | **ID del número de teléfono:**Esta es una identificación para cada número de teléfono registrado en la plataforma comercial de WhatsApp. Más detalles aquí **ID de usuario:**El número de teléfono del consumidor para el que se solicita el permiso. Se requieren códigos de país. Más información sobre los países aceptados. formatos aquí. |
| Detalles de la respuesta | permission status: cadena (enumeración: [“no_permission”, “temporary”, “permanent”]). Estado actual del permiso. no_permission: no se encontró ningún permiso para este consumidor temporary: al usuario se le otorgó un permiso temporal, según los detalles.aquí. permanent: al usuario se le otorgó un permiso permanente, no se requieren más permisos de llamada para poder iniciar una llamada con esteconsumidor expiration_time (opcional): La hora a la que expirará el permiso, representada como una marca de tiempo Unix en segundos en la zona horaria UTC. Si el permiso es permanente, este campo no estará presente. **actions:**Una lista de acciones que un número de teléfono empresarial puede realizar para facilitar el permiso de llamada o una llamada iniciada por la empresa. Por ejemplo, “send_call_permission_request”, “start_call”. Cada objeto de acción contiene los siguientes campos: **action_name:**Identifica la acción y puede ser send_call_permission_request o start_call **can_perform_action:**Una bandera que indica si la acción se puede realizar ahora, teniendo en cuenta todos los límites. **limits:**Representa la lista de restricciones temporales para la acción. Cada acción tiene una o más restricciones según el período (por ejemplo, solo se pueden enviar dos solicitudes de permiso en un período de 24 horas). Cada límite contiene los siguientes campos: time_period: Cadena (formato de duración ISO 8601, p. ej., “PT24H”, “P7D”). La duración del límite, que especifica el período de tiempo durante el cual se aplica. max_allowed: El número máximo de acciones permitidas dentro del período de tiempo especificado. current_usage: El número actual de acciones realizadas dentro del período de tiempo especificado. **limit_expiration_time (opcional):**La hora UTC a la que expirará el límite, representada como una marca de tiempo Unix en segundos. Si el uso actual es inferior al máximo permitido para el límite, este campo no estará presente. |
| Detalles | Las empresas pueden llamar a esta API para obtener el estado del permiso de llamada para un número de teléfono comercial con un solo número de teléfono de consumidor. Tipos de acciones restringidas por permisos de llamada: send_call_permission_request: representa la acción de enviar nuevos mensajes de solicitud de permisos de llamada al consumidor. start_call: Representa la acción de establecer una nueva llamada con el cliente. Establecer una nueva llamada significa que el consumidor contestó la llamada correctamente. |
| Posibles errores | ID de número de teléfono no válido Formato de número de teléfono del consumidor no válido. Si el formato del número de teléfono del consumidor no cumple con los estándares de formato de la API en la nube. Si el número de teléfono del consumidor es no apto para llamadas, la respuesta de la API será no_permission. Errores de permisos/autorización. Límite de velocidad alcanzado.Se puede realizar un máximo de 5 solicitudes a la API en una ventana de 1 segundo. Las llamadas no están habilitadas para el número de teléfono comercial. Más detalles sobre los códigos de error de la API de Cloud aquí. |
Webhook: Recepción de una respuesta de aprobación temporal de permiso de llamada
{
"object": "whatsapp_business_account",
"entry": [
{
"id": "{phone-number-id}",
"changes": [
{
"value": {
"messaging_product": "whatsapp",
"metadata": {
"display_phone_number": "{phone-number}",
"phone_number_id": "{phone-number-id}"
},
"contacts": [
{
"profile": {
"name": "NAME"
},
"wa_id": "{phone-number}"
}
],
"messages": [
{
"from": "{phone-number}",
"id": "wamid.sH0kFlaCGg0xcvZbgmg90lHrg2dL",
"timestamp": "{TIMESTAMP}",
"context": {
"from": "{phone-number}",
"id": "wamid.gBGGFlaCmZ9plHrf2Mh-o"
},
"interactive": {
"type": "call_permission_reply",
"call_permission_reply": {
"response": "accept",
"is_permanent": false,
"expiration_timestamp": "{timestamp}",
"response_source": "user_action"
}
}
}
]
},
"field": "messages"
}
]
}
]
}
| Nombre del campo | Descripción |
|---|---|
| id | ID único creado para el mensaje |
| from | Remitente del mensaje |
| timestamp | Marca de tiempo de Unix en segundos del evento del webhook |
| interactive | Estructura que contiene los detalles de la respuesta de la cuenta del consumidor de WhatsApp al mensaje de solicitud de permisos de llamada. |
| response | Respuesta del consumidor al mensaje de solicitud de permiso de llamada |
| is_permanent | Indica si el permiso es permanente o no. Para permisos temporales, siempre será falso. |
| expiration_timestamp | Tiempo en segundos que expira este permiso de llamada si el consumidor lo aprobó. Este valor puede ser nulo si el permiso es permanente. |
| response_source | Fuente de este permiso, los valores posibles para los permisos de llamadas aceptados son user_action: El usuario aprobó o rechazó el permiso [Desde junio] automático: aprobación automática debido a la llamada iniciada por el usuario |
| context | Se incluye contexto para un mensaje cuando un usuario responde o interactúa con uno de tus mensajes. El ID en la sección de contexto se basará en el caso de uso. Cuando el usuario responde a un mensaje de solicitud de permiso de llamada enviado por la empresa, el ID del mensaje de solicitud de permiso de llamada enviado por la empresa se incluye en la sección de contexto del webhook. |
| from | Número de teléfono comercial |
| id | Id. del mensaje de solicitud de permiso de llamada para el que es esta respuesta |
Webhook: Recepción de una respuesta de aprobación permanente de permiso de llamada
{
"object": "whatsapp_business_account",
"entry": [
{
"id": "{phone-number-id}",
"changes": [
{
"value": {
"messaging_product": "whatsapp",
"metadata": {
"display_phone_number": "{phone-number}",
"phone_number_id": "{phone-number-id}"
},
"contacts": [
{
"profile": {
"name": "NAME"
},
"wa_id": "{phone-number}"
}
],
"messages": [
{
"from": "{phone-number}",
"id": "wamid.sH0kFlaCGg0xcvZbgmg90lHrg2dL",
"timestamp": "{TIMESTAMP}",
"context": {
"from": "{phone-number}",
"id": "wamid.gBGGFlaCmZ9plHrf2Mh-o"
},
"interactive": {
"type": "call_permission_reply",
"call_permission_reply": {
"response": "accept",
"is_permanent": true,
"response_source": "user_action"
}
}
}
]
},
"field": "messages"
}
]
}
]
}
| Nombre del campo | Descripción |
|---|---|
| id | ID único creado para el mensaje |
| from | Remitente del mensaje |
| timestamp | Marca de tiempo de Unix en segundos del evento del webhook |
| interactive | Estructura que contiene los detalles de la respuesta de la cuenta del consumidor de WhatsApp al mensaje de solicitud de permisos de llamada. |
| response | Respuesta del consumidor al mensaje de solicitud de permiso de llamada |
| is_permanent | Indica si el permiso es permanente o no. Para permisos permanentes, esto siempre será cierto. |
| response_source | Fuente de este permiso, los valores posibles para los permisos de llamadas aceptados son user_action: El usuario aprobó o rechazó el permiso [Desde junio] automático: aprobación automática debido a la llamada iniciada por el usuario |
| context | Se incluye contexto para un mensaje cuando un usuario responde o interactúa con uno de tus mensajes. El ID en la sección de contexto se basará en el caso de uso. Cuando el usuario responde a un mensaje de solicitud de permiso de llamada enviado por la empresa, el ID del mensaje de solicitud de permiso de llamada enviado por la empresa se incluye en la sección de contexto del webhook. |
| from | Número de teléfono comercial |
| id | Id. del mensaje de solicitud de permiso de llamada para el que es esta respuesta |
Webhook: Recepción de una respuesta de rechazo de permiso de llamada
{
"object": "whatsapp_business_account",
"entry": [
{
"id": "{phone-number-id}",
"changes": [
{
"value": {
"messaging_product": "whatsapp",
"metadata": {
"display_phone_number": "{phone-number}",
"phone_number_id": "{phone-number-id}"
},
"contacts": [
{
"profile": {
"name": "NAME"
},
"wa_id": "{c-phone-number}"
}
],
"messages": [
{
"from": "{c-phone-number}",
"id": "wamid.sH0kFlaCGg0xcvZbgmg90lHrg2dL",
"timestamp": "{TIMESTAMP}",
"context": {
"from": "{phone-number}",
"id": "wamid.gBGGFlaCmZ9plHrf2Mh-o"
},
"interactive": {
"type": "call_permission_reply",
"call_permission_reply": {
"response": "reject",
"response_source": "user_action"
}
}
}
]
},
"field": "messages"
}
]
}
]
}
| Nombre del campo | Descripción |
|---|---|
| id | ID único creado para el mensaje |
| from | Remitente del mensaje |
| timestamp | Marca de tiempo Unix del evento webhook en segundos |
| interactive | Estructura que contiene los detalles de la respuesta de la cuenta del consumidor de WhatsApp al mensaje de solicitud de permisos de llamada. |
| response | Respuesta del consumidor al mensaje de solicitud de permiso de llamada |
| response_source | Origen de este permiso, posibles valores para permisos de llamadas rechazadas user_action: El usuario aprobó o rechazó el permiso automático: rechazo automático debido a límites de llamadas no contestadas |
| context | Se incluye contexto para un mensaje cuando un usuario responde o interactúa con uno de tus mensajes. El ID en la sección de contexto se basará en el caso de uso. Cuando el usuario responde a un mensaje de solicitud de permiso de llamada enviado por la empresa, el ID del mensaje de solicitud de permiso de llamada enviado por la empresa se incluye en la sección de contexto del webhook. |
| from | Número de teléfono comercial |
| id | Id. del mensaje de solicitud de permiso de llamada enviado al consumidor |
Webhook: Recepción de un permiso de llamada desde el flujo de callback
{
"object": "whatsapp_business_account",
"entry": [
{
"id": "{phone-number-id}",
"changes": [
{
"value": {
"messaging_product": "whatsapp",
"metadata": {
"display_phone_number": "phone-number",
"phone_number_id": "{phone-number-id}"
},
"contacts": [
{
"profile": {
"name": "NAME"
},
"wa_id": "{c-phone-number}"
}
],
"messages": [
{
"from": "{c-phone-number}",
"id": "wamid.sH0kFlaCGg0xcvZbgmg90lHrg2dL",
"timestamp": "{TIMESTAMP}",
"context": {
"from": "{phone-number}",
"id": "wacid.gBGGFlaCmZ9plHrf2Mh-o"
},
"interactive": {
"type": "call_permission_reply",
"call_permission_reply": {
"response": "accept",
"is_permanent": false,
"expiration_timestamp": "{timestamp}",
"response_source": "[user_action|automatic]"
}
}
}
]
},
"field": "messages"
}
]
}
]
}
| Nombre del campo | Descripción |
|---|---|
| id | ID único creado para el mensaje |
| from | Remitente del mensaje |
| timestamp | Marca de tiempo Unix del evento webhook en segundos |
| interactive | Estructura que contiene los detalles de la respuesta de la cuenta del consumidor de WhatsApp al mensaje de solicitud de permisos de llamada. |
| response | Respuesta del consumidor al mensaje de solicitud de permiso de llamada |
| expiration_timestamp | Tiempo en segundos en que expira este permiso de llamada si el consumidor lo aprobó |
| response_source | Fuente de este permiso, posibles valores para la devolución de llamada [Antes de junio] user_action: El usuario aprobó o rechazó el permiso [Después de junio] automático: aprobación automática debido a la llamada iniciada por el usuario |
| context | Se incluye contexto para un mensaje cuando un usuario responde o interactúa con uno de tus mensajes. El ID en la sección de contexto se basará en el caso de uso. Cuando el usuario proporciona un permiso después de una llamada iniciada por un consumidor perdida, el identificador de llamada de la llamada iniciada por el usuario perdida por la empresa se incluye en la sección de contexto. La empresa recibirá los webhooks de llamada habituales para esta llamada cuando se produzca. |
| from | Número de teléfono comercial |
| id | Id. del mensaje de solicitud de permiso de llamada enviado al consumidor |
Nueva API de llamada
| Descripción | Iniciar una nueva llamada |
|---|---|
| Endpoint | POST calls/v21.0/{did}/singnalig |
| Cuerpo de la solicitud | { “messaging_product”: “whatsapp”, “to”:“14085551234”, “action”: “connect”, “session” : { “sdp_type” : “offer”, “sdp” : “<<RFC 4566 SDP>>” }, “biz_opaque_callback_data”: “random data” } |
| Respuesta | { “messaging_product”: “whatsapp”, “calls” : [{ “id” : “wacid.ABGGFjFVU2AfAgo6V”, }] } |
| Respuesta de error | { “error”: { “message”: “<Error Message>”, “type”: “<Exception Type>”, “code”: <Exception Code>, } } |
| Parámetros del punto final | ID de número de teléfono Este es un ID para cada número de teléfono registrado en la plataforma comercial de WhatsApp.Más detalles aquí |
| Parámetros del cuerpo de la solicitud | Para: Número al que se realiza la llamada. Se requieren los códigos de país. Más información sobre las llamadas aceptadas. formatos aquí. Sesión: Indica la información de conexión/evento correspondiente a esta sesión de llamada. Requiere dos parámetros. sdp: Información SDP del dispositivo en el otro extremo de la llamada. Ejemplo de estructura en el apéndice. Sdp debe cumplir con RFC 4566. sdp_type: “oferta” - para indicar oferta sdp biz_opaque_callback_data [Opcional]: Una cadena arbitraria, útil para seguimiento. Cualquier aplicación suscrita a lal lama al webhook El campo de la cuenta de WhatsApp Business puede obtener esta cadena. Se incluye en las siguientes cargas útiles del webhook: el objeto “calls” dentro de Conectar webhook carga útil, objeto “estados” dentro Webhook de estado carga útil y “llama” al objeto dentro Terminar webhook carga útil La API de Cloud no procesa este campo, solo lo devuelve como parte de los webhooks Máximo 512 caracteres. |
| Detalles de la respuesta | id: Id. único creado para identificar cada llamada comercial |
| Detalles | Las empresas llamarán a esta API para iniciar una llamada proporcionando el número del receptor de la llamada y una oferta de llamada webrtc. |
| Posibles errores | ID de número de teléfono no válido Errores de permisos/autorización Errores de validación del formato de solicitud, por ejemplo, información de conexión, sdp, ice, etc. Errores de validación de SDP en torno a Más detalles sobre los códigos de error de la API de Cloud aquí. |
Colgar una llamada activa
Webhooks de llamadas
La estructura de los webhooks es similar a la de los webhooks utilizados para mensajería en la API de la Nube. La documentación detallada de los webhooks se puede encontrar aquí. aquí.
Connect: Recibir la respuesta SDP de la API en la nube para iniciar la conexión de medios
Este webhook se envía en respuesta a una nueva solicitud de llamada recibida de la empresa.
- Este webhook contiene la información SDP de respuesta para establecer la conexión WebRTC
{
"object": "whatsapp_business_account",
"entry": [
{
"id": "whatsapp-business-account-id",
"changes": [
{
"value": {
"messaging_product": "whatsapp",
"metadata": {
"display_phone_number": "16315553601",
"phone_number_id": "phone-number-id"
},
"calls": [
{
"id": "wacid.ABGGFjFVU2AfAgo6V",
"to": "16315553602",
"from": "16315553601",
"event": "connect",
"timestamp": "1671644824",
"direction": "BUSINESS_INITIATED",
"session": {
"sdp_type": "answer",
"sdp": "<<RFC 4566 SDP>>"
},
"biz_opaque_callback_data": "random data"
}
]
},
"field": "calls"
}
]
}
]
}
| Nombre del campo | Descripción |
|---|---|
| id | ID único creado para una llamada |
| to | Destinatario de la llamada |
| from | Llamador de la llamada |
| event | El evento sobre el cual este webhook notifica al oyente |
| timestamp | Marca de tiempo del evento del webhook |
| session | Indica información de conexión/evento correspondiente a esta sesión de llamada. Contendrá los dos parámetros siguientes. |
| sdp | Datos del protocolo de descripción de sesión para el dispositivo en el otro extremo de la llamada. Estructura de ejemplo enapéndice. Sdp debe cumplir con RFC 4566 |
| sdp_type | El tipo de sdp es “respuesta” para una llamada iniciada por el negocio. |
| biz_opaque_callback_data | [Opcional] Solo estará disponible si se proporciona a través de nuevas solicitudes de API de llamadas |
Webhooks de estado de llamada: recibir notificaciones sobre eventos de una llamada iniciada por la empresa
Este webhook se envía en determinados eventos de una llamada iniciada por la empresa. Más concretamente, el webhook de estado se generará en los siguientes casos.
- Ringing: cuando la llamada iniciada por la empresa comienza a sonar en el dispositivo del consumidor de WhatsApp
- Accepted: cuando el consumidor de WhatsApp acepta la llamada iniciada por la empresa
- Rejected: cuando el consumidor de WhatsApp rechaza la llamada iniciada por la empresa
La estructura de este webhook es similar a la de los webhooks de estado utilizados para los mensajes de la API de Cloud. Más detalles sobre la estructura actual de los webhooks de estado aquí. aquí.
{
"object": "whatsapp_business_account",
"entry": [
{
"id": "whatsapp-business-account-id",
"changes": [
{
"value": {
"messaging_product": "whatsapp",
"metadata": {
"display_phone_number": "16315553601",
"phone_number_id": "phone-number-id"
},
"statuses": [
{
"id": "wacid.ABGGFjFVU2AfAgo6V",
"timestamp": "1671644824",
"type": "call",
"status": "[RINGING|ACCEPTED|REJECTED]",
"recipient_id": "16315553602",
"biz_opaque_callback_data": "random data"
}
]
},
"field": "calls"
}
]
}
]
}
| Nombre del campo | Descripción |
|---|---|
| statuses | Esta sección contiene información sobre los estados. |
| id | ID de la llamada para la que es este estado |
| type | El tipo al que pertenece este webhook de estado. Otro valor posible es “mensaje”. |
| recipient_id | El número de teléfono del consumidor de WhatsApp al que se dirige esta llamada es |
| timestamp | Marca de tiempo del evento del webhook |
| status | Estado de la llamada que este webhook está comunicando RINGING: La llamada iniciada por el negocio está sonando para el usuario ACCEPTED: La llamada iniciada por el negocio es aceptada por el usuario REJECTED: La llamada iniciada por el negocio es rechazada por el usuario |
| biz_opaque_callback_data | [Opcional] Solo estará disponible si se proporciona a través de nuevas solicitudes de API de llamadas |
Terminar: Recibir notificación sobre la terminación de la llamada
Esto es igual que el webhook de terminación para llamadas iniciadas por el usuario
Diagrama Consumidor - Empresa
Llamada Empresa a Consumidor
Prerrequisitos:
- [Esfuerzo único] Suscribirse a los campos de webhook de mensajes y llamadas
- [Por cada llamada] Asegurarse de que se abra una conversación con el consumidor.
- La empresa envía un mensaje de solicitud de permiso de llamada al consumidor
POST {phone-number-id}/messages
{
"messaging_product": "whatsapp",
"recipient_type": "individual",
"to": "<c-phone-number> or <wa_id>",
"type": "interactive",
"interactive": {
"type": "call_permission_request",
"action": {
"name": "call_permission_request"
}
}
}
-
La empresa recibe una respuesta con un ID de mensaje
{ "messaging_product": "whatsapp", "contacts": [ { "input": "{c-phone-number}", "wa_id": "{wa_id}" } ], "messages": [ { "id": "wamid.HBgLMTQxMjYxMzYyNTMVAgAR" } ] } -
Los webhooks de estado de mensajes se reciben según lo detallado aquí.
-
El consumidor responde a la solicitud de permiso de llamada con una aprobación.
{ "object": "whatsapp_business_account", "entry": [ { "id": "{phone-number-id}", "changes": [ { "value": { "messaging_product": "whatsapp", "metadata": { "display_phone_number": "{phone-number}", "phone_number_id": "{phone-number-id}" }, "contacts": [ { "profile": { "name": "NAME" }, "wa_id": "{c-phone-number}" } ], "messages": [ { "from": "{c-phone-number}", "id": "wamid.sH0kFlaCGg0xcvZbgmg90lHrg2dL", "timestamp": "{TIMESTAMP}", "context": { "from": "{phone-number}", "id": "wamid.HBgLMTQxMjYxMzYyNTMVAgAR" }, "interactive": { "type": "call_permission_reply", "call_permission_reply": { "response": "APPROVE", "expiration_timestamp": "{timestamp}" } } } ], "field": "messages" } } ] } ] } -
La empresa inicia una nueva llamada con el**/llamadas**API con el siguiente cuerpo de solicitud
**POST {phone-number-id}/calls**{ "messaging_product": "whatsapp", "to": "{c-phone-number}", "action": "connect", "session": { "sdp_type": "offer", "sdp": "<<RFC 4566 SDP>>" } } -
La empresa recibe la siguiente respuesta con un ID de llamada de la API de Cloud. La respuesta con el código de error 138006 indica que la cuenta del consumidor no tiene permiso para solicitar llamadas a este número.
{ "messaging_product": "whatsapp", "calls" : { "id" : "wacid.ABGGFjFVU2AfAgo6V", } } -
La empresa recibe un webhook con la respuesta sdp de Cloud API
{ "entry": [ { "changes": [ { "field": "calls", "value": { "calls": [ { "from": "{phone-number}", "session": { "sdp": "RFC 4566 SDP", "sdp_type": "answer" }, "id": "wacid.ABGGFjFVU2AfAgo6V", "to": "{c-phone-number}", "event": "connect", "timestamp": "1716496634", "direction": "BUSINESS_INITIATED" } ], "metadata": { "phone_number_id": "{phone-number-id}", "display_phone_number": "{phone-number}" }, "messaging_product": "whatsapp" } } ], "id": "{phone-number-id}" } ], "object": "whatsapp_business_account" } -
La empresa recibe los webhooks de estado apropiados para la llamada
{ "entry": [ { "changes": [ { "field": "calls", "value": { "statuses": [ { "id": "wacid.ABGGFjFVU2AfAgo6V", "type": "call", "status": "[RINGING|ACCEPTED|REJECTED]", "timestamp": "1716496655", "recipient_id": "{c-phone-number}" } ], "metadata": { "phone_number_id": "{phone-number-id}", "display_phone_number": "{phone-number}" }, "messaging_product": "whatsapp" } } ], "id": "{phone-number-id}" } ], "object": "whatsapp_business_account" } -
La empresa podrá dar por terminada la llamada invocando la**/llamadas**API con el siguiente cuerpo de solicitud
POST {phone-number-id}/calls{ "messaging_product": "whatsapp", "call_id": "wacid.ABGGFjFVU2AfAgo6V", "action" : "terminate" } -
La empresa recibirá la siguiente respuesta.
{ "success": true } -
La empresa eventualmente recibirá el webhook de finalización una vez que se haya desconectado la llamada o si la llamada fue desconectada por el consumidor de WhatsApp.
{ "object": "whatsapp_business_account", "entry": [ { "id": "{phone-number-id}", "changes": [ { "value": { "messaging_product": "whatsapp", "metadata": { "display_phone_number": "{phone-number}", "phone_number_id": "{phone-number-id}" }, "calls": [ { "id": "wacid.ABGGFjFVU2AfAgo6V-Hc5eCgK5Gh", "to": "{c-phone-number}", "from": "{phone-number}", "event": "terminate", "direction": "BUSINESS_INITIATED", "timestamp": "1671644824", "status": "FAILED", // [Failed | Completed] "start_time": "1671644824", "end_time": "1671644944", "duration": 120 } ] }, "field": "calls" } ] } ] }
Mejores Prácticas de Integración
Problema y solución de recorte de audio
Si estás conectando el segmento de medios del consumidor de WhatsApp que llega a través de WebRTC, por ejemplo, a otro segmento de medios como SIP, ten en cuenta los posibles problemas de recorte de audio y cómo evitarlos. Una manifestación común de este problema es que el consumidor de WhatsApp que llama pierde aproximadamente un segundo del negocio. Por ejemplo, si un IVR imaginario está reproduciendo 1-2-3…, el consumidor puede escuchar solo desde el 2 o 3. La duración de la pérdida de audio depende de la integración específica y de la gravedad del problema.
El siguiente diagrama de secuencia ilustra el problema tomando un ejemplo donde el segmento WebRTC de la API en la nube se conecta con un segmento de medios SIP. Dependiendo del proveedor de SIP y la implementación utilizada, los medios del Agente de Usuario SIP pueden reproducirse desde el paso 11, pero no podrán llegar al consumidor de WhatsApp hasta el paso 18.
Componentes del diagrama de secuencia
- Consumidor de WA es un usuario de WhatsApp que llama al número de teléfono de la empresa utilizando la aplicación móvil de WhatsApp.
- Meta es el producto de la API en la nube.
- Endpoint de MetaWebrtc es el agente WebRTC en la infraestructura de Meta.
- Integración empresarial es el servidor webhook que recibe webhooks relacionados con llamadas y el servidor de aplicaciones con lógica de negocio para invocar las API de Graph de la API en la nube.
- Endpoint de BizWebrtc es el punto de terminación WebRTC, así como el UAC SIP, típicamente en un servidor de medios de tu lado.
- Endpoint de BizSip es el Agente de Usuario SIP (UA), que a menudo representa un IVR o un Agente de Negocios.
Causa raíz Cuando un servidor de medios está conectando dos segmentos de medios, necesita asegurarse de que ambos segmentos están aproximadamente listos al mismo tiempo para evitar el recorte de audio. En este caso, BizWebrtcEndpoint está permitiendo que el UA SIP envíe medios mucho antes de que el segmento WebRTC esté listo. Por lo tanto, los paquetes se descartan (en el servidor de medios de tu lado) causando el recorte de audio.
Solución sugerida Según la recomendación del RFC, un agente WebRTC (es decir, BizWebrtcEndpoint) no debe transmitir medios hasta que el proceso ICE esté casi completo. En nuestro caso, esto se traduce en emplear un enfoque de ‘aceptación optimista’ donde invocas la llamada a la API de Graph de Pre-aceptación incluso antes de enviar el INVITE SIP. Según los RFC de SIP, un UAC debe estar listo para recibir medios justo después de enviar el INVITE, por lo que es bueno iniciar el proceso de configuración de la conexión WebRTC antes del INVITE SIP.
La solución se ilustra en el siguiente diagrama de secuencia.
Puntos clave a tener en cuenta
- Al recibir el webhook de conexión (paso 5), inicializa tu agente WebRTC, prepara la respuesta SDP y llama a la API de Graph de pre-aceptación con la respuesta SDP. Esto permite que la conexión WebRTC se pre establezca en anticipación de una ‘aceptación/ok’ del UA SIP. En la mayoría de los casos, una llamada del consumidor es efectivamente respondida (por ejemplo, grabación automatizada o IVR).
- En el paso 11, espera a que el proceso ICE complete la creación de listas válidas que indiquen la casi finalización del establecimiento de la conexión ICE (referencia RFC).
- En caso de que el UA SIP rechace la llamada en lugar de enviar un 200 OK, llama a la API de Graph de terminación para finalizar la llamada.
- Si la conexión del consumidor está lista antes que la conexión SIP, el consumidor puede escuchar unos pocos milisegundos de silencio, lo cual es mejor que perder el audio inicial del negocio.
Otras posibles soluciones A continuación se presenta un resumen de alto nivel de otras alternativas para abordar el recorte de audio, destinadas simplemente a servir como ideas. Todas tienen desventajas obvias, pero puedes juzgar su viabilidad mejor bajo tus circunstancias específicas:
- Forzar al UA SIP a no reproducir audio hasta que reciba un ACK de BizWebrtcEndpoint, que se envía solo después de recibir una respuesta exitosa de la API de Aceptación más algún retraso artificial.
- Forzar al UA SIP a no reproducir audio hasta que detectes que el estado de la conexión WebRTC es ‘conectado’.
- Almacenar en búfer los paquetes de medios SIP y enviarlos al establecer la conexión WebRTC.
- Insertar silencio en el IVR antes del audio real.
Modelo de precios
Las llamadas se cobrarán en función de la duración de la llamada y de si son:
- Iniciadas por el usuario: Una llamada de consumidor a empresa (a partir del 1 de mayo de 2025, sin cargo para la empresa).
- Iniciadas por la empresa: Una llamada de empresa a consumidor.
Las tarifas de las llamadas varían según la dirección de la llamada y el código de país/región del número de teléfono del consumidor.
Las empresas solo podrán realizar llamadas iniciadas por la empresa o aceptar llamadas iniciadas por el usuario si tienen un método de pago válido adjunto.
Las estadísticas de llamadas de Analytics Graph API asociadas con su WABA estarán disponibles a través del endpoint de Graph API y la interfaz de usuario de WhatsApp Manager. El campo “call_analytics” proporciona información de costos, número de llamadas completadas y duración promedio de las llamadas para un WABA específico.Obtener información detallada de llamadas
| Descripción | Obtener información sobre llamadas |
|---|---|
| Endpoint | GET /{whatsapp-business-account-id}?fields=call_analytics .{filtering-parameters} &access_token={access-token} |
| Respuesta | { “call_analytics”: { “data”: [ { “data_points”: [ { “start”: 1676361600, “end”: 1676448000, “cost”: 10, “count”: 10, “average_duration”: 1 } ] } ] }, “id”: “114525791557199”} |
| Respuesta de error | { “error”: { “message”: “<Error Message>”, “type”: “<Exception Type>”, “code”: <Exception Code>, “fb_trace_id”: <Trace id> }} |
| Artículo | Tipo | Detalles |
|---|---|---|
| start | Entero | Requerido La fecha de inicio (unixtimestamp) para el rango de fechas para el que estás recuperando análisis. |
| end | Entero | Requerido La fecha de finalización (unixtimestamp) para el rango de fechas para el que está recuperando análisis. |
| granularity | Enumeración Opciones admitidas HALF_HOUR DAILY MONTHLY | Requerido La granularidad con la que desea recuperar los análisis. |
| country_codes | Cadena Formación | Opcional Los países de los que desea obtener análisis. Proporcione una matriz con los códigos de país de dos letras de los países que desea incluir. Si no se proporciona, se obtendrán análisis de todos los países a los que haya llamado. |
| phone_numbers | Cadena Matriz | Opcional Una lista de números de teléfono comerciales para los que desea obtener análisis. Si no se proporciona, se incluyen todos los números de teléfono agregados a su WABA. |
| metric_types | Enumeración Opciones admitidas COST COUNT AVERAGE_DURATION | Opcional Lista de métricas que desea recibir. Si envía una lista vacía, se mostrarán resultados para todos los tipos de métricas. COSTO:Costo calculado para la duración total de la llamada aplicando la tarjeta de tarifas basada en la dirección de la llamada y el código del país del consumidor CONTAR:Número total de llamadas completadas. DURACIÓN_PROMEDIO: Duración media de las llamadas completadas calculada por suma de la duración de las llamadas de todas las llamadas/recuento de las llamadas |
| directions | Enumeración Opciones admitidas USER_INITIATED BUSINESS_INITIATED | Opcional Lista de direcciones. Si envía una lista vacía, se mostrarán resultados para todas las direcciones de llamada. |
| dimensions | Enumeración Opciones admitidas DIRECTION COUNTRY PHONE | Opcional Lista de desgloses que desea aplicar a sus métricas. Si envía una lista vacía, devolvemos los resultados sin desgloses. |
Ejemplos
- Sólo parámetros obligatorios
| Endpoint | GET /calls/v21.0/{did}/analytics?fields=call_analytics .start(1643702400).end(1646121600) .granularity(MONTHLY) .phone_numbers([]) &Authorization={access-token} |
|---|---|
| Respuesta | { “call_analytics”: { “data”: [ { “data_points”: [ { “start”: 1676361600, “end”: 1676448000, “cost”: 10, “count”: 10, “average_duration”: 1 } ] } ] }, “id”: “114525791557199”} |
- Con averías
| Endpoint | GET /calls/v21.0/{did}/analytics?fields=call_analytics .start(1643702400).end(1646121600) .granularity(MONTHLY) .dimensions([DIRECTION]) &Authorization={access-token} |
|---|---|
| Respuesta | {“call_analytics”: { “data”: [ { “data_points”: [ { “start”: 1676361600, “end”: 1676448000, “direction”:“USER_INITIATED”, “cost”: 0.6, “count”: 5, “average_duration”: 1 }, { “start”: 1676361600, “end”: 1676448000, “direction”: “BUSINESS_INITIATED”, “cost”: 0.4, “count”: 5, “average_duration”: 1 } ] } ] }, “id”: “114525791557199”} |
Base de URL: https://channels.chattigo.com/bsp-cloud-chattigo-isv
Especificaciones SIP
PRECAUCIÓN: Al habilitar SIP en un número de teléfono comercial, no recibirá webhooks relacionados con llamadas y no podrá utilizar las API de Graph relacionadas con llamadas, como realizar o aceptar llamadas. En otras palabras, un número determinado puede usar las API de Graph/Webhooks para señalización o SIP para señalización, pero no ambas.
Requisitos previos
- Su aplicación debe estar habilitada para llamadas, lo que requiere que firme el contrato Beta.
- Su aplicación debe tener permisos de mensajería en el número de teléfono comercial. La mejor manera es probar el envío/recepción de mensajes utilizando las API de Graph regulares y usar la misma aplicación para configurar su servidor SIP en el número de teléfono comercial para llamadas.
- El modo de su aplicación debe ser “En vivo” (NO “En desarrollo”).
Pasos para llamadas iniciadas por el usuario
- Puede habilitar SIP en sus números de teléfono. Consulte la sección Habilitar SIP para obtener más detalles.
- Llame al número habilitado para SIP desde cualquier teléfono de consumidor de WhatsApp y Meta enviará un INVITACIÓN SIP al servidor SIP configurado.
- Responda con SIP OK con respuesta SDP o desafíe el INVITE SIP de Meta si desea usar autenticación digest para seguridad adicional.
Pasos para llamadas iniciadas por la empresa
- Puede habilitar SIP en sus números de teléfono. Consulte la sección Habilitar SIP para obtener más detalles.
- Este paso no es necesario si ya habilitó SIP como se mencionó en la sección de llamadas iniciadas por el usuario.
- Meta genera una contraseña de usuario SIP única para cada combinación de número de teléfono comercial + aplicación. Puede recuperar esta contraseña utilizando la API GET /configuraciones.
- Envíe el INVITE SIP al número de usuario de WhatsApp. Consulte INVITACIÓN SIP para llamadas iniciadas por la empresa para ver un ejemplo.
- Asegúrese de cumplir con todos estos requisitos para una llamada iniciada por la empresa exitosa.
Requisitos previos para llamadas iniciadas por la empresa
- Soporte para autenticación digest. Su primer INVITE SIP a Meta fallará con SIP 407 Proxy Authentication required. Debe enviar un segundo INVITE SIP con el encabezado de autorización adecuado según RFC.
- El atributo de nombre de usuario del campo de autorización debe coincidir con el nombre de usuario del encabezado “from”, que es el número de teléfono comercial.
- La contraseña es generada por Meta y puede recuperarla utilizando la API GET /configuraciones.
- La parte del nombre de usuario del encabezado “from” debe ser el número de teléfono comercial completamente normalizado.
- El nombre de dominio del encabezado “from” debe coincidir con el servidor SIP que se configuró en el número de teléfono comercial.
- Tiene la aprobación de permiso de llamada requerida del usuario de WhatsApp. Consulte Obtención de permiso de llamada para obtener más detalles.
- La oferta SDP que incluye es compatible con ICE, DTLS-SRTP y OPUS, que es esencialmente medios WebRTC.
API de configuración
Configurar los ajustes SIP
| Descripción | Actualizar la configuración de llamadas de un número de teléfono |
|---|---|
| Endpoint | POST calls/v21.0/{did}/settings |
| Cuerpo de la solicitud | { “calling”: { “status”: “ENABLED”, // … other fields omitted for brevity “sip”: { “status”: “ENABLED |
| Respuesta | { “success”: true } |
| Respuesta de error | { “error”: { “message”: “<Error Message>”, “type”: “<Exception Type>”, “code”: <Exception Code>, “fbtrace_id”: “<Trace ID>” } } |
| Campos | Parámetros anidados bajo el nodo “llamante”: sip.status: el valor predeterminado es DISABLED. Cuando está ENABLED, este número de teléfono usa exclusivamente SIP para señalización y no funciona con las API Graph ni envía webhooks. Cuando el estado está DISABLED, los servidores SIP no se restablecen. Al volver a habilitar SIP, se aplicarán los servidores SIP configurados previamente. Puede configurar el estado y los servidores SIP en la misma solicitud. sip.servers: una aplicación puede configurar como máximo un servidor SIP. Un número de teléfono puede tener varios servidores SIP, uno por aplicación. Para eliminar un servidor SIP previamente configurado, especifique este campo con una matriz vacía. La aplicación asociada se extrae del token de acceso utilizado para realizar la llamada a la API. sip.server.hostname: nombre de host de su servidor SIP para enviar solicitudes SIP mediante TLS. En el futuro, podríamos permitir la anulación de parámetros de consulta y encabezados. Tenga en cuenta que este servidor SIP está asociado con la aplicación que realiza esta solicitud API. sip.server.port: puerto de su servidor SIP para enviar solicitudes SIP mediante TLS. El puerto predeterminado es 5061. sip.server.request_uri_user_params: campo opcional que indica los parámetros que Meta debe incluir en la sección de usuario de la URI de solicitud utilizada en nuestra invitación SIP a este servidor. Un ejemplo de caso de uso son los grupos troncales (RFC 4904). Ej: sip:+1234567890@sip.example.com;tgrp=wacall;trunk-context=byoc.example.com tiene dos parámetros de usuario tgrp y trunk-context El tamaño de la clave o valor está limitado a 128 caracteres. |
| Consideraciones especiales | Tenga en cuenta que una PN puede ser operada por varias aplicaciones ante la próxima función MSC (Conversación Multisolución). En estos casos, analizamos el estado general de SIP del número de teléfono. Si SIP está habilitado, solo analizamos los servidores SIP configurados (por cualquier aplicación) para este número y no las suscripciones a webhooks de ninguna aplicación. Esto significa que, si una PN es administrada por, por ejemplo, dos socios P1 y P2, y uno de ellos decide habilitar SIP en el número, ambos deben usar SIP para recibir notificaciones sobre las llamadas. En el futuro, podríamos ofrecer este escenario híbrido: P1 recibe notificaciones mediante SIP y P2 mediante webhooks para que un socio no pueda afectar a los demás. |
| Permisos de la aplicación | gestión empresarial de whatsapp Se requiere acceso avanzado para utilizar la API en nombre de las empresas finales. |
Habilitar SIP (teléfono comercial)
A continuación se muestra un ejemplo de solicitud curl basada en configurar la API de ajustes SIP.
curl -X POST \
https://graph.facebook.com/v18.0/{PHONE_NUMBER_ID}/settings \
-H 'Authorization: Bearer {ACCESS_TOEN} \
-H 'Content-Type: application/json' \
-d '
{
"calling": {
"status": "ENABLED",
"sip": {
"status": "ENABLED",
"servers": [{
"hostname": "{SIP_SERVER_URL}"
}],
}
}
}'
Obtener la configuración SIP
Nota: La contraseña del usuario SIP se incluye solo si menciona explícitamente el parámetro de consulta include_sip_credentials
curl https://graph.facebook.com/v18.0/{PHONE_NUMBER_ID}/settings?include_sip_credentials=true \
-H 'Authorization: Bearer {ACCESS_TOEN}'
{
"calling": {
"status": "ENABLED",
"call_icon_visibility": "DEFAULT",
"callback_permission_status": "ENABLED",
"sip": {
"status": "ENABLED",
"servers": [
{
"hostname": "sip.example.com",
"sip_user_password": "{SIP_USER_PASSWORD}"
}
]
}
}
}
Resolución de problemas
Validar el certificado TLS
| Ejemplo de certificado válido $ openssl s_client -quiet -verify_hostname meta-voip.example.com -connect meta-voip.example.com:5061 Connecting to 64:ff9b::68f8:b0b8 depth=2 C=US, ST=New Jersey, L=Jersey City, O=The USERTRUST Network, CN=USERTrust RSA Certification Authority verify return:1 depth=1 C=AT, O=ZeroSSL, CN=ZeroSSL RSA Domain Secure Site CA verify return:1 depth=0 CN=example.com verify return:1 |
|---|
| Ejemplo de certificado no válido $ openssl s_client -quiet -verify_hostname meta-inb.byoc.mypurecloud.com -connect meta-inb.byoc.mypurecloud.com:5061 Connecting to 64:ff9b::3652:f1c0 depth=0 jurisdictionC=US, jurisdictionST=California, businessCategory=Private Organization, serialNumber=1515861, C=US, ST=Indiana, L=Indianapolis, O=Genesys Cloud Services, Inc., CN=voice.mypurecloud.com verify error:num=62:hostname mismatch verify return:1 depth=2 C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert High Assurance EV Root CA verify return:1 depth=1 C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert SHA2 Extended Validation Server CA verify return:1 depth=0 jurisdictionC=US, jurisdictionST=California, businessCategory=Private Organization, serialNumber=1515861, C=US, ST=Indiana, L=Indianapolis, O=Genesys Cloud Services, Inc., CN=voice.mypurecloud.com verify return:1 $ |
Validación de la certificación
Si utiliza Genesys BYOC, existe una forma específica de configurar el nombre de host del servidor SIP para evitar problemas de validación del nombre del sujeto. Consulte la sección Validación del nombre del sujeto
La siguiente tabla ilustra una forma de solucionar este problema.
Si lo haces de esta manera, fallará la validación de la certificación SIP TLS, por lo que no recibirás tráfico SIP de Meta
curl https://graph.facebook.com/v18.0/{PHONE_NUMBER_ID}/settings?include_sip_credentials=true \ -H 'Authorization: Bearer {ACCESS_TOEN}'
{
"calling": {
"status": "ENABLED",
"call_icon_visibility": "DEFAULT",
"callback_permission_status": "ENABLED",
"sip": {
"status": "ENABLED",
"servers": [
{
"hostname": "meta-wa.byoc.mypurecloud.com"
}
]
}
}
}
Asegúrese de actualizar los valores reales para que reflejen su entorno. Este es solo un ejemplo ilustrativo.
curl https://graph.facebook.com/v18.0/{PHONE_NUMBER_ID}/settings?include_sip_credentials=true \ -H 'Authorization: Bearer {ACCESS_TOEN}'
{
"calling": {
"status": "ENABLED",
"call_icon_visibility": "DEFAULT",
"callback_permission_status": "ENABLED",
"sip": {
"status": "ENABLED",
"servers": [
{
"hostname": "lb01.voice.use1.pure.cloud",
"request_uri_user_params": {
"tgrp": "meta-wa",
"trunk-context": "byoc.mypurecloud.com"
}
}
]
}
}
}
Solicitudes SIP de muestra
INVITE WebRTC Media
INVITE sip:17015558857@meta-voip.example.com SIP/2.0
Via: SIP/2.0/TLS [2803:6080:e888:51aa:d4a4:c5e0:300:0]:33819;
rport=33819;received=2803:6080:e888:51aa:d4a4:c5e0:300:0;
branch=z9hG4bKPjNvs.IZBnUa1W4l8oHPpk3SUMmcx3MMcE;alias
Max-Forwards: 70
From: "12195550714" <sip:12195550714@wa.meta.vc>;
tag=bbf1ad6e-79bb-4d9c-8a2c-094168a10bea
To: <sip:17015558857@meta-voip.example.com>
Contact: \<sip:12195550714@wa.meta.vc;transport=tls;ob\>;isfocus
Call-ID: outgoing:wacid.HBgLMTIxOTU1NTA3MTQVAgASGCAzODg1NTE5NEU1NTBEMTc1RTFFQUY5NjNCQ0FCRkEzRhwYCzE3MDE1NTU4ODU3FQIAAA== CSeq: 2824
INVITE Route: \<sip:onevc-sip-proxy-dev.fbinfra.net:8191;transport=tls;lr\> X-FB-External-Domain: wa.meta.vc Allow: INVITE, ACK, BYE, CANCEL, NOTIFY, OPTIONS
User-Agent: Facebook SipGateway
Content-Type: application/sdp
Content-Length: 1028
v=0
o=- 1741113186367 2 IN IP4 127.0.0.1
s=-
t=0 0
a=group:BUNDLE audio
a=msid-semantic: WMS 632a909f-1060-4369-96a4-7bd03e291ee7
a=ice-lite
m=audio 3480 UDP/TLS/RTP/SAVPF 111 126
c=IN IP4 57.144.135.35
a=rtcp:9 IN IP4 0.0.0.0
a=candidate:1775469887 1 udp 2122260223 57.144.135.35 3480 typ host generation 0 network-cost 50
a=candidate:3355715111 1 udp 2122262783 2a03:2880:f343:131:face:b00c:0:699c 3480 typ host generation 0 network-cost 50
a=ice-ufrag:RmDDkfzkwbexPfbC
a=ice-pwd:*************************
a=fingerprint:********************************************************************************************************
a=setup:actpass
a=mid:audio
a=sendrecv
a=msid:632a909f-1060-4369-96a4-7bd03e291ee7 WhatsAppTrack1
a=rtcp-mux
a=rtpmap:111 opus/48000/2
a=rtcp-fb:111 transport-cc
a=fmtp:111 maxaveragebitrate=20000;maxplaybackrate=16000;minptime=20;sprop-maxcapturerate=16000;useinbandfec=1
a=rtpmap:126 telephone-event/8000
a=maxptime:20
a=ptime:20
a=ssrc:849255537 cname:WhatsAppAudioStream1
a=rtcp:9 IN IP4 0.0.0.0
a=candidate:1775469887 1 udp 2122260223 57.144.135.35 3480 typ host generation 0 network-cost 50
a=candidate:3355715111 1 udp 2122262783 2a03:2880:f343:131:face:b00c:0:699c 3480 typ host generation 0 network-cost 50
a=ice-ufrag:RmDDkfzkwbexPfbC
a=ice-pwd:*************************
a=fingerprint:********************************************************************************************************
a=setup:actpass
a=mid:audio
a=sendrecv
a=msid:632a909f-1060-4369-96a4-7bd03e291ee7 WhatsAppTrack1
a=rtcp-mux
a=rtpmap:111 opus/48000/2
a=rtcp-fb:111 transport-cc
a=fmtp:111 maxaveragebitrate=20000;maxplaybackrate=16000;minptime=20;sprop-maxcapturerate=16000;useinbandfec=1
a=rtpmap:126 telephone-event/8000
a=maxptime:20
a=ptime:20
a=ssrc:849255537 cname:WhatsAppAudioStream1
INVITE (Autenticación Digest)
El servidor SIP de Meta admite la autenticación implícita para llamadas iniciadas por el usuario. Su servidor SIP debería responder con un desafío de autenticación implícita y Meta reenviará la invitación SIP con la respuesta.
Primera solicitud de INVITACIÓN
INVITE sip:+12145551869@meta-voip.example.com;transport=tls SIP/2.0
Via: SIP/2.0/TLS [2803:6080:f948:9597::]:47237;rport;branch=z9hG4bKPj1e6c665db16b3ecacf32cadb4497fe77;alias
Record-Route: <sip:wa.meta.vc;transport=tls;lr>
Record-Route: <sip:onevc-sip-proxy.fbinfra.net:8191;transport=tls;lr>
Via: SIP/2.0/TLS [2803:6080:f948:9597:7253:922a:400:0]:5061;branch=z9hG4bKPj1e6c665db16b3ecacf32cadb4497fe77
Via: SIP/2.0/TLS [2803:6080:f8bc:9272:e488:9927:400:0]:58279;rport=58279;received=2803:6080:f8bc:9272:e488:9927:400:0;branch=z9hG4bKPjr33j97A1mx5J8HWHEy2zIgqZYCCIb4Fb;alias
Max-Forwards: 69
From: "12195550714" <sip:+12195550714@wa.meta.vc>;tag=ece2da15-39e7-4983-ac65-e312f325d94a
To: <sip:+12145551869@meta-voip.example.com>
Contact: <sip:+12195550714@wa.meta.vc;transport=tls;ob>;isfocus
Call-ID: outgoing:wacid.HBgLMTIxOTU1NTA3MTQVAgASGCA2MUI2QUY0MDRCMTUyOTM4QkE5ODEwN0ZGQTAwODkxORwYCzEyMTQ1NTUxODY5FQIAFRoA
CSeq: 9989 INVITE
X-FB-External-Domain: wa.meta.vc
Allow: INVITE, ACK, BYE, CANCEL, NOTIFY, OPTIONS
User-Agent: Facebook SipGateway
Content-Type: application/sdp
Content-Length: 643
v=0
o=- 1750716867913 2 IN IP4 127.0.0.1
s=-
t=0 0
a=group:BUNDLE audio
a=msid-semantic: WMS 4e37b099-8aef-45d0-be4f-1cde2ca5a37d
m=audio 3480 RTP/SAVP 111 126
c=IN IP4 57.144.219.49
a=rtcp:9 IN IP4 0.0.0.0
a=mid:audio
a=sendrecv
a=msid:4e37b099-8aef-45d0-be4f-1cde2ca5a37d WhatsAppTrack1
a=rtcp-mux
a=crypto:**************************************************************************
a=rtpmap:111 opus/48000/2
a=fmtp:111 maxaveragebitrate=20000;maxplaybackrate=16000;minptime=20;sprop-maxcapturerate=16000;useinbandfec=1
a=rtpmap:126 telephone-event/8000
a=maxptime:20
a=ptime:20
a=ssrc:215879358 cname:WhatsAppAudioStream1
Respuesta 407 del servidor SIP del socio
SIP/2.0 407 Proxy Authentication required
CSeq: 9989 INVITE
Call-ID: outgoing:wacid.HBgLMTIxOTU1NTA3MTQVAgASGCA2MUI2QUY0MDRCMTUyOTM4QkE5ODEwN0ZGQTAwODkxORwYCzEyMTQ1NTUxODY5FQIAFRoA
From: "12195550714" <sip:+12195550714@wa.meta.vc>;tag=ece2da15-39e7-4983-ac65-e312f325d94a
To: <sip:+12145551869@meta-voip.example.com>;tag=45065608_c3356d0b_16001fd8-76d2-45f0-bb35-e0441d6dc4a2
Via: SIP/2.0/TLS 31.13.66.215:5061;rport=62080;received=69.171.251.112;branch=z9hG4bKPj1e6c665db16b3ecacf32cadb4497fe77;alias
Via: SIP/2.0/TLS [2803:6080:f948:9597:7253:922a:400:0]:5061;branch=z9hG4bKPj1e6c665db16b3ecacf32cadb4497fe77
Via: SIP/2.0/TLS [2803:6080:f8bc:9272:e488:9927:400:0]:58279;rport=58279;received=2803:6080:f8bc:9272:e488:9927:400:0;branch=z9hG4bKPjr33j97A1mx5J8HWHEy2zIgqZYCCIb4Fb;alias
Contact: <sip:172.25.58.54:5060>
Proxy-Authenticate: Digest realm="sip.twilio.com",nonce="eyOam_8-l5FVugxsyxFRjnlxq9vy1TjQIMB3mBfJuAvB5gV4",opaque="4a6a068be2ca2032a57912b9a2a6adf7",qop="auth"
Content-Length: 0
Content-Length: 0
Segunda INVITACIÓN con autorización de Meta
INVITE sip:+12145551869@meta-voip.example.com;transport=tls SIP/2.0
Via: SIP/2.0/TLS 31.13.66.215:5061;rport;branch=z9hG4bKPj16be0694dc6763eb66de5ec5f262db03;alias
Record-Route: <sip:wa.meta.vc;transport=tls;lr>
Record-Route: <sip:onevc-sip-proxy.fbinfra.net:8191;transport=tls;lr>
Via: SIP/2.0/TLS [2803:6080:f948:9597:7253:922a:400:0]:5061;branch=z9hG4bKPj16be0694dc6763eb66de5ec5f262db03
Via: SIP/2.0/TLS [2803:6080:f8bc:9272:e488:9927:400:0]:58279;rport=58279;received=2803:6080:f8bc:9272:e488:9927:400:0;branch=z9hG4bKPjYp9LqI0D8zJ.wly5wyMyVaH9fUwIU921;alias
Max-Forwards: 69
From: "12195550714" <sip:+12195550714@wa.meta.vc>;tag=ece2da15-39e7-4983-ac65-e312f325d94a
To: <sip:+12145551869@meta-voip.example.com>
Contact: <sip:+12195550714@wa.meta.vc;transport=tls;ob>;isfocus
Call-ID: outgoing:wacid.HBgLMTIxOTU1NTA3MTQVAgASGCA2MUI2QUY0MDRCMTUyOTM4QkE5ODEwN0ZGQTAwODkxORwYCzEyMTQ1NTUxODY5FQIAFRoA
CSeq: 9990 INVITE
X-FB-External-Domain: wa.meta.vc
Allow: INVITE, ACK, BYE, CANCEL, NOTIFY, OPTIONS
User-Agent: Facebook SipGateway
Proxy-Authorization: Digest username="12145551869", realm="sip.twilio.com", nonce="eyOam_8-l5FVugxsyxFRjnlxq9vy1TjQIMB3mBfJuAvB5gV4", uri="sip:+12145551869@meta-voip.example.com", response="b28ed6b8bf1418e3c6eca05ef8c7a0b1", cnonce="TY2SszvYCKitUCBlVLpGiPKMQfmBbj", opaque="4a6a068be2ca2032a57912b9a2a6adf7", qop=auth, nc=00000001
Content-Type: application/sdp
Content-Length: 643
v=0
o=- 1750716867913 2 IN IP4 127.0.0.1
s=-
t=0 0
a=group:BUNDLE audio
a=msid-semantic: WMS 4e37b099-8aef-45d0-be4f-1cde2ca5a37d
m=audio 3480 RTP/SAVP 111 126
c=IN IP4 57.144.219.49
a=rtcp:9 IN IP4 0.0.0.0
a=mid:audio
a=sendrecv
a=msid:4e37b099-8aef-45d0-be4f-1cde2ca5a37d WhatsAppTrack1
a=rtcp-mux
a=crypto:**************************************************************************
a=rtpmap:111 opus/48000/2
a=fmtp:111 maxaveragebitrate=20000;maxplaybackrate=16000;minptime=20;sprop-maxcapturerate=16000;useinbandfec=1
a=rtpmap:126 telephone-event/8000
a=maxptime:20
a=ptime:20
a=ssrc:215879358 cname:WhatsAppAudioStream1
OK del servidor SIP del socio
SIP/2.0 200 OK
CSeq: 9990 INVITE
Call-ID: outgoing:wacid.HBgLMTIxOTU1NTA3MTQVAgASGCA2MUI2QUY0MDRCMTUyOTM4QkE5ODEwN0ZGQTAwODkxORwYCzEyMTQ1NTUxODY5FQIAFRoA
From: "12195550714" <sip:+12195550714@wa.meta.vc>;tag=ece2da15-39e7-4983-ac65-e312f325d94a
To: <sip:+12145551869@meta-voip.example.com>;tag=29360930_c3356d0b_4933dc58-f035-4597-b075-04b19e552329
Via: SIP/2.0/TLS 31.13.66.215:5061;rport=62080;received=69.171.251.112;branch=z9hG4bKPj16be0694dc6763eb66de5ec5f262db03;alias
Via: SIP/2.0/TLS [2803:6080:f948:9597:7253:922a:400:0]:5061;branch=z9hG4bKPj16be0694dc6763eb66de5ec5f262db03
Via: SIP/2.0/TLS [2803:6080:f8bc:9272:e488:9927:400:0]:58279;rport=58279;received=2803:6080:f8bc:9272:e488:9927:400:0;branch=z9hG4bKPjYp9LqI0D8zJ.wly5wyMyVaH9fUwIU921;alias
Record-Route: <sip:54.172.60.0:5060;lr;r2=on;twnat=sip:69.171.251.112:62080>
Record-Route: <sip:54.172.60.0:5061;transport=tls;lr;r2=on;twnat=sip:69.171.251.112:62080>
Record-Route: <sip:wa.meta.vc;transport=tls;lr>
Record-Route: <sip:onevc-sip-proxy.fbinfra.net:8191;transport=tls;lr>
Contact: <sip:172.25.43.84:5060>
Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY
Content-Type: application/sdp
X-Twilio-CallSid: CAd4d6e59a356c4d1b0ee85323b2d9dab5
Content-Length: 444
Content-Type: application/sdp
Content-Length: 444
v=0
o=root 477560318 477560318 IN IP4 172.18.156.61
s=Twilio Media Gateway
c=IN IP4 168.86.137.174
t=0 0
m=audio 12710 RTP/SAVP 111 126
a=rtpmap:111 opus/48000/2
a=fmtp:111 maxplaybackrate=16000;sprop-maxcapturerate=16000;maxaveragebitrate=20000;useinbandfec=1
a=rtpmap:126 telephone-event/8000
a=fmtp:126 0-16
a=crypto:**************************************************************************
a=ptime:20
a=maxptime:20
a=sendrecv
INVITE Iniciadas por empresa
Primera solicitud de INVITACIÓN
INVITE sip:12195550714@wa.meta.vc;transport=tls SIP/2.0e
Record-Route: <sip:159.65.244.171:5061;transport=tls;lr;ftag=Kc9QZg4496maQ;nat=yes>
Via: SIP/2.0/TLS 159.65.244.171:5061;received=2803:6081:798c:93f8:5f9b:bfe8:300:0;branch=z9hG4bK0da2.36614b8977461b486ceabc004c723476.0;i=617261
Via: SIP/2.0/TLS 137.184.87.1:35181;rport=56533;received=137.184.87.1;branch=z9hG4bKQNa6meey5Dj2g
Max-Forwards: 69
From: <sip:17125550259@meta-voip.example.com>;tag=Kc9QZg4496maQ
To: <sip:12195550714@wa.meta.vc>
Call-ID: dc2c5b33-1b81-43ee-9213-afb56f4e56ba
CSeq: 96743476 INVITE
Contact: <sip:mod_sofia@137.184.87.1:35181;transport=tls;swrad=137.184.87.1~56533~3>
User-Agent: SignalWire
Allow: INVITE, ACK, BYE, CANCEL, OPTIONS, MESSAGE, INFO, UPDATE, REGISTER, REFER, NOTIFY
Supported: timer, path, replaces
Allow-Events: talk, hold, conference, refer
Session-Expires: 600;refresher=uac
Min-SE: 90
Content-Type: application/sdp
Content-Disposition: session
Content-Length: 2427
X-Relay-Call-ID: dc2c5b33-1b81-43ee-9213-afb56f4e56ba
Remote-Party-ID: <sip:17125550259@meta-voip.example.com>;party=calling;screen=yes;privacy=off
Content-Type: application/sdp
Content-Length: 2427
<<SDP omitted for brevity>>
Respuesta 407 de Meta
SIP/2.0 407 Proxy Authentication Required
Via: SIP/2.0/TLS 159.65.244.171:5061;received=2803:6081:798c:93f8:5f9b:bfe8:300:0;branch=z9hG4bK0da2.36614b8977461b486ceabc004c723476.0;i=617261
Via: SIP/2.0/TLS 137.184.87.1:35181;rport=56533;received=137.184.87.1;branch=z9hG4bKQNa6meey5Dj2g
Record-Route: <sip:159.65.244.171:5061;transport=tls;lr;ftag=Kc9QZg4496maQ;nat=yes>
Call-ID: dc2c5b33-1b81-43ee-9213-afb56f4e56ba
From: <sip:17125550259@meta-voip.example.com>;tag=Kc9QZg4496maQ
To: <sip:12195550714@wa.meta.vc>;tag=z9hG4bK0da2.36614b8977461b486ceabc004c723476.0
CSeq: 96743476 INVITE
Proxy-Authenticate: Digest realm="wa.meta.vc",nonce="419ac2415577f8e1",opaque="440badfc05072367",algorithm=MD5,qop="auth"
Content-Length: 0
Segunda INVITACIÓN con autorización
INVITE sip:12195550714@wa.meta.vc;transport=tls SIP/2.0
Record-Route: <sip:159.65.244.171:5061;transport=tls;lr;ftag=Kc9QZg4496maQ;nat=yes>
Via: SIP/2.0/TLS 159.65.244.171:5061;received=2803:6081:798c:93f8:5f9b:bfe8:300:0;branch=z9hG4bK1da2.ed8900012befced853927008d619d374.0;i=617261
Via: SIP/2.0/TLS 137.184.87.1:35181;rport=56533;received=137.184.87.1;branch=z9hG4bKry3yp9y12p8mc
Max-Forwards: 69
From: <sip:17125550259@meta-voip.example.com>;tag=Kc9QZg4496maQ
To: <sip:12195550714@wa.meta.vc>
Call-ID: dc2c5b33-1b81-43ee-9213-afb56f4e56ba
CSeq: 96743477 INVITE
Contact: <sip:mod_sofia@137.184.87.1:35181;transport=tls;swrad=137.184.87.1~56533~3>
User-Agent: SignalWire
Allow: INVITE, ACK, BYE, CANCEL, OPTIONS, MESSAGE, INFO, UPDATE, REGISTER, REFER, NOTIFY
Supported: timer, path, replaces
Allow-Events: talk, hold, conference, refer
Proxy-Authorization: Digest username="17125550259", realm="wa.meta.vc", nonce="419ac2415577f8e1", uri="sip:12195550714@wa.meta.vc;transport=tls", response="blah", algorithm=MD5, cnonce="/mVZtYFCEj65YQJCrBEAAg", opaque="440badfc05072367", qop=auth, nc=00000001
Session-Expires: 600;refresher=uac
Min-SE: 90
Content-Type: application/sdp
Content-Disposition: session
Content-Length: 2427
X-Relay-Call-ID: dc2c5b33-1b81-43ee-9213-afb56f4e56ba
Remote-Party-ID: <sip:17125550259@meta-voip.example.com>;party=calling;screen=yes;privacy=off
Content-Type: application/sdp
Content-Length: 2427
<<SDP omitted for brevity>>
Ejemplo de respuesta de error de Meta
SIP/2.0 403 SIP server wa.meta.vc from INVITE does not match any SIP server configured for phone number id {ID}
Via: SIP/2.0/TLS [2803:6080:c954:b533:ecfb:5cec:300:0]:39459;rport=39459;received=2803:6080:c954:b533:ecfb:5cec:300:0;branch=z9hG4bKPjf9f3d0bddb3dbe0c9b1e3b486f39784a;alias
Via: SIP/2.0/TLS 148.72.155.236:5061;rport=30498;received=2803:6080:d014:8e40:ddbb:4ed7:300:0;branch=z9hG4bKPjfd270ec8-7aaf-4a65-b290-4bef3b50b7b7;alias
Record-Route: <sip:onevc-sip-proxy-dev.fbinfra.net:8191;transport=tls;lr>
Record-Route: <sip:wa.meta.vc;transport=tls;lr>
Call-ID: 91578781-44f1-4268-9a7f-d7efec1abf72
From: <sip:17125550259@wa.meta.vc>;tag=3a63b370-a697-4a5a-82b4-e8105e23f176
To: <sip:12195550714@wa.meta.vc>;tag=e0d30a05-657b-47ec-a668-e05ca79f9f05
CSeq: 15659 INVITE
Allow: INVITE, ACK, BYE, CANCEL, NOTIFY, OPTIONS
X-FB-External-Domain: wa.meta.vc
Warning: 399 wa.meta.vc "SIP server wa.meta.vc from INVITE does not match any SIP server configured for phone number id {ID}"
Content-Length: 0
Content-Length: 0
BYE del socio (lo mismo para llamadas iniciadas por el usuario o la empresa)
BYE sip:+5559800000693@wa.meta.vc;transport=tls;ob SIP/2.0
Via: SIP/2.0/TLS 137.184.4.155:5061;received=2803:6080:c074:cac:10ed:4b05:400:0;i=8d2dc2
Via: SIP/2.0/TLS 143.198.136.243:35181;rport=38087;received=143.198.136.243
Route: <sip:wa.meta.vc;transport=tls;lr>
Route: <sip:onevc-sip-proxy.fbinfra.net:8191;transport=tls;lr>
Max-Forwards: 69
From: <sip:+12145551869@meta-voip.example.com>;tag=NcKQ6mtDKSDQB
To: "5559800000693" <sip:+5559800000693@wa.meta.vc>;tag=92a01092-ee78-4870-865f-bc176203a6bd
Call-ID: outgoing:wacid.HBgPMjAwNzU2OTA0ODY5OTY1FRIAEhggMjQ4QzUwOUQ1REQ0NDUwNENEQzRFMTgwRTNGQjAwNjEcGAsxMjE0NTU1MTg2ORUCAAA
CSeq: 98734935 BYE
User-Agent: SignalWire
Allow: INVITE, ACK, BYE, CANCEL, OPTIONS, MESSAGE, INFO, UPDATE, REGISTER, REFER, NOTIFY
Supported: timer, path, replaces
Reason: Q.850;cause=16;text="NORMAL_CLEARING"
Content-Length: 0
X-Relay-Call-ID: b72c0c65-e319-41b3-afb7-19ebcca05d38
Content-Length: 0
INVITE con SDES para llamadas iniciadas por el usuario
INVITE sip:+12145551869@meta-voip.example.com;transport=tls SIP/2.0
Via: SIP/2.0/TLS [2803:6080:f948:9597::]:57363;rport;branch=z9hG4bKPj3a9f2ad89e4a3df61408aa84f7d9a63e;alias
Record-Route: <sip:wa.meta.vc;transport=tls;lr>
Record-Route: <sip:onevc-sip-proxy.fbinfra.net:8191;transport=tls;lr>
Via: SIP/2.0/TLS [2803:6080:f948:9597:d33c:e00:400:0]:5061;branch=z9hG4bKPj3a9f2ad89e4a3df61408aa84f7d9a63e
Via: SIP/2.0/TLS [2803:6080:f948:9597:1ac5:cdf8:300:0]:63057;rport=63057;received=2803:6080:f948:9597:1ac5:cdf8:300:0;branch=z9hG4bKPj-phic0sbns27DiP0OlrxRxgLtNg4mio7;alias
Max-Forwards: 69
From: "12195550714" <sip:+12195550714@wa.meta.vc>;tag=8a0f7e65-6e9e-4801-bf92-85c3ef2485d9
To: <sip:+12145551869@meta-voip.example.com>
Contact: <sip:+12195550714@wa.meta.vc;transport=tls;ob>;isfocus
Call-ID: outgoing:wacid.HBgLMTIxOTU1NTA3MTQVAgASGCA4QkY1MTJCQkNFNTgxMEVFRERFRTUzNTFERkE1MDU0MhwYCzEyMTQ1NTUxODY5FQIAAA
CSeq: 31159 INVITE
X-FB-External-Domain: wa.meta.vc
Allow: INVITE, ACK, BYE, CANCEL, NOTIFY, OPTIONS
User-Agent: Facebook SipGateway
Content-Type: application/sdp
Content-Length: 645
v=0
o=- 1746659966980 2 IN IP4 127.0.0.1
s=-
t=0 0
a=group:BUNDLE audio
a=msid-semantic: WMS 07092115-d151-427e-8722-26c70936b104
m=audio 3480 RTP/SAVP 111 126
c=IN IP4 157.240.19.130
a=rtcp:9 IN IP4 0.0.0.0
a=mid:audio
a=sendrecv
a=msid:07092115-d151-427e-8722-26c70936b104 WhatsAppTrack1
a=rtcp-mux
a=crypto:**************************************************************************
a=rtpmap:111 opus/48000/2
a=fmtp:111 maxaveragebitrate=20000;maxplaybackrate=16000;minptime=20;sprop-maxcapturerate=16000;useinbandfec=1
a=rtpmap:126 telephone-event/8000
a=maxptime:20
a=ptime:20
a=ssrc:1615009994 cname:WhatsAppAudioStream1
OK con SDES para llamadas iniciadas por el usuario
SIP/2.0 200 OK
CSeq: 31159 INVITE
Call-ID: outgoing:wacid.HBgLMTIxOTU1NTA3MTQVAgASGCA4QkY1MTJCQkNFNTgxMEVFRERFRTUzNTFERkE1MDU0MhwYCzEyMTQ1NTUxODY5FQIAAA
From: "12195550714" <sip:+12195550714@wa.meta.vc>;tag=8a0f7e65-6e9e-4801-bf92-85c3ef2485d9
To: <sip:+12145551869@meta-voip.example.com>;tag=66596922_c3356d0b_fee164be-566a-4679-a80d-5bfdf1d0aa9e
Via: SIP/2.0/TLS 157.240.229.209:5061;rport=51830;received=69.171.251.115;branch=z9hG4bKPj3a9f2ad89e4a3df61408aa84f7d9a63e;alias
Via: SIP/2.0/TLS [2803:6080:f948:9597:d33c:e00:400:0]:5061;branch=z9hG4bKPj3a9f2ad89e4a3df61408aa84f7d9a63e
Via: SIP/2.0/TLS [2803:6080:f948:9597:1ac5:cdf8:300:0]:63057;rport=63057;received=2803:6080:f948:9597:1ac5:cdf8:300:0;branch=z9hG4bKPj-phic0sbns27DiP0OlrxRxgLtNg4mio7;alias
Record-Route: <sip:54.172.60.1:5060;lr;r2=on;twnat=sip:69.171.251.115:51830>
Record-Route: <sip:54.172.60.1:5061;transport=tls;lr;r2=on;twnat=sip:69.171.251.115:51830>
Record-Route: <sip:wa.meta.vc;transport=tls;lr>
Record-Route: <sip:onevc-sip-proxy.fbinfra.net:8191;transport=tls;lr>
Contact: <sip:172.25.16.223:5060>
Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY
Content-Type: application/sdp
X-Twilio-CallSid: CAb0d74508fe5fcdf6ec70ea3cf4e9b90b
Content-Length: 446
Content-Type: application/sdp
Content-Length: 446
v=0
o=root 1353670385 1353670385 IN IP4 172.18.164.24
s=Twilio Media Gateway
c=IN IP4 168.86.138.176
t=0 0
m=audio 15822 RTP/SAVP 111 126
a=rtpmap:111 opus/48000/2
a=fmtp:111 maxplaybackrate=16000;sprop-maxcapturerate=16000;maxaveragebitrate=20000;useinbandfec=1
a=rtpmap:126 telephone-event/8000
a=fmtp:126 0-16
a=crypto:**************************************************************************
a=ptime:20
a=maxptime:20
a=sendrecv
INVITE con SDES para llamadas iniciadas por empresas
INVITE sip:12195550714@wa.meta.vc;transport=tls SIP/2.0
Record-Route: <sip:54.172.60.1:5061;transport=tls;lr;r2=on>
Record-Route: <sip:54.172.60.1;lr;r2=on>
CSeq: 2 INVITE
From: "12145551869" <sip:12145551869@meta-voip.example.com>;tag=28460006_c3356d0b_5cdada8c-cbf0-4369-b02d-cc97d3c36f2b
To: <sip:12195550714@wa.meta.vc>
Max-Forwards: 66
P-Asserted-Identity: <sip:12145551869@meta-voip.example.com>
Min-SE: 120
Call-ID: f304a1d2cafb8139c1f9ff93a7733586@0.0.0.0
Contact: "12145551869" <sip:12145551869@172.25.10.217:5060;transport=udp>
Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY
Via: SIP/2.0/TLS 54.172.60.1:5061;received=2803:6080:f934:8894:7eb5:24f9:300:0;branch=z9hG4bK1e5a.0da2ace9cc912d9e5f2595ca4acb9847.0
Via: SIP/2.0/UDP 172.25.10.217:5060;rport=5060;branch=z9hG4bK5cdada8c-cbf0-4369-b02d-cc97d3c36f2b_c3356d0b_54-457463274351249162
Supported: timer
User-Agent: Example VoIP Gateway
Proxy-Authorization: Digest username="12145551869", realm="wa.meta.vc", nonce="2a487cb01d4ed43b", uri="sip:12195550714@wa.meta.vc;transport=tls", response="3f58df7af575b948625aeffd51bf9060", algorithm=MD5, cnonce="b338deb7f0e004e66353e26d34ad62b7", opaque="725a06fb2cd89a32", qop=auth, nc=00000002
Content-Type: application/sdp
X-Twilio-CallSid: CA93eac6be615da5e6836c7059e9555348
Content-Length: 422
Content-Type: application/sdp
Content-Length: 422
v=0
o=root 1185414872 1185414872 IN IP4 172.18.155.180
s=Twilio Media Gateway
c=IN IP4 168.86.138.232
t=0 0
m=audio 19534 RTP/SAVP 107 0 8 101
a=crypto:**************************************************************************
a=rtpmap:0 PCMU/8000
a=rtpmap:107 opus/48000/2
a=fmtp:107 useinbandfec=1
a=rtpmap:8 PCMA/8000
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-16
a=ptime:20
a=maxptime:20
a=sendrecv
OK con SDES para llamadas iniciadas por empresas
SIP/2.0 200 OK
Via: SIP/2.0/TLS 54.172.60.1:5061;received=2803:6080:f934:8894:7eb5:24f9:300:0;branch=z9hG4bK1e5a.0da2ace9cc912d9e5f2595ca4acb9847.0
Via: SIP/2.0/UDP 172.25.10.217:5060;rport=5060;branch=z9hG4bK5cdada8c-cbf0-4369-b02d-cc97d3c36f2b_c3356d0b_54-457463274351249162
Record-Route: <sip:onevc-sip-proxy.fbinfra.net:8191;transport=tls;lr>
Record-Route: <sip:wa.meta.vc;transport=tls;lr>
Record-Route: <sip:54.172.60.1:5061;transport=tls;lr;r2=on>
Record-Route: <sip:54.172.60.1;lr;r2=on>
Call-ID: f304a1d2cafb8139c1f9ff93a7733586@0.0.0.0
From: "12145551869" <sip:12145551869@meta-voip.example.com>;tag=28460006_c3356d0b_5cdada8c-cbf0-4369-b02d-cc97d3c36f2b
To: <sip:12195550714@wa.meta.vc>;tag=0d185053-2615-46c7-8ff2-250bda494cf1
CSeq: 2 INVITE
Allow: INVITE, ACK, BYE, CANCEL, NOTIFY, OPTIONS
Supported: timer
X-FB-External-Domain: wa.meta.vc
Contact: <sip:12195550714@wa.meta.vc;transport=tls;ob;X-FB-Sip-Smc-Tier=collaboration.sip_gateway.sip.prod>;isfocus
Content-Type: application/sdp
Content-Length: 645
v=0
o=- 1746657286595 2 IN IP4 127.0.0.1
s=-
t=0 0
a=group:BUNDLE audio
a=msid-semantic: WMS 42da9643-cb50-4eca-95d3-ca41b3f1f4bb
m=audio 3480 RTP/SAVP 107 101
c=IN IP4 157.240.19.130
a=rtcp:9 IN IP4 0.0.0.0
a=mid:audio
a=sendrecv
a=msid:42da9643-cb50-4eca-95d3-ca41b3f1f4bb WhatsAppTrack1
a=rtcp-mux
a=crypto:**************************************************************************
a=rtpmap:107 opus/48000/2
a=fmtp:107 maxaveragebitrate=20000;maxplaybackrate=16000;minptime=20;sprop-maxcapturerate=16000;useinbandfec=1
a=rtpmap:101 telephone-event/8000
a=maxptime:20
a=ptime:20
a=ssrc:1238967757 cname:WhatsAppAudioStream1
SDES
Pruebas para llamadas iniciadas por usuarios y empresas
- Puede configurar el protocolo de intercambio de claves SRTP para que sea SDES en lugar del DTLS predeterminado
Habilitación/Deshabilitación de SDES SRTP
| Descripción | Actualizar la configuración de llamadas de un número de teléfono |
|---|---|
| Endpoint | POST calls/v21.0/{did}/settings |
| Cuerpo de la solicitud | { “calling”: { “status”: “ENABLED”, “call_icon_visibility”: “DEFAULT” “srtp_key_exchange_protocol”: “DTLS (default) |
| Respuesta | { “success”: true } |
| Campos | Parámetros anidados bajo el nodo “llamante”: srtp_key_exchange_protocol: campo opcional con DTLS como valor predeterminado. Configure este campo como SDES para usar SDES para el intercambio de claves. Es posible que solo se permita el uso de SDES para números con SIP habilitado. |
| Respuesta de error | { “error”: { “message”: “<Error Message>”, “type”: “<Exception Type>”, “code”: <Exception Code>, “fbtrace_id”: “<Trace ID>” } } |
| Consideraciones especiales | Meta aún espera que el lado comercial envíe el paquete SRTP inaugural tanto para las llamadas iniciadas por el usuario como por el negocio. |
| Permisos de la aplicación | gestión empresarial de whatsapp Se requiere acceso avanzado para utilizar la API en nombre de las empresas finales. |
Protocolo de intercambio de claves GET SRTP
| Descripción | Obtener la configuración de llamadas para un número de teléfono, asociado únicamente a la aplicación actual que realiza esta solicitud de API |
|---|---|
| Endpoint | GET calls/v21.0/{did}/settings |
| Respuesta | { “calling”: { “status”: “ENABLED”, “call_icon_visibility”: “DEFAULT”, “srtp_key_exchange_protocol”: “DTLS (default) |
| Campos | srtp_key_exchange_protocol es un campo opcional y estará ausente si el socio no lo configura explícitamente. Esto se hace para no hacerlo visible de forma proactiva, ya que no queremos incentivar de ninguna manera el uso de SDES por parte de los socios. Nuestra preferencia es DTLS. |
| Respuesta de error | { “error”: { “message”: “<Error Message>”, “type”: “<Exception Type>”, “code”: <Exception Code>, “fbtrace_id”: “<Trace ID>” } } |
| Permisos de la aplicación | gestión empresarial de whatsapp Se requiere acceso avanzado para actualizar el uso de la API para clientes comerciales finales |
| Campos | Lo mismo que configurar los ajustes de SIP. |