feat: update image generation logic to use new Google GenAI API and enhance error handling
This commit is contained in:
@@ -1,61 +1,83 @@
|
||||
import { CommandMessage } from "../../../core/types/commands";
|
||||
import { aiService } from "../../../core/services/AIService";
|
||||
import logger from "../../../core/lib/logger";
|
||||
import { Message, AttachmentBuilder } from 'discord.js';
|
||||
import { aiService } from '../../../core/services/AIService';
|
||||
import logger from '../../../core/lib/logger';
|
||||
|
||||
function parseSizeArg(arg?: string): 'square' | 'portrait' | 'landscape' {
|
||||
if (!arg) return 'square';
|
||||
const v = arg.toLowerCase();
|
||||
if (v === 'square' || v === 'cuadrado' || v === '1:1') return 'square';
|
||||
if (v === 'portrait' || v === 'vertical' || v === '9:16') return 'portrait';
|
||||
if (v === 'landscape' || v === 'horizontal' || v === '16:9') return 'landscape';
|
||||
return 'square';
|
||||
}
|
||||
export default {
|
||||
name: 'image',
|
||||
description: 'Genera una imagen usando IA',
|
||||
cooldown: 10,
|
||||
async execute(message: Message, args: string[]) {
|
||||
// Verificar que hay un prompt
|
||||
if (!args || args.length === 0) {
|
||||
await message.reply('❌ **Error**: Debes proporcionar una descripción para generar la imagen.\n\n**Ejemplo**: `imagen un gato espacial flotando entre estrellas`');
|
||||
return;
|
||||
}
|
||||
|
||||
const prompt = args.join(' ').trim();
|
||||
|
||||
// Validar longitud del prompt
|
||||
if (prompt.length < 3) {
|
||||
await message.reply('❌ **Error**: La descripción debe tener al menos 3 caracteres.');
|
||||
return;
|
||||
}
|
||||
|
||||
if (prompt.length > 1000) {
|
||||
await message.reply('❌ **Error**: La descripción es demasiado larga (máximo 1000 caracteres).');
|
||||
return;
|
||||
}
|
||||
|
||||
// Mostrar mensaje de "generando..."
|
||||
const thinkingMessage = await message.reply('🎨 **Generando imagen**... Esto puede tomar unos momentos.');
|
||||
|
||||
export const command: CommandMessage = {
|
||||
name: 'aiimg',
|
||||
type: 'message',
|
||||
aliases: ['img', 'imagen'],
|
||||
cooldown: 5,
|
||||
description: 'Genera una imagen con Gemini (gemini-2.5-flash-image).',
|
||||
category: 'IA',
|
||||
usage: 'aiimg [square|portrait|landscape] <prompt>',
|
||||
run: async (message, args) => {
|
||||
try {
|
||||
if (!args || args.length === 0) {
|
||||
await message.reply({
|
||||
content: 'Uso: aiimg [square|portrait|landscape] <prompt>\nEjemplo: aiimg portrait un gato astronauta'
|
||||
});
|
||||
return;
|
||||
}
|
||||
logger.info(`Generando imagen para usuario ${message.author.id}: ${prompt.slice(0, 100)}`);
|
||||
|
||||
let size: 'square' | 'portrait' | 'landscape' = 'square';
|
||||
let prompt = args.join(' ').trim();
|
||||
|
||||
// Si el primer arg es un tamaño válido, usarlo y quitarlo del prompt
|
||||
const maybeSize = parseSizeArg(args[0]);
|
||||
if (maybeSize !== 'square' || ['square', 'cuadrado', '1:1'].includes(args[0]?.toLowerCase?.() ?? '')) {
|
||||
// Detect explicit size keyword; if first arg matches any known size token, shift it
|
||||
if (['square','cuadrado','1:1','portrait','vertical','9:16','landscape','horizontal','16:9'].includes(args[0].toLowerCase())) {
|
||||
size = maybeSize;
|
||||
prompt = args.slice(1).join(' ').trim();
|
||||
}
|
||||
}
|
||||
|
||||
if (!prompt) {
|
||||
await message.reply({ content: 'El prompt no puede estar vacío.' });
|
||||
return;
|
||||
}
|
||||
|
||||
(message.channel as any)?.sendTyping?.().catch(() => {});
|
||||
const result = await aiService.generateImage(prompt, { size });
|
||||
|
||||
await message.reply({
|
||||
content: `✅ Imagen generada (${size}).`,
|
||||
files: [{ attachment: result.data, name: result.fileName }]
|
||||
// Generar la imagen usando el AIService actualizado
|
||||
const result = await aiService.generateImage(prompt, {
|
||||
size: 'square', // Por defecto usar formato cuadrado
|
||||
mimeType: 'image/jpeg',
|
||||
numberOfImages: 1,
|
||||
personGeneration: true
|
||||
});
|
||||
} catch (error: any) {
|
||||
logger.error(error, 'Error generando imagen');
|
||||
await message.reply({ content: `❌ Error generando imagen: ${error?.message || 'Error desconocido'}` });
|
||||
|
||||
// Crear attachment para Discord
|
||||
const attachment = new AttachmentBuilder(result.data, {
|
||||
name: result.fileName,
|
||||
description: `Imagen generada: ${prompt.slice(0, 100)}${prompt.length > 100 ? '...' : ''}`
|
||||
});
|
||||
|
||||
// Responder con la imagen
|
||||
await thinkingMessage.edit({
|
||||
content: `✅ **Imagen generada** para: *${prompt.slice(0, 150)}${prompt.length > 150 ? '...' : ''}*`,
|
||||
files: [attachment]
|
||||
});
|
||||
|
||||
logger.info(`Imagen generada exitosamente para usuario ${message.author.id}, tamaño: ${result.data.length} bytes`);
|
||||
|
||||
} catch (error) {
|
||||
logger.error(`Error generando imagen para usuario ${message.author.id}: ${error}`);
|
||||
|
||||
let errorMessage = '❌ **Error generando imagen**: ';
|
||||
|
||||
if (error instanceof Error) {
|
||||
const errorText = error.message.toLowerCase();
|
||||
|
||||
if (errorText.includes('no está disponible') || errorText.includes('not found')) {
|
||||
errorMessage += 'El servicio de generación de imágenes no está disponible en este momento.';
|
||||
} else if (errorText.includes('límite') || errorText.includes('quota')) {
|
||||
errorMessage += 'Se ha alcanzado el límite de generación de imágenes. Intenta más tarde.';
|
||||
} else if (errorText.includes('bloqueado') || errorText.includes('safety')) {
|
||||
errorMessage += 'Tu descripción fue bloqueada por las políticas de seguridad. Intenta con algo diferente.';
|
||||
} else if (errorText.includes('inicializado') || errorText.includes('api')) {
|
||||
errorMessage += 'El servicio no está configurado correctamente.';
|
||||
} else {
|
||||
errorMessage += error.message;
|
||||
}
|
||||
} else {
|
||||
errorMessage += 'Error desconocido. Intenta de nuevo más tarde.';
|
||||
}
|
||||
|
||||
await thinkingMessage.edit(errorMessage);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user