Mohammed Foud commited on
Commit
deb2780
·
1 Parent(s): 7585a32

Add application file

Browse files
Files changed (2) hide show
  1. Dockerfile +1 -1
  2. 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", "telegram_bot.py"]
 
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("☀️ اليوم", callback_data='date_today'),
238
- InlineKeyboardButton("🗓️ غداً", callback_data='date_tomorrow'),
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("🎭 المسرح والفنون الأدائية", callback_data='category_theater-and-performing-arts'),
247
- InlineKeyboardButton("⛰️ الأنشطة والمغامرات", callback_data='category_activities-adventures')
248
  ],
249
  [
250
- InlineKeyboardButton("🎶 موسیقی", callback_data='category_music-events'),
251
- InlineKeyboardButton("✨ التجارب", callback_data='category_experience')
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
- f'Welcome to WeBook Events Bot! 🎉\n'
278
- f'Please select filters or "Show Events":\n{current_filters_text}',
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
- # --- Handle Filter Button Presses ---
291
- if callback_data.startswith('category_'):
 
 
 
 
 
 
 
 
 
 
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 = 20
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 fetching the events. Please try again later."
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
- # Add a MessageHandler for text input to handle event number selection
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...")