102 lines
3.8 KiB
JavaScript
102 lines
3.8 KiB
JavaScript
const axios = require('axios');
|
|
const { MessageMedia } = require('whatsapp-web.js');
|
|
const recipesService = require('../services/recipes_service');
|
|
const recipeUtils = require('../utils/recipe_utils');
|
|
const { translateText } = require('../plugins/translator');
|
|
|
|
/**
|
|
* Selecciona una receta aleatoria de una lista.
|
|
* @param {Array} recipes - Lista de recetas.
|
|
* @returns {Object} - Una receta aleatoria de la lista.
|
|
*/
|
|
const getRandomRecipe = (recipes) => {
|
|
return recipes[Math.floor(Math.random() * recipes.length)];
|
|
};
|
|
|
|
/**
|
|
* Realiza una búsqueda flexible utilizando varias estrategias.
|
|
* @param {String} query - La consulta de búsqueda introducida por el usuario.
|
|
* @returns {Object|null} - Objeto de receta encontrado o null si no hay coincidencias.
|
|
*/
|
|
const flexibleSearch = async (query) => {
|
|
const words = query.split(' ');
|
|
let recipes;
|
|
|
|
// 1. Intentar búsqueda exacta
|
|
recipes = await recipesService.searchMealByName(query);
|
|
if (recipes && recipes.length > 0) return getRandomRecipe(recipes);
|
|
|
|
// 2. Intentar con palabras clave parciales
|
|
for (let i = words.length; i > 0; i--) {
|
|
const partialQuery = words.slice(0, i).join(' ');
|
|
recipes = await recipesService.searchMealByName(partialQuery);
|
|
if (recipes && recipes.length > 0) return getRandomRecipe(recipes);
|
|
}
|
|
|
|
// 3. Intentar con cada palabra como filtro de ingrediente
|
|
for (const word of words) {
|
|
recipes = await recipesService.filterByIngredient(word);
|
|
if (recipes && recipes.length > 0) {
|
|
const randomRecipe = await recipesService.lookupMealById(getRandomRecipe(recipes).idMeal);
|
|
if (randomRecipe) return randomRecipe;
|
|
}
|
|
}
|
|
|
|
return null;
|
|
};
|
|
|
|
/**
|
|
* Maneja el comando de recetas.
|
|
* @param {Object} client - Instancia del cliente de WhatsApp.
|
|
* @param {Object} message - Mensaje recibido.
|
|
*/
|
|
const handleRecipeCommand = async (client, message) => {
|
|
const parts = message.body.trim().split(' ');
|
|
const subCommand = parts[0].toLowerCase();
|
|
const query = parts.slice(1).join(' ');
|
|
|
|
try {
|
|
let recipe;
|
|
|
|
if (subCommand === '!receta') {
|
|
if (query === 'saludable') {
|
|
recipe = await recipesService.getRandomHealthyMeal();
|
|
} else if (query) {
|
|
recipe = await flexibleSearch(query);
|
|
} else {
|
|
recipe = await recipesService.getRandomMeal();
|
|
}
|
|
|
|
if (!recipe) {
|
|
throw new Error('No se encontraron recetas para tu búsqueda.');
|
|
}
|
|
|
|
// Traducir instrucciones al español antes de formatear la información
|
|
const instructions = recipe.strInstructions
|
|
? await translateText(recipe.strInstructions, 'es')
|
|
: 'No hay instrucciones disponibles.';
|
|
|
|
const recipeInfo = await recipeUtils.formatRecipeInfo({ ...recipe, strInstructions: instructions });
|
|
|
|
// Descargar la imagen de la receta
|
|
const imageUrl = recipe.strMealThumb;
|
|
const response = await axios.get(imageUrl, { responseType: 'arraybuffer' });
|
|
const imageBase64 = Buffer.from(response.data, 'binary').toString('base64');
|
|
const media = new MessageMedia('image/jpeg', imageBase64, 'receta.jpg');
|
|
|
|
// Enviar la imagen con la información de la receta como leyenda
|
|
await client.sendMessage(message.from, media, { caption: recipeInfo });
|
|
console.log(`📤 Información de la receta enviada a ${message.from}`);
|
|
} else {
|
|
await client.sendMessage(message.from, '❌ Comando no reconocido.');
|
|
}
|
|
} catch (error) {
|
|
console.error('❌ Error al manejar el comando de recetas:', error);
|
|
await client.sendMessage(message.from, `❌ Error al obtener la receta: ${error.message}`);
|
|
}
|
|
};
|
|
|
|
module.exports = {
|
|
handleRecipeCommand
|
|
};
|