Imgpost / main.py
understanding's picture
Update main.py
a90bf74 verified
raw
history blame
7.27 kB
import os
import logging
import asyncio
from pathlib import Path # For handling file paths robustly
from hydrogram import Client, filters
from hydrogram.types import Message
from hydrogram.errors import SessionPasswordNeeded, PhoneCodeInvalid, PhoneNumberInvalid, PasswordHashInvalid
# --- Configuration ---
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)
# Retrieve Session String from Hugging Face secrets
# MUST be set in your Hugging Face Space/Repo secrets settings as SESSION_STRING
SESSION_STRING = os.environ.get('SESSION_STRING')
# Path for storing the template content
DATA_DIR = Path("data")
TEMPLATE_FILE_PATH = DATA_DIR / "template_content.txt"
# Global variable to hold the loaded template content
current_template_content = None
# --- Helper Functions for Template Management ---
def ensure_data_dir_exists():
"""Ensures the data directory exists."""
DATA_DIR.mkdir(parents=True, exist_ok=True)
logger.info(f"Data directory '{DATA_DIR}' ensured.")
async def load_template_from_file():
"""Loads template content from the persistent file."""
global current_template_content
ensure_data_dir_exists()
if TEMPLATE_FILE_PATH.exists():
try:
with open(TEMPLATE_FILE_PATH, "r", encoding="utf-8") as f:
current_template_content = f.read()
logger.info(f"Template loaded successfully from {TEMPLATE_FILE_PATH}")
except Exception as e:
logger.error(f"Error loading template from {TEMPLATE_FILE_PATH}: {e}")
current_template_content = None # Or a default error message
else:
logger.info(f"Template file {TEMPLATE_FILE_PATH} not found. No template loaded.")
current_template_content = None
async def save_template_to_file(content: str):
"""Saves template content to the persistent file."""
global current_template_content
ensure_data_dir_exists()
try:
with open(TEMPLATE_FILE_PATH, "w", encoding="utf-8") as f:
f.write(content)
current_template_content = content
logger.info(f"Template saved successfully to {TEMPLATE_FILE_PATH}")
return True
except Exception as e:
logger.error(f"Error saving template to {TEMPLATE_FILE_PATH}: {e}")
return False
# --- Initialization ---
if not SESSION_STRING:
logger.error("SESSION_STRING environment variable not found. Please set it in Hugging Face secrets.")
exit(1)
# Initialize the Hydrogram Client using the session string
# The name "user_session" is arbitrary when using a session_string,
# as the session is loaded directly from the string into memory.
logger.info("Initializing Hydrogram Client with session string...")
try:
app = Client(
name="user_session", # Name is a placeholder when session_string is used
session_string=SESSION_STRING,
# workdir="." # workdir is not strictly necessary for session file when session_string is used,
# but good if other client files are ever created.
# The template file path is handled separately.
)
logger.info("Hydrogram Client initialized.")
except Exception as e:
logger.error(f"Failed to initialize Hydrogram Client: {type(e).__name__} - {e}")
exit(1)
# --- Bot Event Handlers ---
@app.on_message(filters.command("start") & filters.private)
async def start_handler(client: Client, message: Message):
"""Handler for the /start command."""
sender_name = message.from_user.first_name if message.from_user else "User"
logger.info(f"Received /start command from {sender_name} (ID: {message.from_user.id})")
welcome_text = f"Hello {sender_name}!\n"
welcome_text += "I am ready to manage your template.\n"
welcome_text += "Use /settemplate <your text> to set a new template.\n"
welcome_text += "Use /gettemplate to view the current template."
if current_template_content:
welcome_text += "\n\nA template is currently set."
else:
welcome_text += "\n\nNo template is currently set."
await message.reply_text(welcome_text)
@app.on_message(filters.command("settemplate") & filters.private)
async def set_template_handler(client: Client, message: Message):
"""Handler for the /settemplate command."""
user_id = message.from_user.id
logger.info(f"Received /settemplate command from User ID: {user_id}")
if len(message.command) > 1:
new_template = message.text.split(" ", 1)[1].strip() # Get content after "/settemplate "
if new_template:
if await save_template_to_file(new_template):
await message.reply_text("✅ Template updated successfully!")
else:
await message.reply_text("❌ Failed to save the template. Please check the logs.")
else:
await message.reply_text("⚠️ Please provide content for the template. Usage: `/settemplate Your template text here`")
else:
await message.reply_text("ℹ️ Usage: `/settemplate Your template text here`")
@app.on_message(filters.command("gettemplate") & filters.private)
async def get_template_handler(client: Client, message: Message):
"""Handler for the /gettemplate command."""
user_id = message.from_user.id
logger.info(f"Received /gettemplate command from User ID: {user_id}")
if current_template_content:
response_text = f"📜 **Current Template:**\n\n{current_template_content}"
else:
response_text = "ℹ️ No template is currently set. Use `/settemplate <your text>` to set one."
await message.reply_text(response_text)
# --- Main Execution ---
async def main():
"""Main function to load initial data and start the bot."""
await load_template_from_file() # Load any existing template on startup
logger.info("Attempting to connect and start the bot...")
try:
await app.start()
me = await app.get_me()
logger.info(f"Bot started successfully as {me.first_name} (ID: {me.id})")
logger.info("Listening for messages...")
await asyncio.Event().wait() # Keep the bot running indefinitely
except (SessionPasswordNeeded, PhoneCodeInvalid, PhoneNumberInvalid, PasswordHashInvalid) as e:
logger.error(f"Authorization error: {type(e).__name__} - {e}. Your SESSION_STRING might be invalid or expired.")
except ConnectionError as e:
logger.error(f"Connection error: {e}. Check your network or Telegram's status.")
except Exception as e:
logger.error(f"An unexpected error occurred during bot startup or runtime: {type(e).__name__} - {e}", exc_info=True)
finally:
if app.is_connected:
logger.info("Stopping the bot...")
await app.stop()
logger.info("Bot stopped.")
else:
logger.info("Bot was not connected or already stopped.")
if __name__ == '__main__':
# Run the main function in the asyncio event loop
try:
asyncio.run(main())
except KeyboardInterrupt:
logger.info("Bot manually interrupted. Exiting...")
except Exception as e:
logger.critical(f"Critical error in main execution block: {e}", exc_info=True)