Implement flexible recipe search and add healthy meal retrieval functionality
This commit is contained in:
parent
4c9455f644
commit
c79ebcf9ff
@ -1,6 +1,49 @@
|
||||
const axios = require('axios');
|
||||
const { MessageMedia } = require('whatsapp-web.js');
|
||||
const recipesService = require('../services/recipes_service');
|
||||
const recipeUtils = require('../utils/recipe_utils');
|
||||
|
||||
/**
|
||||
* 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.
|
||||
@ -15,19 +58,30 @@ const handleRecipeCommand = async (client, message) => {
|
||||
let recipe;
|
||||
|
||||
if (subCommand === '!receta') {
|
||||
if (query) {
|
||||
// Buscar receta por nombre
|
||||
recipe = await recipesService.searchMealByName(query);
|
||||
if (query === 'saludable') {
|
||||
recipe = await recipesService.getRandomHealthyMeal();
|
||||
} else if (query) {
|
||||
recipe = await flexibleSearch(query);
|
||||
} else {
|
||||
// Obtener receta aleatoria
|
||||
recipe = await recipesService.getRandomMeal();
|
||||
}
|
||||
|
||||
if (!recipe) {
|
||||
throw new Error('No se encontraron recetas para tu búsqueda.');
|
||||
}
|
||||
|
||||
const recipeInfo = recipeUtils.formatRecipeInfo(recipe);
|
||||
await client.sendMessage(message.from, recipeInfo);
|
||||
|
||||
// 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 {
|
||||
// Manejar otros subcomandos si es necesario
|
||||
await client.sendMessage(message.from, '❌ Comando no reconocido.');
|
||||
}
|
||||
} catch (error) {
|
||||
|
@ -1,24 +1,22 @@
|
||||
const axios = require('axios');
|
||||
|
||||
/**
|
||||
* Busca una receta por nombre utilizando la API de TheMealDB.
|
||||
* Busca recetas por nombre utilizando la API de TheMealDB.
|
||||
* @param {String} name - Nombre de la receta a buscar.
|
||||
* @returns {Object} - Objeto de receta encontrado.
|
||||
* @throws {Error} - Si no se encuentra la receta o hay un error en la solicitud.
|
||||
* @returns {Array} - Lista de recetas encontradas.
|
||||
* @throws {Error} - Si no se encuentran recetas o hay un error en la solicitud.
|
||||
*/
|
||||
const searchMealByName = async (name) => {
|
||||
try {
|
||||
const response = await axios.get('https://www.themealdb.com/api/json/v1/1/search.php', {
|
||||
params: {
|
||||
s: name
|
||||
}
|
||||
params: { s: name }
|
||||
});
|
||||
|
||||
if (!response.data.meals) {
|
||||
throw new Error('No se encontraron recetas para tu búsqueda.');
|
||||
}
|
||||
|
||||
return response.data.meals[0]; // Retorna la primera receta encontrada
|
||||
return response.data.meals; // Devuelve todas las recetas encontradas
|
||||
} catch (error) {
|
||||
throw new Error(`Error al buscar la receta: ${error.message}`);
|
||||
}
|
||||
@ -65,8 +63,59 @@ const filterByIngredient = async (ingredient) => {
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* Categorías saludables para filtrar recetas.
|
||||
*/
|
||||
const healthyCategories = ['Salad', 'Chicken', 'Eggs', 'Fish', 'Seafood', 'Pasta', 'Rice', 'Beef', 'Pork', 'Lamb'];
|
||||
|
||||
/**
|
||||
* Obtiene una receta aleatoria de categorías saludables.
|
||||
* @returns {Object} - Objeto de receta aleatoria saludable.
|
||||
* @throws {Error} - Si no se encuentra una receta o hay un error en la solicitud.
|
||||
*/
|
||||
const getRandomHealthyMeal = async () => {
|
||||
try {
|
||||
// Escoge una categoría saludable al azar
|
||||
const randomCategory = healthyCategories[Math.floor(Math.random() * healthyCategories.length)];
|
||||
|
||||
// Filtra las recetas por la categoría saludable seleccionada
|
||||
const response = await axios.get('https://www.themealdb.com/api/json/v1/1/filter.php', {
|
||||
params: { c: randomCategory }
|
||||
});
|
||||
|
||||
if (!response.data.meals || response.data.meals.length === 0) {
|
||||
throw new Error('No se encontraron recetas saludables.');
|
||||
}
|
||||
|
||||
// Escoge una receta aleatoria dentro de las recetas saludables
|
||||
const randomMeal = response.data.meals[Math.floor(Math.random() * response.data.meals.length)];
|
||||
return await lookupMealById(randomMeal.idMeal);
|
||||
} catch (error) {
|
||||
throw new Error(`Error al obtener una receta saludable: ${error.message}`);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Busca los detalles completos de una receta por ID.
|
||||
* @param {String} id - ID de la receta.
|
||||
* @returns {Object} - Objeto de receta con detalles completos.
|
||||
*/
|
||||
const lookupMealById = async (id) => {
|
||||
try {
|
||||
const response = await axios.get(`https://www.themealdb.com/api/json/v1/1/lookup.php?i=${id}`);
|
||||
if (!response.data.meals) {
|
||||
throw new Error('No se encontraron detalles para la receta.');
|
||||
}
|
||||
return response.data.meals[0];
|
||||
} catch (error) {
|
||||
throw new Error(`Error al obtener detalles de la receta: ${error.message}`);
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
searchMealByName,
|
||||
getRandomMeal,
|
||||
filterByIngredient
|
||||
filterByIngredient,
|
||||
getRandomHealthyMeal,
|
||||
lookupMealById
|
||||
};
|
Loading…
Reference in New Issue
Block a user