Mohammed Foud
commited on
Commit
·
deb2780
1
Parent(s):
7585a32
Add application file
Browse files- Dockerfile +1 -1
- telegram_bot.py +158 -55
Dockerfile
CHANGED
|
@@ -30,4 +30,4 @@ COPY . .
|
|
| 30 |
EXPOSE 7860
|
| 31 |
|
| 32 |
# Command to run the application
|
| 33 |
-
CMD ["python", "
|
|
|
|
| 30 |
EXPOSE 7860
|
| 31 |
|
| 32 |
# Command to run the application
|
| 33 |
+
CMD ["python", "telegram_bot1.py"]
|
telegram_bot.py
CHANGED
|
@@ -36,6 +36,8 @@ class WeBookBot:
|
|
| 36 |
"User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36",
|
| 37 |
}
|
| 38 |
self.monitor = EventMonitor(self)
|
|
|
|
|
|
|
| 39 |
|
| 40 |
def _get_events_payload(self, category=None, date_filter=None, price_min=None, price_max=None, zones=None, country_code="SA", limit=20, skip=0):
|
| 41 |
"""Generate the payload for the events API request with flexible filtering using the getShows query."""
|
|
@@ -217,68 +219,156 @@ class WeBookBot:
|
|
| 217 |
|
| 218 |
async def start_command(self, update: Update, context: ContextTypes.DEFAULT_TYPE):
|
| 219 |
"""Handle the /start command"""
|
| 220 |
-
# Store default filters in context user_data if they don't exist
|
| 221 |
-
if 'category' not in context.user_data:
|
| 222 |
-
context.user_data['category'] = None # Or a default category slug if needed
|
| 223 |
-
if 'date_filter' not in context.user_data:
|
| 224 |
-
context.user_data['date_filter'] = 'today' # Default date filter
|
| 225 |
-
# Add placeholders for other filters
|
| 226 |
-
if 'price_min' not in context.user_data:
|
| 227 |
-
context.user_data['price_min'] = None
|
| 228 |
-
if 'price_max' not in context.user_data:
|
| 229 |
-
context.user_data['price_max'] = None
|
| 230 |
-
if 'zones' not in context.user_data:
|
| 231 |
-
context.user_data['zones'] = None # Or a list of default zone slugs if needed
|
| 232 |
-
if 'country_code' not in context.user_data:
|
| 233 |
-
context.user_data['country_code'] = 'SA' # Default country
|
| 234 |
-
|
| 235 |
keyboard = [
|
| 236 |
[
|
| 237 |
-
InlineKeyboardButton("
|
| 238 |
-
InlineKeyboardButton("
|
| 239 |
-
InlineKeyboardButton("📅 هذا الأسبوع", callback_data='date_this_week')
|
| 240 |
-
],
|
| 241 |
-
[
|
| 242 |
-
InlineKeyboardButton("🎁 العروض", callback_data='category_offers'),
|
| 243 |
-
InlineKeyboardButton("⚽ الرياضة", callback_data='category_sports-events')
|
| 244 |
],
|
| 245 |
[
|
| 246 |
-
InlineKeyboardButton("
|
| 247 |
-
InlineKeyboardButton("
|
| 248 |
],
|
| 249 |
[
|
| 250 |
-
InlineKeyboardButton("
|
| 251 |
-
|
| 252 |
-
],
|
| 253 |
-
[
|
| 254 |
-
InlineKeyboardButton("🍽️ المطاعم", callback_data='category_restaurant-and-cafe')
|
| 255 |
-
],
|
| 256 |
-
# Add buttons for other filters would be complex here.
|
| 257 |
-
# You might consider a "Filter Options" button that leads to a new message
|
| 258 |
-
# with more specific filter buttons or instructions.
|
| 259 |
-
# For now, we just keep the category and date buttons.
|
| 260 |
-
[
|
| 261 |
-
InlineKeyboardButton("✅ Show Events with Current Filters", callback_data='show_events')
|
| 262 |
-
],
|
| 263 |
-
[
|
| 264 |
-
InlineKeyboardButton("🔄 Reset Filters", callback_data='reset_filters')
|
| 265 |
-
],
|
| 266 |
-
[
|
| 267 |
-
InlineKeyboardButton("🔍 Start Event Monitoring", callback_data='start_monitoring'),
|
| 268 |
-
InlineKeyboardButton("⏹️ Stop Monitoring", callback_data='stop_monitoring')
|
| 269 |
-
]
|
| 270 |
]
|
| 271 |
reply_markup = InlineKeyboardMarkup(keyboard)
|
| 272 |
|
| 273 |
-
# Display current filters in the message
|
| 274 |
-
current_filters_text = self._get_current_filters_text(context.user_data)
|
| 275 |
-
|
| 276 |
await update.message.reply_text(
|
| 277 |
-
|
| 278 |
-
|
| 279 |
reply_markup=reply_markup
|
| 280 |
)
|
| 281 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 282 |
async def button_callback(self, update: Update, context: ContextTypes.DEFAULT_TYPE):
|
| 283 |
"""Handle button callbacks"""
|
| 284 |
query = update.callback_query
|
|
@@ -287,8 +377,18 @@ class WeBookBot:
|
|
| 287 |
try:
|
| 288 |
callback_data = query.data
|
| 289 |
|
| 290 |
-
|
| 291 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 292 |
selected_category = callback_data.replace('category_', '')
|
| 293 |
# Toggle category selection (assuming single selection for simplicity for now)
|
| 294 |
if context.user_data.get('category') == selected_category:
|
|
@@ -475,7 +575,7 @@ class WeBookBot:
|
|
| 475 |
|
| 476 |
# Reset skip to 0 for a new search
|
| 477 |
context.user_data['skip'] = 0
|
| 478 |
-
current_limit =
|
| 479 |
|
| 480 |
payload = self._get_events_payload(
|
| 481 |
category=current_category,
|
|
@@ -612,7 +712,7 @@ class WeBookBot:
|
|
| 612 |
logger.error(f"Error processing callback: {str(e)}")
|
| 613 |
logger.error(f"Response content: {response.text if 'response' in locals() else 'No response'}")
|
| 614 |
await query.edit_message_text(
|
| 615 |
-
"Sorry, there was an error
|
| 616 |
)
|
| 617 |
|
| 618 |
async def _start_monitoring_setup(self, query: CallbackQuery, context: ContextTypes.DEFAULT_TYPE):
|
|
@@ -756,9 +856,12 @@ class WeBookBot:
|
|
| 756 |
|
| 757 |
# Add handlers
|
| 758 |
application.add_handler(CommandHandler("start", self.start_command))
|
|
|
|
|
|
|
|
|
|
|
|
|
| 759 |
application.add_handler(CallbackQueryHandler(self.button_callback))
|
| 760 |
-
|
| 761 |
-
application.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, self.handle_event_number_input)) # Listen for non-command text
|
| 762 |
|
| 763 |
# Start the bot
|
| 764 |
logger.info("Starting bot...")
|
|
|
|
| 36 |
"User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36",
|
| 37 |
}
|
| 38 |
self.monitor = EventMonitor(self)
|
| 39 |
+
# Add storage for user credentials
|
| 40 |
+
self.user_credentials = {}
|
| 41 |
|
| 42 |
def _get_events_payload(self, category=None, date_filter=None, price_min=None, price_max=None, zones=None, country_code="SA", limit=20, skip=0):
|
| 43 |
"""Generate the payload for the events API request with flexible filtering using the getShows query."""
|
|
|
|
| 219 |
|
| 220 |
async def start_command(self, update: Update, context: ContextTypes.DEFAULT_TYPE):
|
| 221 |
"""Handle the /start command"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 222 |
keyboard = [
|
| 223 |
[
|
| 224 |
+
InlineKeyboardButton("🔑 Login to WeBook", callback_data='login_webook'),
|
| 225 |
+
InlineKeyboardButton("ℹ️ Help", callback_data='help')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 226 |
],
|
| 227 |
[
|
| 228 |
+
InlineKeyboardButton("👤 Set Account Info", callback_data='set_account_info'),
|
| 229 |
+
InlineKeyboardButton("📊 Account Status", callback_data='account_status')
|
| 230 |
],
|
| 231 |
[
|
| 232 |
+
InlineKeyboardButton("🎫 Browse Events", callback_data='browse_events')
|
| 233 |
+
]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 234 |
]
|
| 235 |
reply_markup = InlineKeyboardMarkup(keyboard)
|
| 236 |
|
|
|
|
|
|
|
|
|
|
| 237 |
await update.message.reply_text(
|
| 238 |
+
'Welcome to WeBook Events Bot! 🎉\n'
|
| 239 |
+
'Please select an option:',
|
| 240 |
reply_markup=reply_markup
|
| 241 |
)
|
| 242 |
|
| 243 |
+
async def set_account_info_command(self, update: Update, context: ContextTypes.DEFAULT_TYPE):
|
| 244 |
+
"""Handle the /setinfoaccountwebook command"""
|
| 245 |
+
await update.message.reply_text(
|
| 246 |
+
"Please enter your WeBook credentials in the following format:\n"
|
| 247 |
+
"email:your.email@example.com\n"
|
| 248 |
+
"password:yourpassword"
|
| 249 |
+
)
|
| 250 |
+
context.user_data['awaiting_credentials'] = True
|
| 251 |
+
|
| 252 |
+
async def account_status_command(self, update: Update, context: ContextTypes.DEFAULT_TYPE):
|
| 253 |
+
"""Handle the /stateloginwebook command"""
|
| 254 |
+
user_id = update.effective_user.id
|
| 255 |
+
if user_id in self.user_credentials:
|
| 256 |
+
await update.message.reply_text(
|
| 257 |
+
f"✅ WeBook Account Status:\n"
|
| 258 |
+
f"Email: {self.user_credentials[user_id]['email']}\n"
|
| 259 |
+
f"Status: Logged In"
|
| 260 |
+
)
|
| 261 |
+
else:
|
| 262 |
+
await update.message.reply_text(
|
| 263 |
+
"❌ No WeBook account configured.\n"
|
| 264 |
+
"Use /setinfoaccountwebook to set up your account."
|
| 265 |
+
)
|
| 266 |
+
|
| 267 |
+
async def help_command(self, update: Update, context: ContextTypes.DEFAULT_TYPE):
|
| 268 |
+
"""Handle the /help command"""
|
| 269 |
+
help_text = (
|
| 270 |
+
"🤖 *WeBook Bot Commands*\n\n"
|
| 271 |
+
"/start - Start the bot and show main menu\n"
|
| 272 |
+
"/setinfoaccountwebook - Set your WeBook account credentials\n"
|
| 273 |
+
"/stateloginwebook - Check your WeBook account status\n"
|
| 274 |
+
"/help - Show this help message\n"
|
| 275 |
+
"/info - Show bot information\n\n"
|
| 276 |
+
"To use the bot:\n"
|
| 277 |
+
"1. Set your WeBook credentials using /setinfoaccountwebook\n"
|
| 278 |
+
"2. Login using the 'Login to WeBook' button\n"
|
| 279 |
+
"3. Browse and book events!"
|
| 280 |
+
)
|
| 281 |
+
await update.message.reply_text(help_text, parse_mode='Markdown')
|
| 282 |
+
|
| 283 |
+
async def info_command(self, update: Update, context: ContextTypes.DEFAULT_TYPE):
|
| 284 |
+
"""Handle the /info command"""
|
| 285 |
+
info_text = (
|
| 286 |
+
"🤖 *WeBook Bot Information*\n\n"
|
| 287 |
+
"Version: 1.0.0\n"
|
| 288 |
+
"Description: A Telegram bot for browsing and booking events on WeBook\n"
|
| 289 |
+
"Features:\n"
|
| 290 |
+
"- Browse events by category\n"
|
| 291 |
+
"- Filter events by date\n"
|
| 292 |
+
"- Book events automatically\n"
|
| 293 |
+
"- Monitor for new events\n"
|
| 294 |
+
"- Account management"
|
| 295 |
+
)
|
| 296 |
+
await update.message.reply_text(info_text, parse_mode='Markdown')
|
| 297 |
+
|
| 298 |
+
async def handle_credentials_input(self, update: Update, context: ContextTypes.DEFAULT_TYPE):
|
| 299 |
+
"""Handle user input for WeBook credentials"""
|
| 300 |
+
if not context.user_data.get('awaiting_credentials'):
|
| 301 |
+
return
|
| 302 |
+
|
| 303 |
+
try:
|
| 304 |
+
text = update.message.text.strip()
|
| 305 |
+
email = None
|
| 306 |
+
password = None
|
| 307 |
+
|
| 308 |
+
for line in text.split('\n'):
|
| 309 |
+
if line.startswith('email:'):
|
| 310 |
+
email = line.split(':', 1)[1].strip()
|
| 311 |
+
elif line.startswith('password:'):
|
| 312 |
+
password = line.split(':', 1)[1].strip()
|
| 313 |
+
|
| 314 |
+
if email and password:
|
| 315 |
+
user_id = update.effective_user.id
|
| 316 |
+
self.user_credentials[user_id] = {
|
| 317 |
+
'email': email,
|
| 318 |
+
'password': password
|
| 319 |
+
}
|
| 320 |
+
context.user_data['awaiting_credentials'] = False
|
| 321 |
+
await update.message.reply_text(
|
| 322 |
+
"✅ WeBook credentials saved successfully!\n"
|
| 323 |
+
"You can now use the 'Login to WeBook' button to log in."
|
| 324 |
+
)
|
| 325 |
+
else:
|
| 326 |
+
await update.message.reply_text(
|
| 327 |
+
"❌ Invalid format. Please use:\n"
|
| 328 |
+
"email:your.email@example.com\n"
|
| 329 |
+
"password:yourpassword"
|
| 330 |
+
)
|
| 331 |
+
except Exception as e:
|
| 332 |
+
logger.error(f"Error handling credentials: {e}")
|
| 333 |
+
await update.message.reply_text("❌ Error saving credentials. Please try again.")
|
| 334 |
+
|
| 335 |
+
async def handle_login(self, query: CallbackQuery, context: ContextTypes.DEFAULT_TYPE):
|
| 336 |
+
"""Handle WeBook login button click"""
|
| 337 |
+
user_id = query.from_user.id
|
| 338 |
+
if user_id not in self.user_credentials:
|
| 339 |
+
await query.edit_message_text(
|
| 340 |
+
"❌ No WeBook credentials found.\n"
|
| 341 |
+
"Please use /setinfoaccountwebook to set up your account first."
|
| 342 |
+
)
|
| 343 |
+
return
|
| 344 |
+
|
| 345 |
+
try:
|
| 346 |
+
# Create login instance
|
| 347 |
+
login = WeBookLogin(
|
| 348 |
+
email=self.user_credentials[user_id]['email'],
|
| 349 |
+
password=self.user_credentials[user_id]['password']
|
| 350 |
+
)
|
| 351 |
+
|
| 352 |
+
# Attempt login
|
| 353 |
+
page = login.login()
|
| 354 |
+
|
| 355 |
+
if page:
|
| 356 |
+
await query.edit_message_text(
|
| 357 |
+
"✅ Successfully logged in to WeBook!\n"
|
| 358 |
+
"You can now browse and book events."
|
| 359 |
+
)
|
| 360 |
+
# Store the page object for future use
|
| 361 |
+
context.user_data['webook_page'] = page
|
| 362 |
+
else:
|
| 363 |
+
await query.edit_message_text(
|
| 364 |
+
"❌ Login failed. Please check your credentials and try again."
|
| 365 |
+
)
|
| 366 |
+
except Exception as e:
|
| 367 |
+
logger.error(f"Login error: {e}")
|
| 368 |
+
await query.edit_message_text(
|
| 369 |
+
"❌ An error occurred during login. Please try again later."
|
| 370 |
+
)
|
| 371 |
+
|
| 372 |
async def button_callback(self, update: Update, context: ContextTypes.DEFAULT_TYPE):
|
| 373 |
"""Handle button callbacks"""
|
| 374 |
query = update.callback_query
|
|
|
|
| 377 |
try:
|
| 378 |
callback_data = query.data
|
| 379 |
|
| 380 |
+
if callback_data == 'login_webook':
|
| 381 |
+
await self.handle_login(query, context)
|
| 382 |
+
elif callback_data == 'help':
|
| 383 |
+
await self.help_command(update, context)
|
| 384 |
+
elif callback_data == 'set_account_info':
|
| 385 |
+
await self.set_account_info_command(update, context)
|
| 386 |
+
elif callback_data == 'account_status':
|
| 387 |
+
await self.account_status_command(update, context)
|
| 388 |
+
elif callback_data == 'browse_events':
|
| 389 |
+
# Show the original event browsing interface
|
| 390 |
+
await self.start_command(update, context)
|
| 391 |
+
elif callback_data.startswith('category_'):
|
| 392 |
selected_category = callback_data.replace('category_', '')
|
| 393 |
# Toggle category selection (assuming single selection for simplicity for now)
|
| 394 |
if context.user_data.get('category') == selected_category:
|
|
|
|
| 575 |
|
| 576 |
# Reset skip to 0 for a new search
|
| 577 |
context.user_data['skip'] = 0
|
| 578 |
+
current_limit = 10
|
| 579 |
|
| 580 |
payload = self._get_events_payload(
|
| 581 |
category=current_category,
|
|
|
|
| 712 |
logger.error(f"Error processing callback: {str(e)}")
|
| 713 |
logger.error(f"Response content: {response.text if 'response' in locals() else 'No response'}")
|
| 714 |
await query.edit_message_text(
|
| 715 |
+
"Sorry, there was an error processing your request. Please try again later."
|
| 716 |
)
|
| 717 |
|
| 718 |
async def _start_monitoring_setup(self, query: CallbackQuery, context: ContextTypes.DEFAULT_TYPE):
|
|
|
|
| 856 |
|
| 857 |
# Add handlers
|
| 858 |
application.add_handler(CommandHandler("start", self.start_command))
|
| 859 |
+
application.add_handler(CommandHandler("setinfoaccountwebook", self.set_account_info_command))
|
| 860 |
+
application.add_handler(CommandHandler("stateloginwebook", self.account_status_command))
|
| 861 |
+
application.add_handler(CommandHandler("help", self.help_command))
|
| 862 |
+
application.add_handler(CommandHandler("info", self.info_command))
|
| 863 |
application.add_handler(CallbackQueryHandler(self.button_callback))
|
| 864 |
+
application.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, self.handle_credentials_input))
|
|
|
|
| 865 |
|
| 866 |
# Start the bot
|
| 867 |
logger.info("Starting bot...")
|