diff --git a/main.py b/main.py index 18c2550..77ac882 100644 --- a/main.py +++ b/main.py @@ -1,6 +1,6 @@ import os from dotenv import load_dotenv -from src.bot import run_bot +from src.bot import main as run_bot load_dotenv() diff --git a/src/api_clients.py b/src/api_clients.py index 5144fa2..859cfdc 100644 --- a/src/api_clients.py +++ b/src/api_clients.py @@ -4,8 +4,8 @@ import wikipediaapi import requests -def get_unsplash_image(query: str) -> dict | None: - """Fetch an image from Unsplash based on the query.""" +def get_unsplash_image(query: str) -> list[dict] | None: + """Fetch images from Unsplash based on the query.""" access_key = os.getenv("UNSPLASH_ACCESS_KEY") if not access_key: raise ValueError("UNSPLASH_ACCESS_KEY is not set in the .env file") @@ -22,11 +22,17 @@ def get_unsplash_image(query: str) -> dict | None: response = requests.get(url, params=params) response.raise_for_status() data = response.json() - return { - "url": data["urls"]["regular"], - "photographer_name": data["user"]["name"], - "photographer_profile": data["user"]["links"]["html"], - } + # data is a list of photo dicts + images = [] + for item in data: + images.append( + { + "url": item["urls"]["regular"], + "photographer_name": item["user"]["name"], + "photographer_profile": item["user"]["links"]["html"], + } + ) + return images except requests.exceptions.RequestException as e: print(f"Error fetching image from Unsplash: {e}") @@ -45,8 +51,8 @@ def get_destination_info(destination: str) -> dict | None: if page.exists(): return { - "Summary": page.summary.split("\n")[0], - "URL": page.fullurl, + "summary": page.summary.split("\n")[0], + "url": page.fullurl, } else: print(f"No Wikipedia page found for {destination}.") diff --git a/src/bot.py b/src/bot.py index e69de29..c3693af 100644 --- a/src/bot.py +++ b/src/bot.py @@ -0,0 +1,16 @@ +from telegram.ext import Application, CommandHandler, CallbackQueryHandler +from . import handlers + + +def main(token: str) -> None: + """Run the bot""" + application = Application.builder().token(token).build() + + # Register command handlers + application.add_handler(CommandHandler("start", handlers.start)) + + # Register callback query handler + application.add_handler(CallbackQueryHandler(handlers.button)) + + # Start the bot + application.run_polling() diff --git a/src/handlers.py b/src/handlers.py index e69de29..892d97d 100644 --- a/src/handlers.py +++ b/src/handlers.py @@ -0,0 +1,77 @@ +from telegram import Update, InlineKeyboardButton, InlineKeyboardMarkup +from telegram.ext import ContextTypes +from .api_clients import get_unsplash_image, get_destination_info + +DESTINATIONS = { + "beaches": ["Maldives", "Bora Bora", "Phuket"], + "mountains": ["Swiss Alps", "Mount Everest", "Andes"], + "cities": ["Tokyo", "Paris", "New York City"], + "adventure": ["Costa Rica", "New Zealand", "Patagonia"], + "ancient ruins": ["Machu Picchu", "Rome", "Angkor Wat"], +} + + +async def start(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None: + """Sends a welcome message when the /start command is issued. + + Args: + update (Update): _description_ + context (ContextTypes.DEFAULT_TYPE): _description_ + """ + keyboard = [ + [InlineKeyboardButton("Beaches 🏖️", callback_data="beaches")], + [InlineKeyboardButton("Mountains 🏔️", callback_data="mountains")], + [InlineKeyboardButton("Cities 🏙️", callback_data="cities")], + [InlineKeyboardButton("Adventure 🧗", callback_data="adventure")], + [InlineKeyboardButton("Ancient Ruins 🏛️", callback_data="ancient ruins")], + ] + + reply_markup = InlineKeyboardMarkup(keyboard) + await update.message.reply_text( + "Welcome, wanderer! ✨\n\nI'm your personal TravelInspo Bot. " + "What kind of adventure are you dreaming of today?", + reply_markup=reply_markup, + ) + + +async def button(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None: + """Handles button presses and sends destination information. + + Args: + update (Update): The update containing the button press. + context (ContextTypes.DEFAULT_TYPE): The context of the update. + """ + query = update.callback_query + await query.answer() + + interest = query.data + if interest in DESTINATIONS: + destination_name = DESTINATIONS[interest][0] + + await query.edit_message_text( + text=f"Great choice! Searching for inspiration in {destination_name}..." + ) + + # Fetch destination info and image + + info = get_destination_info(destination_name) + image_data = get_unsplash_image(destination_name) + + if image_data and info: + image = image_data[0] # Get the first image + caption = ( + f"📍 *{destination_name}*\n\n" + f"{info['summary']}\n\n" + f"[Read more on Wikipedia]({info['url']})\n\n" + f"📸 Photo by [{image['photographer_name']}]({image['photographer_profile']}) on Unsplash" + ) + await context.bot.send_photo( + chat_id=query.message.chat_id, + photo=image["url"], + caption=caption, + parse_mode="Markdown", + ) + else: + await query.message.reply_text( + "Sorry, I couldn't find information for that destination." + )