understanding commited on
Commit
bc39fa8
·
verified ·
1 Parent(s): 188c608

Update main.py

Browse files
Files changed (1) hide show
  1. main.py +111 -99
main.py CHANGED
@@ -1,103 +1,115 @@
1
- # main.py
2
  import os
 
3
  import logging
4
- import asyncio
5
- from concurrent.futures import ThreadPoolExecutor
6
-
7
- from hydrogram import Client, idle
8
- from hydrogram.errors import AuthKeyUnregistered
9
-
10
- from config import Config
11
- import handlers # To access register_handlers
12
-
13
- # --- Global Executor ---
14
- # Defined here so it can be imported by handlers if structured that way,
15
- # or simply passed/used within main_async_logic.
16
- # max_workers can be adjusted based on CPU cores or expected load.
17
- executor = ThreadPoolExecutor(max_workers=(os.cpu_count() or 1) + 4)
18
-
19
-
20
- # --- Logging Setup ---
21
- def setup_logging():
22
- logging.basicConfig(
23
- level=logging.INFO,
24
- format='%(asctime)s - %(name)s - %(levelname)s - [%(module)s.%(funcName)s:%(lineno)d] - %(message)s',
25
- )
26
- logging.getLogger("hydrogram").setLevel(logging.WARNING) # Reduce hydrogram verbosity
27
- return logging.getLogger(__name__)
28
-
29
- logger = setup_logging()
30
-
31
-
32
- # --- Directory and Font Checks ---
33
- def run_startup_checks():
34
- logger.info("Running startup checks...")
35
- # Check directories (expected to be created by Dockerfile or COPY . .)
36
- if not os.path.isdir(Config.PREDEFINED_TEMPLATES_DIR):
37
- logger.error(f"FATAL: Templates directory '{Config.PREDEFINED_TEMPLATES_DIR}' not found or is not a directory in the repository root.")
38
- return False
39
- if not os.path.isdir(Config.OUTPUT_DIR): # This one is created by Dockerfile if not present
40
- logger.info(f"Output directory '{Config.OUTPUT_DIR}' not found, will be created by Dockerfile.")
41
- # It's okay if this one is missing initially, Dockerfile handles it.
42
- # But templates dir *must* come from repo.
43
-
44
- # Check if templates directory has content (optional but good)
45
  try:
46
- if os.path.isdir(Config.PREDEFINED_TEMPLATES_DIR) and not os.listdir(Config.PREDEFINED_TEMPLATES_DIR):
47
- logger.warning(f"Templates directory '{Config.PREDEFINED_TEMPLATES_DIR}' is empty. Predefined templates will not work.")
48
- except Exception as e:
49
- logger.warning(f"Could not check contents of templates directory: {e}")
50
-
51
-
52
- logger.info("Required directories check complete.")
53
- logger.info(f"Attempting to use font: '{Config.FONT_PATH}' (requires system font access).")
54
- return True
55
-
56
- # --- Main Application Logic ---
57
- async def main_async_logic():
58
- logger.info("Initializing Hydrogram Bot Client...")
59
-
60
- app = Client(
61
- name=Config.SESSION_NAME,
62
- api_id=Config.API_ID,
63
- api_hash=Config.API_HASH,
64
- bot_token=Config.BOT_TOKEN,
65
- workdir="/app" # Ensures .session file is stored in /app (writable)
66
- )
67
-
68
- handlers.register_handlers(app)
69
- logger.info("Message handlers registered.")
70
-
71
- try:
72
- logger.info("Starting Hydrogram client (as BOT)...")
73
- await app.start()
74
- me = await app.get_me()
75
- logger.info(f"Successfully started. Bot: {me.first_name} (Username: @{me.username}, ID: {me.id})")
76
- logger.info("Bot is up and listening for messages from admins!")
77
- await idle()
78
- except AuthKeyUnregistered:
79
- logger.critical("BOT TOKEN INVALID or REVOKED. Please check your BOT_TOKEN secret in Hugging Face.")
80
- except Exception as e:
81
- logger.critical(f"Error starting or running Hydrogram client: {e}", exc_info=True)
82
- finally:
83
- logger.info("Shutting down executor...")
84
- executor.shutdown(wait=True)
85
- if app.is_initialized and app.is_connected: # Check if client was started
86
- logger.info("Stopping Hydrogram client...")
87
- await app.stop()
88
- logger.info("Shutdown complete.")
89
-
90
- if __name__ == "__main__":
91
- if not run_startup_checks():
92
- logger.critical("Startup checks failed. Exiting.")
93
- exit(1)
94
-
95
- try:
96
- asyncio.run(main_async_logic())
97
- except KeyboardInterrupt:
98
- logger.info("Bot stopped by KeyboardInterrupt.")
99
- except Exception as e:
100
- logger.critical(f"Unhandled exception in main: {e}", exc_info=True)
101
- finally:
102
- logger.info("Application terminated.")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
103
 
 
 
1
  import os
2
+ import requests
3
  import logging
