Mohammed Foud commited on
Commit
9c3fa19
·
1 Parent(s): f644c01

Fix some Bugs and add some Feathers

Browse files
checkout.py ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import requests
2
+
3
+ url = "https://api.webook.com/api/v2/checkout?lang=en"
4
+
5
+ headers = {
6
+ "authority": "api.webook.com",
7
+ "accept": "application/json",
8
+ "accept-encoding": "gzip, deflate, br, zstd",
9
+ "accept-language": "en-US,en;q=0.9,ar;q=0.8",
10
+ "authorization": "Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImp0aSI6ImIxZGIyZmJkOThkNGMzNWI1NjA3MzU1YjgxMGIyZDg2YjEyMjFkYzE2NjEyYTI1N2YyOGMxODk3NGY5NjRkNGY4NTg3MDcxMDMxOTBhZTlmIn0.eyJhdWQiOiI2NzhmYmQ3MDRiMTk1NTg5MTEwYzczZDIiLCJqdGkiOiJiMWRiMmZiZDk4ZDRjMzViNTYwNzM1NWI4MTBiMmQ4NmIxMjIxZGMxNjYxMmEyNTdmMjhjMTg5NzRmOTY0ZDRmODU4NzA3MTAzMTkwYWU5ZiIsImlhdCI6MTc1MDM3Mjg2MiwibmJmIjoxNzUwMzcyODYyLCJleHAiOjE3NTA5Nzc2NjIsInN1YiI6IjY4NTQ5MWZjNzQwZmNlMWU5NDA0YTQyYiIsInNjb3BlcyI6W119.ih4ftU7OFrRV4SCyMTYFDrStem4gzYEnX16eM_ikCZKtVHIftbwIIDlBKUaNb5ZukgkFyhtUljYUBBghQT2xDasE1LihSv8jRJAwo8nujqa8QuG9S6LOAnbp7W3m-8UcfvzkkK-oL4ntA4P_tEzhfY54Ln_qev1ov0-sLU_j2ozonXpR6PFO01MXqLE2oqUqP47mvr2aKII3EH-VXgMoeUfF1dD4Q-uoq9zdyg_wFy8HejDvsVVvUTEDKTGaOajsIJKb4b5OiIa78C8xvtKwwBBvYjuOtXWmYDQEo9pIy_bmX4Rkh1GDj86XqwmRilnOnwrqO2ZIF-6aNA4LPYPTQiuPh2hSR5b9BBmhzDamEvk59sD9qdJ2tMAJYd7TuZD7Ej4FFPmXoJ9b8XEHwo-2QupwU6Z50WGRBFmW30tmSGGogFRw-tIGKODhRAtEhijuhiDvlE5TLPU5bxDSLsxT_KeQ6CggbwZSbSJjqMlUij2Afh2r7UU16-3VBhQGeomSjYS59U9KBrkEXqE3jsihTEyzeO6KLsv_GyW71bu5X1XIt8JwBfQlaV1Cje_rmQD7NmHb_xUVTbyIScvXD3X60ErEZlto35dP6HK5IrhzMkwWb5Dii9v55aLgKutO6m8mtj1Ifl0EHpG9fdS5a3oF71jAlQv7f0RbwkCPkniCn7U",
11
+ "content-type": "application/json",
12
+ "origin": "https://webook.com",
13
+ "priority": "u=1, i",
14
+ "referer": "https://webook.com/",
15
+ "sec-ch-ua": '"Google Chrome";v="131", "Chromium";v="131", "Not:A-Brand";v="24"',
16
+ "sec-ch-ua-mobile": "?0",
17
+ "sec-ch-ua-platform": '"Linux"',
18
+ "sec-fetch-dest": "empty",
19
+ "sec-fetch-mode": "cors",
20
+ "sec-fetch-site": "same-site",
21
+ "token": "e9aac1f2f0b6c07d6be070ed14829de684264278359148d6a582ca65a50934d2",
22
+ "user-agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36",
23
+ }
24
+
25
+ payload = {
26
+ "event_id": "684fa2428a13cd16d70ba1f3",
27
+ "redirect": "https://webook.com/en/payment-success",
28
+ "redirect_failed": "https://webook.com/en/payment-failed",
29
+ "booking_source": "rs-web",
30
+ "lang": "en",
31
+ "payment_method": "credit_card",
32
+ "is_wallet": False,
33
+ "saudi_redeem": None,
34
+ "is_mada": False,
35
+ "is_amex": False,
36
+ "perks": [],
37
+ "merchandise": [],
38
+ "addons": [],
39
+ "vouchers": [],
40
+ "tickets": [{"qty": 5, "id": "684fa3dab0ca95373b0083bf"}],
41
+ "captcha": "03AFcWeA7b63YrZRZwQHUDsy0C-CrF9NaIwGTMTYl5LT2rIhQWtrY1wXwlLBTadln0vttRlKz1aaaC4rwid6mlfexaZMGRPGPOKfm4nPrx8Ph1gCJVh9UcsO-4Z7zG-RHU0Oa0tEBVQsS2-ixbU8KViREZMYT2egdWd-CefIm1FDe_gs92ikGaGGK3j8k23dK13AJXqYr3RYhscx1fe7BYTemdGahxBz65q-U3_ZDAN1_CHGugs2F0nNz527zPZDAOGRxjmOw1Lz4Zs52ibb6JT9ddLIiQ4AEfF_CYWlxnkzXfz76tBQgvRkuLJNRw2KNH0IcQioJlJD3XUflruwZMdTS-q3QrMxHgeuvDxlziT_udnQ8dXKNytIT4gHfD9mIflf2GcR1zT1lM8FUl5nNElpqICGEhDRYMBFQcm3ejVZdLTlWfiP3AwHSLuFF8wBBSvwfhwUqvG7Z-HgRTIz8qbvfA9DBRRALctHca8JmHkizGM1AH2z0rA6ac5cS8ZnEZ5FtRVeE9APmdfK30WMJdmlZ90c22qbL1eT6EiOn3r6baSele90zs2aUAj-LFtbbhHytruxA6o9Fmjc5ObNGhVSAqV2Tz9FjKbQ1JmX4dTbDc5fafHh8WdJIypPUmAy4gO2JA3UvAC3VCijGtL8s5yEkdx5rCkDScNtIDcJuE1BJbib1lBs9nqQTxqCRPIjz3maVS4BsJf17DL76pi0xqZPT5SbN_N1ZmKyS_UJmlZah1AdGjRBfrNG3zPwJdCEP9o41tPXqhtOg5_a7Yf6yo5dhRtAEdgj4YdIaMqh8oCik5dengme3A8sG6HDxnyS116uxnELdxlFjfFCj-Rf-8OFmNJ-hBR0aButrqP2FmYeyKI96IK8VPMGV85GZtlyYnoqcYJNv_8BBD8LhTtjeFoyUTtF0c97IP4H3MSwNMqiKYHORDi_p2zvapxWcBmSM3pluFnIYyIcz2es-l5Tf7reQYwHif0-eR1Dw8QojoT_As-5uW1ijX58as8-bZDhnBIfQ3mQCzz_FSf7h9UdNs0Zuqm8PK3ne1KtfEQlGPDdwBViqnh7vepN-au48jdc-wQG71l6-yB7FiJRydTVxWfrxxmbaGOVD1FRT40Ba-wKHvogx4m27TLGgHfufwrh6TVzQHKT9cFcv1QGdVjvpgFxbpU2Og6TCJGOEwWUkwoH8MD8uQVm2YwbVTteD1j_aakVvzOx1zw4RXGvOg_iZ1tHZYohFCb0i19kDLBytTt1bAckujb8dNpARC5poPLsZiiHCv5hDAxTPyCDlImB-_i729nL9gvYQSJTFlre_KMh6X95LIgT7QsddpuXzpGuXSzwNtTNbGTfOvKbS2uOy-gu0TMJxJ3P4SHAvIVxoH31_dBFozS-_J0MwJpiYgO1OSZG_kBsKEuoMHIrFRK_L1s6QeLJ7EnRBUjc9PqcuwPxDahRpsJv3jygucAo_QGmp_7pWz4XvlLGtLzcQh9EUZgahbjAaXA7uWqZz5CTlNSxCJJAmSptSZEmkoLk2MDUhohj5TQaGYj7VTAUPPbhCUjBiTlOsmqC-9E40HZ-QK0r71WWLVpYv465wqhP1zVs3IU-WufxC6y5IHDMM_2GbFcExiTDBdZ_37SFpuNP5TjKlNgXyeno2BFXalkgSIVIbRLIGlX9ZhvJSvxhg8KKfsH95ZUQ_YJueCrcp5PUcxeImkQVkKUU5Y8c48kaRC09IUyEJwP8p08MeOJ3aLr6OYA3GttlPOMxYMERbWhpAHWIs1GelY3dDADGgmzVoABH8G0QNigb_Am2lM_eEdW88hA7BmDjQXGvDj7nv4rFKqfg8vv6B7hfDpnnCJo4zfuOnUCt4CALPRpns6amCYtUMquvtPyAYo-Sm5efsyvdOfAs17pMDvqCi0_Q3OLI2YkP6toc3f2BHqvUnTOmXFabp6Jk-zskeJ8vI6Nd2UCkjR2FEXi2SguWeoWr1faWUqZ2_PhI_-Cw6bp-o81F0ECF01hJA9_jpi9G9k3y136pVIdoH00HMJzmny2xA",
42
+ "tpp_cart_id": None,
43
+ "app_source": "rs",
44
+ "utm_wbk_wa_session_id": "5693c764-96b1-48e7-b595-beed4f50175f"
45
+ }
46
+
47
+ response = requests.post(url, headers=headers, json=payload)
48
+
49
+ print(f"Status Code: {response.status_code}")
50
+ print("Response:")
51
+ print(response.json())
src/bots/handlers/webookHandlers.ts CHANGED
@@ -127,6 +127,19 @@ export async function handleBookByUrlText(ctx: BotContext) {
127
  state.step = 2;
128
  bookByUrlStates.set(telegramId, state);
129
  console.log('[BookByUrl] URL accepted for', telegramId, 'fixedUrl:', fixedUrl);
 
 
 
 
 
 
 
 
 
 
 
 
 
130
  const reply = await ctx.reply(
131
  messageManager.getMessage('webook_url_accepted')
132
  .replace('{original_url}', url)
@@ -257,30 +270,136 @@ export function setupWeBookBookByUrlPaymentHandlers(bot: any) {
257
  */
258
  export async function handleWeBookEventInfoByUrl(ctx: BotContext) {
259
  const message = ctx.message;
260
- if (!message || typeof message !== 'object' || !('text' in message) || typeof message.text !== 'string') return false;
261
  const url = message.text.trim();
262
- if (!isValidWeBookEventUrl(url)) return false;
263
- await ctx.reply('Fetching event information...');
264
  const event = await getEventDetailsByUrl(url);
265
  if (!event) {
 
266
  await ctx.reply('Could not find event information for this URL.');
267
- return true;
268
  }
269
- // Format event info
270
- let info = `<b>${event.title || ''}</b>\n`;
271
- if (event.subtitle) info += `<i>${event.subtitle}</i>\n`;
272
- if (event.startingPrice) info += `Price: <b>${event.startingPrice} ${event.currencyCode || ''}</b>\n`;
273
- if (event.schedule && event.schedule.openDateTime) info += `Start: <b>${event.schedule.openDateTime}</b>\n`;
274
- if (event.schedule && event.schedule.closeDateTime) info += `End: <b>${event.schedule.closeDateTime}</b>\n`;
275
- if (event.location && event.location.title) info += `Location: <b>${event.location.title}</b>\n`;
276
- if (event.description && event.description.json && event.description.json.content && event.description.json.content.length > 0) {
277
- const desc = event.description.json.content.map((c: any) => c.content && c.content[0] && c.content[0].value).filter(Boolean).join(' ');
278
- if (desc) info += `\n${desc}`;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
279
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
280
  if (event.image11 && event.image11.url) {
281
  await ctx.replyWithPhoto({ url: event.image11.url }, { caption: info, parse_mode: 'HTML' });
282
  } else {
283
  await ctx.reply(info, { parse_mode: 'HTML' });
284
  }
285
- return true;
 
286
  }
 
127
  state.step = 2;
128
  bookByUrlStates.set(telegramId, state);
129
  console.log('[BookByUrl] URL accepted for', telegramId, 'fixedUrl:', fixedUrl);
130
+
131
+ // Send event info to user and check if sold out
132
+ const event = await handleWeBookEventInfoByUrl(ctx);
133
+ if (event && event.buttonLabel === 'Sold out') {
134
+ await ctx.reply('This event is sold out. Cannot proceed with booking.', {
135
+ parse_mode: 'HTML',
136
+ ...getBackToMainMenuButton()
137
+ });
138
+ bookByUrlStates.delete(telegramId);
139
+ return true;
140
+ }
141
+
142
+
143
  const reply = await ctx.reply(
144
  messageManager.getMessage('webook_url_accepted')
145
  .replace('{original_url}', url)
 
270
  */
271
  export async function handleWeBookEventInfoByUrl(ctx: BotContext) {
272
  const message = ctx.message;
273
+ if (!message || typeof message !== 'object' || !('text' in message) || typeof message.text !== 'string') return null;
274
  const url = message.text.trim();
275
+ if (!isValidWeBookEventUrl(url)) return null;
276
+ const loadingMsg = await ctx.reply('Fetching event information...');
277
  const event = await getEventDetailsByUrl(url);
278
  if (!event) {
279
+ await ctx.deleteMessage(loadingMsg.message_id);
280
  await ctx.reply('Could not find event information for this URL.');
281
+ return null;
282
  }
283
+ // Delete loading message
284
+
285
+ // Format all event info
286
+ let info = `<b>Event Information</b>\n`;
287
+ info += `<b>Title:</b> ${event.title || 'None'}\n`;
288
+ // info += `<b>Subtitle:</b> ${event.subtitle || 'None'}\n`;
289
+ info += `<b>ID:</b> ${event.id || 'None'}\n`;
290
+ // info += `<b>Slug:</b> ${event.slug || 'None'}\n`;
291
+ // info += `<b>Ticketing URL Slug:</b> ${event.ticketingUrlSlug || 'None'}\n`;
292
+ info += `<b>Starting Price:</b> ${event.startingPrice || 'None'} ${event.currencyCode || ''}\n`;
293
+ // info += `<b>Is Streaming Event:</b> ${event.isStreamingEvent ? 'Yes' : 'No'}\n`;
294
+ // info += `<b>Zone Entry Included:</b> ${event.zoneEntryIncluded ? 'Yes' : 'No'}\n`;
295
+ // info += `<b>Streaming URL:</b> ${event.streamingUrl || 'None'}\n`;
296
+ // info += `<b>Button Label:</b> ${event.buttonLabel || 'None'}\n`;
297
+ // info += `<b>Card Button Label:</b> ${event.cardButtonLabel || 'None'}\n`;
298
+ info += `<b>Event Type:</b> ${event.eventType || 'None'}\n`;
299
+ // info += `<b>Auth Guard:</b> ${event.authGaurd ? 'Yes' : 'No'}\n`;
300
+ info += `<b>Button Link:</b> ${event.buttonLink || 'None'}\n`;
301
+ info += `<b>Is Coming Soon:</b> ${event.isComingSoon ? 'Yes' : 'No'}\n`;
302
+ // info += `<b>What To Know:</b> ${event.whatToKnow || 'None'}\n`;
303
+ // info += `<b>Special Promotion:</b> ${event.specialPromotion || 'None'}\n`;
304
+ // info += `<b>Show Resell Banner:</b> ${event.showResellBanner ? 'Yes' : 'No'}\n`;
305
+ // info += `<b>Organization Slug:</b> ${event.organizationSlug || 'None'}\n`;
306
+ // info += `<b>Visibility:</b> ${event.visibility || 'None'}\n`;
307
+
308
+ // // Images
309
+ // if (event.image11) {
310
+ // info += `<b>Image 1:</b> ${event.image11.url || 'None'} (${event.image11.title || ''})\n`;
311
+ // }
312
+ // if (event.image31) {
313
+ // info += `<b>Image 2:</b> ${event.image31.url || 'None'} (${event.image31.title || ''})\n`;
314
+ // }
315
+
316
+ // // Description
317
+ // if (event.description && event.description.json && event.description.json.content && event.description.json.content.length > 0) {
318
+ // const desc = event.description.json.content.map((c: any) => c.content && c.content[0] && c.content[0].value).filter(Boolean).join(' ');
319
+ // if (desc) info += `<b>Description:</b> ${desc}\n`;
320
+ // } else {
321
+ // info += `<b>Description:</b> None\n`;
322
+ // }
323
+
324
+ // // Schedule
325
+ // if (event.schedule) {
326
+ // info += `<b>Schedule:</b>\n`;
327
+ // info += `- Title: ${event.schedule.title || 'None'}\n`;
328
+ // info += `- Open Title: ${event.schedule.openTitle || 'None'}\n`;
329
+ // info += `- Open DateTime: ${event.schedule.openDateTime || 'None'}\n`;
330
+ // info += `- Close DateTime: ${event.schedule.closeDateTime || 'None'}\n`;
331
+ // info += `- Open Schedule Text: ${event.schedule.openScheduleText || 'None'}\n`;
332
+ // }
333
+
334
+ // // Season
335
+ // if (event.season) {
336
+ // info += `<b>Season:</b>\n`;
337
+ // info += `- Title: ${event.season.title || 'None'}\n`;
338
+ // info += `- Slug: ${event.season.slug || 'None'}\n`;
339
+ // }
340
+
341
+ // // Category
342
+ if (event.category) {
343
+ info += `<b>Category:</b>\n`;
344
+ // info += `- ID: ${event.category.id || 'None'}\n`;
345
+ info += `- Title: ${event.category.title || 'None'}\n`;
346
+ // info += `- Slug: ${event.category.slug || 'None'}\n`;
347
  }
348
+
349
+
350
+ // // Location
351
+ if (event.location) {
352
+ info += `<b>Location:</b>\n`;
353
+ // info += `- Title: ${event.location.title || 'None'}\n`;
354
+ info += `- Address: ${event.location.address || 'None'}\n`;
355
+ info += `- City: ${event.location.city || 'None'}\n`;
356
+ // info += `- Country Code: ${event.location.countryCode || 'None'}\n`;
357
+ // info += `- Section Header: ${event.location.seactionHeader || 'None'}\n`;
358
+ // if (event.location.location) {
359
+ // info += `- Latitude: ${event.location.location.lat || 'None'}\n`;
360
+ // info += `- Longitude: ${event.location.location.lon || 'None'}\n`;
361
+ // }
362
+ // info += `- Accessibility: ${event.location.accessibility || 'None'}\n`;
363
+ // if (event.location.banner) {
364
+ // info += `- Banner: ${event.location.banner.url || 'None'} (${event.location.banner.title || ''})\n`;
365
+ // }
366
+ }
367
+
368
+ // // SEO
369
+ // if (event.seo) {
370
+ // info += `<b>SEO:</b>\n`;
371
+ // info += `- Title: ${event.seo.title || 'None'}\n`;
372
+ // info += `- Description: ${event.seo.description || 'None'}\n`;
373
+ // info += `- Keywords: ${event.seo.keywords || 'None'}\n`;
374
+ // info += `- Noindex: ${event.seo.noindex ? 'Yes' : 'No'}\n`;
375
+ // if (event.seo.image) {
376
+ // info += `- Image: ${event.seo.image.url || 'None'} (${event.seo.image.title || ''})\n`;
377
+ // }
378
+ // }
379
+
380
+ // // CMS Tags
381
+ // if (event.cmsTagsCollection && event.cmsTagsCollection.items && event.cmsTagsCollection.items.length > 0) {
382
+ // info += `<b>CMS Tags:</b>\n`;
383
+ // for (const tag of event.cmsTagsCollection.items) {
384
+ // info += `- Title: ${tag.title || 'None'}\n`;
385
+ // info += ` Slug: ${tag.slug || 'None'}\n`;
386
+ // info += ` ID: ${tag.id || 'None'}\n`;
387
+ // if (tag.background) {
388
+ // info += ` Background: ${tag.background.url || 'None'} (${tag.background.title || ''})\n`;
389
+ // }
390
+ // if (tag.icon) {
391
+ // info += ` Icon: ${tag.icon.url || 'None'} (${tag.icon.title || ''})\n`;
392
+ // }
393
+ // }
394
+ // }
395
+
396
+
397
+ // Send image if available, else send info as text
398
  if (event.image11 && event.image11.url) {
399
  await ctx.replyWithPhoto({ url: event.image11.url }, { caption: info, parse_mode: 'HTML' });
400
  } else {
401
  await ctx.reply(info, { parse_mode: 'HTML' });
402
  }
403
+ await ctx.deleteMessage(loadingMsg.message_id);
404
+ return event;
405
  }
src/bots/services/WeBookBookingService.ts CHANGED
@@ -42,69 +42,69 @@ export async function bookTicketsForAccount(
42
  withPayment: boolean,
43
  ticketsObtained: number,
44
  ticketsNeeded: number,
45
- isLogin: boolean = false
46
  ): Promise<BookingResult> {
47
  let login: WeBookLogin | undefined;
48
  try {
49
  if (isLogin) {
50
- await ctx.reply(messageManager.getMessage('webook_logging_in').replace('{email}', account.email), { parse_mode: 'HTML' });
51
- login = new WeBookLogin(account.email, account.password, `${account.id}`);
52
- const page = await login.login();
53
- if (!page || typeof page !== 'object') {
54
- await ctx.reply(messageManager.getMessage('webook_login_failed').replace('{email}', account.email), { parse_mode: 'HTML' });
55
- return { success: false, account: account.email };
56
- }
57
- await ctx.reply(messageManager.getMessage('webook_attempting_booking').replace('{email}', account.email), { parse_mode: 'HTML' });
58
- const booking = new WeBookBooking(page);
59
- const bookingResult = await booking.bookEvent(eventUrl, withPayment);
60
- if (withPayment) {
61
- if (typeof bookingResult === 'number') {
62
- const bookedCount = bookingResult;
63
- if (bookedCount > 0) {
64
- await ctx.reply(messageManager.getMessage('webook_booking_success_auto')
65
- .replace('{tickets}', bookedCount.toString())
66
- .replace('{email}', account.email)
67
- .replace('{total_obtained}', (ticketsObtained + bookedCount).toString())
68
- .replace('{total_needed}', ticketsNeeded.toString()), { parse_mode: 'HTML' });
69
- return { success: true, tickets: bookedCount, account: account.email };
70
- } else {
71
- await ctx.reply(messageManager.getMessage('webook_booking_failed').replace('{email}', account.email), { parse_mode: 'HTML' });
72
- return { success: false, account: account.email };
73
- }
74
  }
75
- } else {
76
- if (typeof bookingResult === 'object' && bookingResult !== null && 'ticketsCount' in bookingResult) {
77
- const result = bookingResult as { ticketsCount: number, paymentUrl?: string };
78
- if (result.ticketsCount > 0) {
79
- if (result.paymentUrl) {
80
- await ctx.reply(
81
- messageManager.getMessage('webook_booking_success_manual_with_payment')
82
- .replace('{tickets}', result.ticketsCount.toString())
83
- .replace('{email}', account.email)
84
- .replace('{total_obtained}', (ticketsObtained + result.ticketsCount).toString())
85
- .replace('{total_needed}', ticketsNeeded.toString()),
86
- {
87
- parse_mode: 'HTML',
88
- ...Markup.inlineKeyboard([
89
- [Markup.button.url('Complete Payment', result.paymentUrl)],
90
- [Markup.button.callback('🔙 Back to Menu', 'webook_back_to_menu')]
91
- ])
92
- }
93
- );
94
- }
95
- await ctx.reply(messageManager.getMessage('webook_booking_success_manual')
96
- .replace('{tickets}', result.ticketsCount.toString())
97
- .replace('{email}', account.email)
98
- .replace('{total_obtained}', (ticketsObtained + result.ticketsCount).toString())
99
- .replace('{total_needed}', ticketsNeeded.toString()), { parse_mode: 'HTML' });
100
- return { success: true, tickets: result.ticketsCount, account: account.email, paymentUrl: result.paymentUrl };
101
- } else {
102
- await ctx.reply(messageManager.getMessage('webook_booking_failed').replace('{email}', account.email), { parse_mode: 'HTML' });
103
- return { success: false, account: account.email };
104
  }
 
 
 
 
 
 
 
 
 
105
  }
106
  }
107
- return { success: false, account: account.email };
 
108
  } else {
109
  // No login, use direct booking
110
  await ctx.reply(messageManager.getMessage('webook_attempting_booking').replace('{email}', account.email), { parse_mode: 'HTML' });
 
42
  withPayment: boolean,
43
  ticketsObtained: number,
44
  ticketsNeeded: number,
45
+ isLogin: boolean = true
46
  ): Promise<BookingResult> {
47
  let login: WeBookLogin | undefined;
48
  try {
49
  if (isLogin) {
50
+ await ctx.reply(messageManager.getMessage('webook_logging_in').replace('{email}', account.email), { parse_mode: 'HTML' });
51
+ login = new WeBookLogin(account.email, account.password, `${account.id}`);
52
+ const page = await login.login();
53
+ if (!page || typeof page !== 'object') {
54
+ await ctx.reply(messageManager.getMessage('webook_login_failed').replace('{email}', account.email), { parse_mode: 'HTML' });
55
+ return { success: false, account: account.email };
56
+ }
57
+ await ctx.reply(messageManager.getMessage('webook_attempting_booking').replace('{email}', account.email), { parse_mode: 'HTML' });
58
+ const booking = new WeBookBooking(page);
59
+ const bookingResult = await booking.bookEvent(eventUrl, withPayment);
60
+ if (withPayment) {
61
+ if (typeof bookingResult === 'number') {
62
+ const bookedCount = bookingResult;
63
+ if (bookedCount > 0) {
64
+ await ctx.reply(messageManager.getMessage('webook_booking_success_auto')
65
+ .replace('{tickets}', bookedCount.toString())
66
+ .replace('{email}', account.email)
67
+ .replace('{total_obtained}', (ticketsObtained + bookedCount).toString())
68
+ .replace('{total_needed}', ticketsNeeded.toString()), { parse_mode: 'HTML' });
69
+ return { success: true, tickets: bookedCount, account: account.email };
70
+ } else {
71
+ await ctx.reply(messageManager.getMessage('webook_booking_failed').replace('{email}', account.email), { parse_mode: 'HTML' });
72
+ return { success: false, account: account.email };
 
73
  }
74
+ }
75
+ } else {
76
+ if (typeof bookingResult === 'object' && bookingResult !== null && 'ticketsCount' in bookingResult) {
77
+ const result = bookingResult as { ticketsCount: number, paymentUrl?: string };
78
+ if (result.ticketsCount > 0) {
79
+ if (result.paymentUrl) {
80
+ await ctx.reply(
81
+ messageManager.getMessage('webook_booking_success_manual_with_payment')
82
+ .replace('{tickets}', result.ticketsCount.toString())
83
+ .replace('{email}', account.email)
84
+ .replace('{total_obtained}', (ticketsObtained + result.ticketsCount).toString())
85
+ .replace('{total_needed}', ticketsNeeded.toString()),
86
+ {
87
+ parse_mode: 'HTML',
88
+ ...Markup.inlineKeyboard([
89
+ [Markup.button.url('Complete Payment', result.paymentUrl)],
90
+ [Markup.button.callback('🔙 Back to Menu', 'webook_back_to_menu')]
91
+ ])
92
+ }
93
+ );
 
 
 
 
 
 
 
 
 
94
  }
95
+ await ctx.reply(messageManager.getMessage('webook_booking_success_manual')
96
+ .replace('{tickets}', result.ticketsCount.toString())
97
+ .replace('{email}', account.email)
98
+ .replace('{total_obtained}', (ticketsObtained + result.ticketsCount).toString())
99
+ .replace('{total_needed}', ticketsNeeded.toString()), { parse_mode: 'HTML' });
100
+ return { success: true, tickets: result.ticketsCount, account: account.email, paymentUrl: result.paymentUrl };
101
+ } else {
102
+ await ctx.reply(messageManager.getMessage('webook_booking_failed').replace('{email}', account.email), { parse_mode: 'HTML' });
103
+ return { success: false, account: account.email };
104
  }
105
  }
106
+ }
107
+ return { success: false, account: account.email };
108
  } else {
109
  // No login, use direct booking
110
  await ctx.reply(messageManager.getMessage('webook_attempting_booking').replace('{email}', account.email), { parse_mode: 'HTML' });
src/index.ts CHANGED
@@ -35,9 +35,11 @@ async function startServer() {
35
  startServer();
36
 
37
 
 
38
  // To use the WeBook main function, uncomment the following line:
39
  // webookMain().catch(e => { console.error('WeBook Fatal error:', e); });
40
 
41
 
42
 
43
- // handleAddTelegrafBot("1e186256-fdd6-453f-8344-fd824660b8bd")
 
 
35
  startServer();
36
 
37
 
38
+
39
  // To use the WeBook main function, uncomment the following line:
40
  // webookMain().catch(e => { console.error('WeBook Fatal error:', e); });
41
 
42
 
43
 
44
+
45
+ handleAddTelegrafBot("1e186256-fdd6-453f-8344-fd824660b8bd")
src/webook/book.ts CHANGED
@@ -7,8 +7,8 @@ export class WeBookBooking extends WeBookBase {
7
  if (pageOrProfileDir && typeof pageOrProfileDir === 'object') {
8
  // page provided
9
  super(profileDirIfPage, pageOrProfileDir as Page);
10
- if (!this.page) {
11
- throw new Error('A Playwright page object must be provided to WeBookBooking');
12
  }
13
  } else {
14
  // only profileDir provided (or nothing)
 
7
  if (pageOrProfileDir && typeof pageOrProfileDir === 'object') {
8
  // page provided
9
  super(profileDirIfPage, pageOrProfileDir as Page);
10
+ if (!this.page) {
11
+ throw new Error('A Playwright page object must be provided to WeBookBooking');
12
  }
13
  } else {
14
  // only profileDir provided (or nothing)