https://a.storyblok.com/f/270183/1368x665/fb6c6e87ac/26aug-record_audio_with_nodejs-blog-r1.jpg

Cómo grabar audio de llamadas entrantes con Node.js

Publicado el August 27, 2026

Tiempo de lectura: 6 minutos

Introducción

Podemos grabar una llamada completa o solo una parte de ella. En la entrada del blog de hoy, aprenderemos más sobre la acción «Grabar objeto de control de llamada» de la Voice API. También utilizaremos Node.js. Puedes consultar el código fuente para grabar una llamada en record-a-call.js en GitHub.

Requisitos previos

  • Node.js instalado - Node.js es un entorno de ejecución de JavaScript multiplataforma y de código abierto.

  • ngrok - Se requiere una Account gratuita. Esta herramienta permite a los desarrolladores exponer a Internet un servidor de desarrollo local.

  • Aprenderemos a grabar llamadas de audio, pero es importante disponer de una aplicación de Vonage creada con la función de Voice, tal y como se muestra en este tutorial sobre cómo gestionar llamadas entrantes con Node.js.

  • CLI de Vonage instalado — ejecutar

    npm install -g @vonage/cli and configure it with vonage config:set --apiKey=YOUR_KEY --apiSecret=YOUR_SECRET.

Definir un objeto de control de llamadas para grabar las llamadas entrantes

En el tutorial anterior se explicó cómo crear direcciones URL de puntos finales de webhook y asociarlas a una aplicación de Voice para gestionar las llamadas entrantes. En este tutorial, modificarás el objeto de control de llamadas (NCCO) para grabar audio. Si aún no has completado el tutorial anterior, sigue primero ese.

Objetos de control de llamadas (NCCO)

El objeto de control de llamadas que se utiliza en la Voice API de Vonage te permite personalizar completamente las llamadas de voz automatizadas mediante:

  • seleccionar el idioma y el estilo de voz del sistema de llamadas automáticas

  • activar webhooks en respuesta a diferentes situaciones (por ejemplo, cuando un usuario pulsa una tecla o no responde)

  • dejar un mensaje personalizado en el contestador automático de un usuario, ¡y mucho más!

Mientras desarrollas y pruebas los objetos de control de llamadas, puedes utilizar Voice Playground para probar los NCCO de forma interactiva. Puedes obtener más información en los detalles técnicos o visitar directamente el Voice Playground.

Iniciar el túnel de ngrok

Para empezar, ejecuta ngrok: 

vonage tunnel ngrok --port=4002

Utilizarás las URL de redireccionamiento, como https://db95720f.ngrok.app, como puntos finales temporales de los webhooks durante el desarrollo.

Actualiza tu aplicación de Vonage con las URL de ngrok. Puedes hacerlo a través del panel de control de Vonage o, si dispones de la CLI de Vonage , abriendo una nueva pestaña de terminal y ejecutando:

vonage apps update YOUR_VONAGE_APPLICATION_ID \

  --voice-answer-url=https://db95720f.ngrok.com/webhooks/answer \

  --voice-event-url=https://db95720f.ngrok.com/webhooks/event

Nota: La opción --voice-event-url que aparece aquí se refiere a los eventos generales del ciclo de vida de la llamada (por ejemplo, llamada contestada, llamada finalizada). La URL del webhook de grabación se configura por separado en el parámetro eventUrl del NCCO, que configurarás en la siguiente sección.

Configuración de un proyecto Node.js

Ahora que hemos creado nuestra aplicación Vonage Voice en el panel de control para desarrolladores, veamos cómo debemos configurar nuestra aplicación Node.js.

Empieza abriendo una ventana de comandos o terminal, creando un directorio de trabajo e inicializando un proyecto de Node.js:

npm init -y

Tramitaremos las solicitudes con Express y utilizaremos body-parser para analizar los cuerpos de las solicitudes entrantes. También necesitamos @vonage/jwt verificar la firma JWT en las solicitudes de webhook entrantes. Instala todas las dependencias con:

npm install dotenv express body-parser @vonage/jwt –save @vonage/server-client

Estructura del proyecto

Tu proyecto debe contener los siguientes archivos:

├── server.js         # main Express application
├── recording.js      # helper functions for naming and downloading recordings
├── .env              # environment variables (VONAGE_API_SIGNATURE_SECRET, PORT)
└── recordings/       # auto-created directory where audio files are saved

Ahora que ya tienes tu proyecto configurado, vamos a definir el objeto de control de llamadas (NCCO). Edita el onInboundCall controlador en server.js para registrar las llamadas entrantes:

// server.js

const onInboundCall = (request, response) => {

  const ncco = [

    {

      action: "talk",

      text: "Please leave your message after the tone, then press hash when finished.",

    },

    {

      action: "record",

      eventUrl: [`${request.protocol}://${request.get("host")}/record`],

      endOnSilence: 3,

      endOnKey: "#",

      beepStart: true,

      timeOut: 60,

    },

    {

      action: "talk",

      text: "Thank you for your message. Goodbye!",

    },

  ];

 

  response.json(ncco);

};

