understanding commited on
Commit
a90bf74
·
verified ·
1 Parent(s): b8d7c4e

Update main.py

Browse files
Files changed (1) hide show
  1. main.py +129 -86
main.py CHANGED
@@ -1,124 +1,167 @@
1
  import os
2
- import requests
3
  import logging
4
- import io # Import io for BytesIO
 
5
 
6
  from hydrogram import Client, filters
7
  from hydrogram.types import Message
 
8
 
9
  # --- Configuration ---
10
  logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
11
  logger = logging.getLogger(__name__)
12
 
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
- TEMPLATE_URL = "https://mediaflare.adasin.workers.dev/dl/4AmNTDcYQSPNQS"
17
 
18
- # --- Helper Function to Fetch Template (Handles Binary Content) ---
19
- def fetch_template(url):
20
- """Fetches binary content (like an image) from the template URL."""
21
- logger.info(f"Fetching template from {url}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22
  try:
23
- response = requests.get(url, timeout=10)
24
- response.raise_for_status()
25
- logger.info(f"Template fetched successfully (Content-Type: {response.headers.get('Content-Type')}).")
26
- # Return the raw binary content
27
- return response.content
28
- except requests.exceptions.RequestException as e:
29
- logger.error(f"Error fetching template from {url}: {e}")
30
- return None
31
 
32
  # --- Initialization ---
33
- if not all([API_ID, API_HASH, BOT_TOKEN]):
34
- logger.error("Missing required environment variables (API_ID, API_HASH, BOT_TOKEN). Ensure they are set in Hugging Face secrets.")
35
  exit(1)
36
 
37
- try:
38
- API_ID = int(API_ID)
39
- except ValueError:
40
- logger.error("API_ID environment variable is not a valid integer.")
41
- exit(1)
42
-
43
- # Fetch the template image content (bytes)
44
- template_image_bytes = fetch_template(TEMPLATE_URL)
45
- if template_image_bytes is None:
46
- logger.warning("Proceeding without template image due to fetch error.")
47
-
48
- # Initialize the Hydrogram (Pyrogram) client
49
- # *** Add workdir='.' to explicitly use the current directory for the session file ***
50
- logger.info("Initializing Hydrogram Client...")
51
  try:
52
  app = Client(
53
- name="my_bot", # Session file will be my_bot.session
54
- api_id=API_ID,
55
- api_hash=API_HASH,
56
- bot_token=BOT_TOKEN,
57
- workdir="." # <--- Explicitly set workdir to the current directory
58
  )
59
  logger.info("Hydrogram Client initialized.")
60
  except Exception as e:
61
- # Log the specific exception
62
  logger.error(f"Failed to initialize Hydrogram Client: {type(e).__name__} - {e}")
63
  exit(1)
64
 
 
65
  # --- Bot Event Handlers ---
66
- @app.on_message(filters.command("start"))
67
  async def start_handler(client: Client, message: Message):
68
- """Handler for the /start command. Sends the template image if available."""
69
  sender_name = message.from_user.first_name if message.from_user else "User"
70
- sender_id = message.from_user.id if message.from_user else "Unknown ID"
71
- logger.info(f"Received /start command from {sender_name} (ID: {sender_id})")
72
 
73
- start_message_caption = f"Hello {sender_name}!" # Caption for the photo
 
 
 
74
 
75
- if template_image_bytes:
76
- logger.info("Attempting to send template image...")
77
- try:
78
- # Send the image bytes directly using io.BytesIO
79
- await message.reply_photo(
80
- photo=io.BytesIO(template_image_bytes),
81
- caption=start_message_caption + "\n\nHere's the template image."
82
- )
83
- logger.info("Template image sent successfully.")
84
- except Exception as e:
85
- logger.error(f"Failed to send template image: {e}")
86
- # Fallback to text message if sending photo fails
87
- await message.reply_text(start_message_caption + "\n\n(Could not send the template image due to an error.)")
88
  else:
89
- # If template wasn't loaded, just send text
90
- await message.reply_text(start_message_caption + "\n\n(Could not load the template image.)")
91
 
 
92
 
93
- @app.on_message(filters.command("help"))
94
- async def help_handler(client: Client, message: Message):
95
- """Handler for the /help command."""
96
- sender_id = message.from_user.id if message.from_user else "Unknown ID"
97
- logger.info(f"Received /help command from {sender_id}")
98
- await message.reply_text(
99
- "This is a sample bot (Hydrogram).\nCommands:\n/start - Show welcome message and template image\n/help - Show this help message"
100
- )
101
 
102
- # --- Main Execution ---
103
- if __name__ == '__main__':
104
- if template_image_bytes is not None:
105
- # Log that we have image bytes, maybe length
106
- logger.info(f"Template image content loaded ({len(template_image_bytes)} bytes).")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
107
  else:
108
- logger.warning("Template image content is not available.")
 
109
 
110
- logger.info("Starting bot...")
 
 
 
 
 
111
  try:
112
- app.run()
113
- except sqlite3.OperationalError as e:
114
- # Catch the specific error again if setting workdir didn't help
115
- logger.error(f"Caught sqlite3 error during app.run(): {e}. Check filesystem permissions for '.' directory.")
116
- # You might try workdir='/data' if '.' doesn't work on HF Spaces specifically
117
- logger.error("Consider trying workdir='/data' in Client initialization if '.' is not writable.")
 
 
 
118
  except Exception as e:
119
- # Catch any other exception during startup/runtime
120
- logger.error(f"An unexpected error occurred during app.run(): {type(e).__name__} - {e}")
121
  finally:
122
- # This might not be reached if app.run() blocks indefinitely,
123
- # but good practice if it were to exit cleanly.
124
- logger.info("Bot stopped or encountered a fatal error.")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import os
 
2
  import logging
3
+ import asyncio
4
+ from pathlib import Path # For handling file paths robustly
5
 
6
  from hydrogram import Client, filters
7
  from hydrogram.types import Message
8
+ from hydrogram.errors import SessionPasswordNeeded, PhoneCodeInvalid, PhoneNumberInvalid, PasswordHashInvalid
9
 
10
  # --- Configuration ---
11
  logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
12
  logger = logging.getLogger(__name__)
13
 
14
+ # Retrieve Session String from Hugging Face secrets
15
+ # MUST be set in your Hugging Face Space/Repo secrets settings as SESSION_STRING
16
+ SESSION_STRING = os.environ.get('SESSION_STRING')
 
17
 
18
+ # Path for storing the template content
19
+ DATA_DIR = Path("data")
20
+ TEMPLATE_FILE_PATH = DATA_DIR / "template_content.txt"
21
+
22
+ # Global variable to hold the loaded template content
23
+ current_template_content = None
24
+
25
+ # --- Helper Functions for Template Management ---
26
+ def ensure_data_dir_exists():
27
+ """Ensures the data directory exists."""
28
+ DATA_DIR.mkdir(parents=True, exist_ok=True)
29
+ logger.info(f"Data directory '{DATA_DIR}' ensured.")
30
+
31
+ async def load_template_from_file():
32
+ """Loads template content from the persistent file."""
33
+ global current_template_content
34
+ ensure_data_dir_exists()
35
+ if TEMPLATE_FILE_PATH.exists():
36
+ try:
37
+ with open(TEMPLATE_FILE_PATH, "r", encoding="utf-8") as f:
38
+ current_template_content = f.read()
39
+ logger.info(f"Template loaded successfully from {TEMPLATE_FILE_PATH}")
40
+ except Exception as e:
41
+ logger.error(f"Error loading template from {TEMPLATE_FILE_PATH}: {e}")
42
+ current_template_content = None # Or a default error message
43
+ else:
44
+ logger.info(f"Template file {TEMPLATE_FILE_PATH} not found. No template loaded.")
45
+ current_template_content = None
46
+
47
+ async def save_template_to_file(content: str):
48
+ """Saves template content to the persistent file."""
49
+ global current_template_content
50
+ ensure_data_dir_exists()
51
  try:
52
+ with open(TEMPLATE_FILE_PATH, "w", encoding="utf-8") as f:
53
+ f.write(content)
54
+ current_template_content = content
55
+ logger.info(f"Template saved successfully to {TEMPLATE_FILE_PATH}")
56
+ return True
57
+ except Exception as e:
58
+ logger.error(f"Error saving template to {TEMPLATE_FILE_PATH}: {e}")
59
+ return False
60
 
61
  # --- Initialization ---
62
+ if not SESSION_STRING:
63
+ logger.error("SESSION_STRING environment variable not found. Please set it in Hugging Face secrets.")
64
  exit(1)
65
 
66
+ # Initialize the Hydrogram Client using the session string
67
+ # The name "user_session" is arbitrary when using a session_string,
68
+ # as the session is loaded directly from the string into memory.
69
+ logger.info("Initializing Hydrogram Client with session string...")
 
 
 
 
 
 
 
 
 
 
70
  try:
71
  app = Client(
72
+ name="user_session", # Name is a placeholder when session_string is used
73
+ session_string=SESSION_STRING,
74
+ # workdir="." # workdir is not strictly necessary for session file when session_string is used,
75
+ # but good if other client files are ever created.
76
+ # The template file path is handled separately.
77
  )
78
  logger.info("Hydrogram Client initialized.")
79
  except Exception as e:
 
80
  logger.error(f"Failed to initialize Hydrogram Client: {type(e).__name__} - {e}")
81
  exit(1)
82
 
83
+
84
  # --- Bot Event Handlers ---
85
+ @app.on_message(filters.command("start") & filters.private)
86
  async def start_handler(client: Client, message: Message):
87
+ """Handler for the /start command."""
88
  sender_name = message.from_user.first_name if message.from_user else "User"
89
+ logger.info(f"Received /start command from {sender_name} (ID: {message.from_user.id})")
 
90
 
91
+ welcome_text = f"Hello {sender_name}!\n"
92
+ welcome_text += "I am ready to manage your template.\n"
93
+ welcome_text += "Use /settemplate <your text> to set a new template.\n"
94
+ welcome_text += "Use /gettemplate to view the current template."
95
 
96
+ if current_template_content:
97
+ welcome_text += "\n\nA template is currently set."
 
 
 
 
 
 
 
 
 
 
 
98
  else:
99
+ welcome_text += "\n\nNo template is currently set."
 
100
 
101
+ await message.reply_text(welcome_text)
102
 
103
+ @app.on_message(filters.command("settemplate") & filters.private)
104
+ async def set_template_handler(client: Client, message: Message):
105
+ """Handler for the /settemplate command."""
106
+ user_id = message.from_user.id
107
+ logger.info(f"Received /settemplate command from User ID: {user_id}")
 
 
 
108
 
109
+ if len(message.command) > 1:
110
+ new_template = message.text.split(" ", 1)[1].strip() # Get content after "/settemplate "
111
+ if new_template:
112
+ if await save_template_to_file(new_template):
113
+ await message.reply_text("Template updated successfully!")
114
+ else:
115
+ await message.reply_text("❌ Failed to save the template. Please check the logs.")
116
+ else:
117
+ await message.reply_text("⚠️ Please provide content for the template. Usage: `/settemplate Your template text here`")
118
+ else:
119
+ await message.reply_text("ℹ️ Usage: `/settemplate Your template text here`")
120
+
121
+ @app.on_message(filters.command("gettemplate") & filters.private)
122
+ async def get_template_handler(client: Client, message: Message):
123
+ """Handler for the /gettemplate command."""
124
+ user_id = message.from_user.id
125
+ logger.info(f"Received /gettemplate command from User ID: {user_id}")
126
+
127
+ if current_template_content:
128
+ response_text = f"📜 **Current Template:**\n\n{current_template_content}"
129
  else:
130
+ response_text = "ℹ️ No template is currently set. Use `/settemplate <your text>` to set one."
131
+ await message.reply_text(response_text)
132
 
133
+ # --- Main Execution ---
134
+ async def main():
135
+ """Main function to load initial data and start the bot."""
136
+ await load_template_from_file() # Load any existing template on startup
137
+
138
+ logger.info("Attempting to connect and start the bot...")
139
  try:
140
+ await app.start()
141
+ me = await app.get_me()
142
+ logger.info(f"Bot started successfully as {me.first_name} (ID: {me.id})")
143
+ logger.info("Listening for messages...")
144
+ await asyncio.Event().wait() # Keep the bot running indefinitely
145
+ except (SessionPasswordNeeded, PhoneCodeInvalid, PhoneNumberInvalid, PasswordHashInvalid) as e:
146
+ logger.error(f"Authorization error: {type(e).__name__} - {e}. Your SESSION_STRING might be invalid or expired.")
147
+ except ConnectionError as e:
148
+ logger.error(f"Connection error: {e}. Check your network or Telegram's status.")
149
  except Exception as e:
150
+ logger.error(f"An unexpected error occurred during bot startup or runtime: {type(e).__name__} - {e}", exc_info=True)
 
151
  finally:
152
+ if app.is_connected:
153
+ logger.info("Stopping the bot...")
154
+ await app.stop()
155
+ logger.info("Bot stopped.")
156
+ else:
157
+ logger.info("Bot was not connected or already stopped.")
158
+
159
+ if __name__ == '__main__':
160
+ # Run the main function in the asyncio event loop
161
+ try:
162
+ asyncio.run(main())
163
+ except KeyboardInterrupt:
164
+ logger.info("Bot manually interrupted. Exiting...")
165
+ except Exception as e:
166
+ logger.critical(f"Critical error in main execution block: {e}", exc_info=True)
167
+