Los Modelos de Lenguaje (LLMs) son increíbles redactando propuestas comerciales, pero se estrellan cuando intentas que le den formato corporativo a ese texto. La mayoría de tutoriales te enseñan a generar texto en la terminal, pero en el mundo B2B real, los usuarios no leen terminales: leen presentaciones corporativas, PDFs y hojas de cálculo.
Hoy vamos a construir un puente entre la Inteligencia Artificial Zyro y Google Workspace. Te enseñaré cómo crear un skill (habilidad) en Node.js que permite a un agente inteligente orquestar la API de Google Slides para generar presentaciones completas desde cero, aplicando tu plantilla corporativa.
Para no reinventar la rueda con la gestión de webhooks, esquemas OpenAPI y el enrutamiento de la IA, utilizaremos el Zyro Skills SDK, una librería open-source diseñada para inyectar herramientas personalizadas en agentes autónomos de forma segura mediante Function Calling.
El concepto: Inversión de Control y Memoria Descentralizada
En lugar de darle a la IA las llaves de tu Google Cloud (un riesgo de seguridad enorme), utilizaremos un patrón descentralizado. La IA decide qué contenido debe ir en la presentación, pero es nuestro servidor Node.js quien ejecuta el cómo. Además, el SDK de Zyro gestiona automáticamente un session_id anónimo, permitiendo que nuestro skill mantenga su propia base de datos (memoria descentralizada) sin sobrecargar el contexto del LLM.
Requisitos Previos
- Node.js instalado.
- Una Service Account de Google Cloud con la API de Google Slides y Google Drive habilitadas.
- El ID de una presentación de Google Slides que servirá como "Plantilla Maestra" corporativa.
Paso 1: Configuración del Proyecto
Iniciamos nuestro proyecto e instalamos el SDK junto con la librería oficial de Google:
npm init -y
npm install express cors googleapis dotenv
Paso 2: Inicializar el SDK de Zyro
Creamos nuestro archivo index.js. Aquí instanciamos la clase principal ZyroSkill, que levantará un servidor Express configurado para escuchar al orquestador de la IA.
const { ZyroSkill } = require('./src/index'); // Ajusta la ruta a tu SDK
const { google } = require('googleapis');
// 1. Inicializar el SDK
const slidesSkill = new ZyroSkill({
name: "Generador de Presentaciones Corporativas",
description: "Permite al orquestador clonar plantillas de Google Slides e inyectar contenido dinámico generado por la IA.",
port: process.env.PORT || 3000
});
Paso 3: Registrar la Acción para Google Slides
Utilizamos el método registerAction de tu SDK. Aquí definimos el esquema JSON que la IA debe respetar al enviarnos los datos, y la función asíncrona que ejecutará la clonación del documento en Google Drive.
// 2. Definir Acción: Crear Presentación
slidesSkill.registerAction(
'generar_google_slides',
'Genera una presentación comercial en Google Slides a partir del nombre del cliente y los textos clave.',
{
type: 'object',
properties: {
clientName: {
type: 'string',
description: 'Nombre de la empresa cliente para el título del archivo'
},
diapositivas: {
type: 'array',
description: 'Lista de textos a inyectar en las diapositivas',
items: { type: 'string' }
}
},
required: ['clientName', 'diapositivas']
},
async (parameters, context) => {
const { session_id } = context;
const { clientName, diapositivas } = parameters;
// 3. Autenticación silenciosa con Google Service Account
const auth = new google.auth.GoogleAuth({
keyFile: './google-credentials.json',
scopes: [
'[https://www.googleapis.com/auth/presentations](https://www.googleapis.com/auth/presentations)',
'[https://www.googleapis.com/auth/drive](https://www.googleapis.com/auth/drive)'
]
});
const drive = google.drive({ version: 'v3', auth });
const slides = google.slides({ version: 'v1', auth });
try {
console.log([Sesión: ${session_id}] Generando propuesta para: ${clientName});
// 4. Clonar la Plantilla Maestra en Drive
const copyResponse = await drive.files.copy({
fileId: process.env.TEMPLATE_ID,
requestBody: { name: `Propuesta Comercial - ${clientName}` }
});
const newPresentationId = copyResponse.data.id;
// 5. Dar permisos para que cualquiera con el enlace pueda editar
await drive.permissions.create({
fileId: newPresentationId,
requestBody: {
role: 'writer',
type: 'anyone'
}
});
// 6. Preparar las sustituciones de texto para Slides
const requests = [
{
replaceAllText: {
containsText: { text: '{{CLIENTE}}', matchCase: true },
replaceText: clientName
}
}
];
// Añadimos un reemplazo automático por cada elemento del array
diapositivas.forEach((texto, index) => {
requests.push({
replaceAllText: {
containsText: { text: `{{TEXTO_${index + 1}}}`, matchCase: true },
replaceText: texto
}
});
});
// 7. Inyectar los textos generados por la IA en la presentación
await slides.presentations.batchUpdate({
presentationId: newPresentationId,
requestBody: { requests }
});
// 8. Devolver el resultado limpio al Orquestador
return {
mensaje: 'Presentación clonada y generada correctamente.',
url_documento: 'https://docs.google.com/presentation/d/' + newPresentationId + '/edit'
};
} catch (error) {
console.error('Error en API de Google:', error);
throw new Error('Fallo al generar la presentación: ' + error.message);
}
}
);
// Arrancamos el servidor de Skills
slidesSkill.start();
Top comments (0)