4
+ from telethon import TelegramClient, events
5
+
6
+ # --- Configuration ---
7
+ # Set up basic logging
8
+ logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
9
+ logger = logging.getLogger(__name__)
10
+
11
+ # Retrieve secrets from Hugging Face secrets (environment variables)
12
+ # These MUST be set in your Hugging Face Space/Repo secrets settings
13
+ API_ID = os.environ.get('API_ID')
14
+ API_HASH = os.environ.get('API_HASH')
15
+ BOT_TOKEN = os.environ.get('BOT_TOKEN')
16
+
17
+ # Your "Permanent Template" URL
18
+ TEMPLATE_URL = "https://mediaflare.adasin.workers.dev/dl/4AmNTDcYQSPNQS"
19
+
20
+ # --- Helper Function to Fetch Template ---
21
+ def fetch_template(url):
22
+ """Fetches content from the template URL."""
23
+ logger.info(f"Fetching template from {url}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
24
  try:
25
+ response = requests.get(url, timeout=10) # Added timeout
26
+ response.raise_for_status() # Raise an exception for bad status codes (4xx or 5xx)
27
+ logger.info("Template fetched successfully.")
28
+ # Assuming the template is text-based. Adjust if it's JSON, binary, etc.
29
+ return response.text
30
+ except requests.exceptions.RequestException as e:
31
+ logger.error(f"Error fetching template from {url}: {e}")
32
+ return None # Return None or a default value if fetching fails
33
+
34
+ # --- Initialization ---
35
+ # Check if essential secrets are loaded
36
+ if not all([API_ID, API_HASH, BOT_TOKEN]):
37
+ logger.error("Missing required environment variables (API_ID, API_HASH, BOT_TOKEN). Ensure they are set in Hugging Face secrets.")
38
+ exit(1) # Exit if secrets are missing
39
+
40
+ try:
41
+ # Convert API_ID to integer
42
+ API_ID = int(API_ID)
43
+ except ValueError:
44
+ logger.error("API_ID environment variable is not a valid integer.")
45
+ exit(1)
46
+
47
+ # Fetch the template content on startup
48
+ template_content = fetch_template(TEMPLATE_URL)
49
+ if template_content is None:
50
+ logger.warning("Proceeding without template content due to fetch error.")
51
+ # You might want to exit(1) here or use a default fallback template
52
+ # template_content = "Default template: An error occurred fetching the primary one."
53
+
54
+ # Initialize the Telethon client
55
+ # 'bot_session' is the name of the session file that will be created.
56
+ logger.info("Initializing Telegram Client...")
57
+ try:
58
+ client = TelegramClient('bot_session', API_ID, API_HASH)
59
+ logger.info("Telegram Client initialized.")
60
+ except Exception as e:
61
+ logger.error(f"Failed to initialize Telegram Client: {e}")
62
+ exit(1)
63
+
64
+ # --- Bot Event Handlers ---
65
+ @client.on(events.NewMessage(pattern='/start'))
66
+ async def start_handler(event):
67
+ """Handler for the /start command."""
68
+ sender = await event.get_sender()
69
+ sender_name = getattr(sender, 'first_name', 'User') # Get sender's first name
70
+ logger.info(f"Received /start command from {sender_name} (ID: {event.sender_id})")
71
+
72
+ # Example of using the fetched template content
73
+ start_message = f"Hello {sender_name}!\n\n"
74
+ if template_content:
75
+ start_message += f"Here's the template content:\n---\n{template_content}\n---"
76
+ else:
77
+ start_message += "Could not load the template content."
78
+
79
+ await event.reply(start_message)
80
+
81
+ @client.on(events.NewMessage(pattern='/help'))
82
+ async def help_handler(event):
83
+ """Handler for the /help command."""
84
+ logger.info(f"Received /help command from {event.sender_id}")
85
+ await event.reply("This is a sample bot.\nCommands:\n/start - Show welcome message and template\n/help - Show this help message")
86
+
87
+ # Add more handlers as needed
88
+ # @client.on(events.NewMessage)
89
+ # async def message_handler(event):
90
+ # """Handles any other message."""
91
+ # logger.info(f"Received message from {event.sender_id}: {event.text}")
92
+ # # Process the message...
93
+ # # await event.reply(f"You said: {event.text}")
94
+
95
+
96
+ # --- Main Execution ---
97
+ async def main():
98
+ """Main function to start the bot."""
99
+ if template_content is not None:
100
+ logger.info("Template Content Loaded:\n" + template_content[:200] + "..." if len(template_content) > 200 else template_content) # Log first 200 chars
101
+ else:
102
+ logger.warning("Template content is not available.")
103
+
104
+ logger.info("Starting bot...")
105
+ # Start the client using the bot token
106
+ await client.start(bot_token=BOT_TOKEN)
107
+ logger.info("Bot started successfully and listening for messages.")
108
+ # Keep the client running until disconnected
109
+ await client.run_until_disconnected()
110
+ logger.info("Bot stopped.")
111
+
112
+ if __name__ == '__main__':
113
+ # Run the main function in the asyncio event loop
114
+ client.loop.run_until_complete(main())
115