La eventUrl en el NCCO, en lugar de codificar una URL de forma fija, ahora se genera dinámicamente a partir de la solicitud entrante, por lo que tu webhook siempre apunta al host correcto, tanto si se ejecuta localmente con ngrok como en producción. Aquí es donde se envía la información de la grabación una vez finalizada la llamada. En este tutorial, el webhook de grabación se gestiona en /record. Asegúrate de que el «eventUrl» de tu NCCO coincida con la ruta registrada en tu aplicación Express.

Ten en cuenta que, en todas las acciones, el eventUrl parámetro DEBE ser un array, aunque solo contenga un único valor.

Verificación de firmas de webhooks con JWT

Vonage firma con el JWT cada solicitud de webhook que envía. Tu servidor debe verificar esta firma para asegurarse de que la solicitud procede realmente de Vonage y no ha sido alterada.

Añade un verifyJWT middleware que lea el Authorization: Bearer <token> encabezado y lo valida según tu VONAGE_API_SIGNATURE_SECRET (disponible en el panel de control de Vonage):

// server.js

const { verifySignature } = require("@vonage/jwt");

 

const verifyJWT = (req, res, next) => {

  try {

    const authHeader = req.headers.authorization;

    if (!authHeader || !authHeader.startsWith("Bearer ")) {

      return res.status(401).send("Unauthorized");

    }

 

    const jwtToken = authHeader.split(" ")[1];

 

    if (!verifySignature(jwtToken, process.env.VONAGE_API_SIGNATURE_SECRET)) {

      return res.status(401).send("Unauthorized");

    }

 

    next();

  } catch (err) {

    return res.status(401).send("Unauthorized");

  }

};

A continuación, este middleware se aplica a todas las rutas de webhook POST (los puntos finales de eventos y de grabación), pero no al punto final GET de respuesta, ya que este lo invoca Vonage para recuperar el NCCO.

El módulo de ayuda a la grabación

Para mantener server.js orden, la lógica de denominación de archivos y de descargas se encuentra en un recording.js . La buildRecordingFileName función genera un nombre de archivo único a partir de la URL de la grabación y, a continuación, downloadRecording recoge el archivo de audio y lo guarda en el disco:

const { buildRecordingFileName, downloadRecording } = require("./recording");

Cuando finaliza una grabación, Vonage activa el /record (o /webhooks/recordings) con una carga útil que incluye el recording_url :

{

  "start_time": "2026-01-19T00:34:48Z",

  "recording_url": "https://api.nexmo.com/v1/files/486fadc7-2abb-4f56-985e-fb83102acb82",

  "size": 19181,

  "recording_uuid": "33e0c756-5405-44d9-b869-197e55e780f0",

  "end_time": "2026-01-19T00:34:53Z",

  "conversation_uuid": "de783420-379c-409e-8c73-1ea1e6b2a38e"

}

Descargar la grabación

El onRecording controlador lee el recording_url del cuerpo del webhook, genera el nombre del archivo de destino utilizando buildRecordingFileName, y guarda el archivo en el /recordings/ directorio (que se crea automáticamente al iniciarse):

const recordingsDir = path.join(__dirname, "recordings");

fs.mkdirSync(recordingsDir, { recursive: true });

 

const onRecording = async (request, response) => {

  const audioURL = request.body.recording_url;

 

  if (!audioURL) {

    return response.status(204).send();

  }

 

  const fileName = buildRecordingFileName(audioURL);

  const audioFile = path.join(recordingsDir, fileName);

 

  try {

    await downloadRecording(audioURL, audioFile);

  } catch (err) {

    console.error("Error downloading recording:", err.message);

  }

 

  response.status(204).send();

};

Por defecto, el audio grabado se guarda en formato MP3 y Vonage lo conserva durante 30 días.

Conectar las rutas

Por último, registra todas las rutas. Ten en cuenta que los puntos finales POST de eventos y de grabación están protegidos por el verifyJWT middleware, mientras que el punto final GET de respuesta se deja abierto:

app

  .get("/webhooks/answer", onInboundCall)

  .post("/webhooks/event", verifyJWT, onCallEvent)

  .post("/record", verifyJWT, onRecording);

El verifyJWT middleware se aplica a todos los puntos finales POST, /webhooks/event y /record, pero no al punto final GET /webhooks/answer, ya que este lo invoca Vonage para recuperar el NCCO en lugar de enviar un webhook firmado.

Ejecutar la aplicación

Instala las dependencias e inicia el servidor:

npm install

node server.js

A continuación, llama a tu número de teléfono de Vonage. Si todo funciona correctamente, deberías oír un mensaje de bienvenida seguido de un pitido. Deja un mensaje y pulsa # en el teclado. Una vez finalizada la llamada, comprueba la /recordings/ carpeta. Allí deberías encontrar el archivo de audio descargado.

Conclusión

En el tutorial de hoy has aprendido a grabar archivos de audio de las llamadas entrantes. A continuación encontrarás más recursos que te ayudarán a conocer mejor las API de Vonage y Node.js.

Grabación de llamadas

Guía de inicio de Vonage para Node.js

¿Tiene alguna pregunta o quiere compartir lo que está construyendo?

Mantente conectado y entérate de las últimas noticias, consejos y eventos para desarrolladores.

Compartir:

https://a.storyblok.com/f/270183/400x400/3f6b0c045f/amanda-cavallaro.png
Amanda CavallaroDefensor del Desarrollador