import os import requests import logging import io # Import io for BytesIO from hydrogram import Client, filters from hydrogram.types import Message # --- Configuration --- logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s') logger = logging.getLogger(__name__) API_ID = os.environ.get('API_ID') API_HASH = os.environ.get('API_HASH') BOT_TOKEN = os.environ.get('BOT_TOKEN') TEMPLATE_URL = "https://mediaflare.adasin.workers.dev/dl/4AmNTDcYQSPNQS" # --- Helper Function to Fetch Template (Handles Binary Content) --- def fetch_template(url): """Fetches binary content (like an image) from the template URL.""" logger.info(f"Fetching template from {url}") try: response = requests.get(url, timeout=10) response.raise_for_status() logger.info(f"Template fetched successfully (Content-Type: {response.headers.get('Content-Type')}).") # Return the raw binary content return response.content except requests.exceptions.RequestException as e: logger.error(f"Error fetching template from {url}: {e}") return None # --- Initialization --- if not all([API_ID, API_HASH, BOT_TOKEN]): logger.error("Missing required environment variables (API_ID, API_HASH, BOT_TOKEN). Ensure they are set in Hugging Face secrets.") exit(1) try: API_ID = int(API_ID) except ValueError: logger.error("API_ID environment variable is not a valid integer.") exit(1) # Fetch the template image content (bytes) template_image_bytes = fetch_template(TEMPLATE_URL) if template_image_bytes is None: logger.warning("Proceeding without template image due to fetch error.") # Initialize the Hydrogram (Pyrogram) client # *** Add workdir='.' to explicitly use the current directory for the session file *** logger.info("Initializing Hydrogram Client...") try: app = Client( name="my_bot", # Session file will be my_bot.session api_id=API_ID, api_hash=API_HASH, bot_token=BOT_TOKEN, workdir="." # <--- Explicitly set workdir to the current directory ) logger.info("Hydrogram Client initialized.") except Exception as e: # Log the specific exception logger.error(f"Failed to initialize Hydrogram Client: {type(e).__name__} - {e}") exit(1) # --- Bot Event Handlers --- @app.on_message(filters.command("start")) async def start_handler(client: Client, message: Message): """Handler for the /start command. Sends the template image if available.""" sender_name = message.from_user.first_name if message.from_user else "User" sender_id = message.from_user.id if message.from_user else "Unknown ID" logger.info(f"Received /start command from {sender_name} (ID: {sender_id})") start_message_caption = f"Hello {sender_name}!" # Caption for the photo if template_image_bytes: logger.info("Attempting to send template image...") try: # Send the image bytes directly using io.BytesIO await message.reply_photo( photo=io.BytesIO(template_image_bytes), caption=start_message_caption + "\n\nHere's the template image." ) logger.info("Template image sent successfully.") except Exception as e: logger.error(f"Failed to send template image: {e}") # Fallback to text message if sending photo fails await message.reply_text(start_message_caption + "\n\n(Could not send the template image due to an error.)") else: # If template wasn't loaded, just send text await message.reply_text(start_message_caption + "\n\n(Could not load the template image.)") @app.on_message(filters.command("help")) async def help_handler(client: Client, message: Message): """Handler for the /help command.""" sender_id = message.from_user.id if message.from_user else "Unknown ID" logger.info(f"Received /help command from {sender_id}") await message.reply_text( "This is a sample bot (Hydrogram).\nCommands:\n/start - Show welcome message and template image\n/help - Show this help message" ) # --- Main Execution --- if __name__ == '__main__': if template_image_bytes is not None: # Log that we have image bytes, maybe length logger.info(f"Template image content loaded ({len(template_image_bytes)} bytes).") else: logger.warning("Template image content is not available.") logger.info("Starting bot...") try: app.run() except sqlite3.OperationalError as e: # Catch the specific error again if setting workdir didn't help logger.error(f"Caught sqlite3 error during app.run(): {e}. Check filesystem permissions for '.' directory.") # You might try workdir='/data' if '.' doesn't work on HF Spaces specifically logger.error("Consider trying workdir='/data' in Client initialization if '.' is not writable.") except Exception as e: # Catch any other exception during startup/runtime logger.error(f"An unexpected error occurred during app.run(): {type(e).__name__} - {e}") finally: # This might not be reached if app.run() blocks indefinitely, # but good practice if it were to exit cleanly. logger.info("Bot stopped or encountered a fatal error.")