Fix(background-booking): Body checks
All checks were successful
ktm-booking-bot/ktm-booking-bot/pipeline/head This commit looks good
All checks were successful
ktm-booking-bot/ktm-booking-bot/pipeline/head This commit looks good
This commit is contained in:
@@ -84,7 +84,8 @@ func (env *Env) BackgroundJobRunner() {
|
|||||||
} else { // if there's job to do
|
} else { // if there's job to do
|
||||||
// Create next run where it's not the past (either from old NextRun or now())
|
// Create next run where it's not the past (either from old NextRun or now())
|
||||||
timeNow := time.Now()
|
timeNow := time.Now()
|
||||||
startTime := time.Date(timeNow.Year(), timeNow.Month(), timeNow.Day(), 00, 10, 0, 0, timeNow.Location())
|
// Run at 12:13am
|
||||||
|
startTime := time.Date(timeNow.Year(), timeNow.Month(), timeNow.Day(), 00, 13, 0, 0, timeNow.Location())
|
||||||
endTime := startTime.Add(15 * time.Minute)
|
endTime := startTime.Add(15 * time.Minute)
|
||||||
|
|
||||||
if forceStartBooking || (timeNow.After(startTime) && timeNow.Before(endTime)) {
|
if forceStartBooking || (timeNow.After(startTime) && timeNow.Before(endTime)) {
|
||||||
@@ -232,7 +233,8 @@ func (env *Env) startBooking(job *Booking, username string, password string, cre
|
|||||||
currPage := getBookingSlots(browser, onwardDate, reverse)
|
currPage := getBookingSlots(browser, onwardDate, reverse)
|
||||||
log.Println("Booking page loaded.")
|
log.Println("Booking page loaded.")
|
||||||
|
|
||||||
currPage = selectBookingSlot(getBookingSlotCtx, currPage, timeCode)
|
delay := int(-5 + i)
|
||||||
|
currPage = selectBookingSlot(getBookingSlotCtx, currPage, timeCode, delay)
|
||||||
log.Println("Booking slot selected.")
|
log.Println("Booking slot selected.")
|
||||||
|
|
||||||
// Make sure page completes loading
|
// Make sure page completes loading
|
||||||
@@ -290,7 +292,10 @@ func (env *Env) startBooking(job *Booking, username string, password string, cre
|
|||||||
|
|
||||||
<-filledPassengerDetailContext.Done()
|
<-filledPassengerDetailContext.Done()
|
||||||
|
|
||||||
passthroughLaggingPage = chooseAndMakePayment(timerCtx, creditCardType, creditCard, creditCardCVV, creditCardExpiry, browser, page)
|
envSkipMakePayment := os.Getenv("SKIP_MAKE_PAYMENT")
|
||||||
|
if strings.ToUpper(envSkipMakePayment) != "TRUE" {
|
||||||
|
passthroughLaggingPage = chooseAndMakePayment(timerCtx, creditCardType, creditCard, creditCardCVV, creditCardExpiry, browser, page)
|
||||||
|
}
|
||||||
|
|
||||||
// Exits if context cancelled
|
// Exits if context cancelled
|
||||||
select {
|
select {
|
||||||
@@ -430,8 +435,7 @@ func getBookingSlots(browser *rod.Browser, onwardDate string, reverse bool) *rod
|
|||||||
return page
|
return page
|
||||||
}
|
}
|
||||||
|
|
||||||
func selectBookingSlot(ctx context.Context, page *rod.Page, timeCode string) *rod.Page {
|
func selectBookingSlot(ctx context.Context, page *rod.Page, timeCode string, delay int) *rod.Page {
|
||||||
time.Sleep(5 * time.Second)
|
|
||||||
twoCaptchaAPIKey := os.Getenv("TWOCAPTCHA_API_KEY")
|
twoCaptchaAPIKey := os.Getenv("TWOCAPTCHA_API_KEY")
|
||||||
|
|
||||||
needToWait := false
|
needToWait := false
|
||||||
@@ -450,10 +454,10 @@ func selectBookingSlot(ctx context.Context, page *rod.Page, timeCode string) *ro
|
|||||||
// Start probing
|
// Start probing
|
||||||
reportedTicketDetails := false
|
reportedTicketDetails := false
|
||||||
completed := false
|
completed := false
|
||||||
retries := 2
|
retries := 3
|
||||||
for !completed {
|
for !completed {
|
||||||
if retries <= 0 {
|
if retries <= 0 {
|
||||||
log.Println("Used up retries. Exiting.")
|
log.Printf("[%d] Used up retries. Exiting.", delay)
|
||||||
completed = true
|
completed = true
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@@ -478,7 +482,7 @@ func selectBookingSlot(ctx context.Context, page *rod.Page, timeCode string) *ro
|
|||||||
}
|
}
|
||||||
|
|
||||||
if rowElement == nil {
|
if rowElement == nil {
|
||||||
log.Println("No timeslot found. Waiting till context cancelled.")
|
log.Printf("[%d] No timeslot found. Waiting till context cancelled.", delay)
|
||||||
<-ctx.Done()
|
<-ctx.Done()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -498,14 +502,15 @@ func selectBookingSlot(ctx context.Context, page *rod.Page, timeCode string) *ro
|
|||||||
|
|
||||||
// Wait for 1214am
|
// Wait for 1214am
|
||||||
if needToWait {
|
if needToWait {
|
||||||
log.Println("Waiting for 1214am")
|
log.Printf("[%d] Waiting for 1214am", delay)
|
||||||
destinationTime := time.Date(time.Now().Year(), time.Now().Month(), time.Now().Day(), 0, 14, 0, 0, time.Now().Location())
|
destinationTime := time.Date(time.Now().Year(), time.Now().Month(), time.Now().Day(), 0, 14, 0, 0, time.Now().Location())
|
||||||
|
destinationTime = destinationTime.Add(time.Duration(delay) * time.Second)
|
||||||
needToWaitTimer := time.NewTimer(time.Until(destinationTime))
|
needToWaitTimer := time.NewTimer(time.Until(destinationTime))
|
||||||
select {
|
select {
|
||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
return page
|
return page
|
||||||
case <-needToWaitTimer.C:
|
case <-needToWaitTimer.C:
|
||||||
log.Println("1214am reached")
|
log.Printf("[%d] 1214am reached", delay)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -514,13 +519,14 @@ func selectBookingSlot(ctx context.Context, page *rod.Page, timeCode string) *ro
|
|||||||
|
|
||||||
page.MustWaitLoad()
|
page.MustWaitLoad()
|
||||||
time.Sleep(500 * time.Millisecond)
|
time.Sleep(500 * time.Millisecond)
|
||||||
|
bodyText = page.MustElement("body").MustText()
|
||||||
|
|
||||||
// Check if there is captcha
|
// Check if there is captcha
|
||||||
if strings.Contains(bodyText, "Please complete the reCAPTCHA") {
|
if strings.Contains(strings.ToLower(bodyText), "please complete the recaptcha") {
|
||||||
// Reset Body text
|
// Reset Body text
|
||||||
time.Sleep(500 * time.Millisecond)
|
time.Sleep(500 * time.Millisecond)
|
||||||
|
|
||||||
log.Println("Captcha detected")
|
log.Printf("[%d] Captcha detected", delay)
|
||||||
currURL := "https://shuttleonline.ktmb.com.my/ShuttleTrip"
|
currURL := "https://shuttleonline.ktmb.com.my/ShuttleTrip"
|
||||||
// Regex research for Google Captcha V2 API Key
|
// Regex research for Google Captcha V2 API Key
|
||||||
gcaptchaElement := page.MustElement(".g-recaptcha")
|
gcaptchaElement := page.MustElement(".g-recaptcha")
|
||||||
@@ -531,24 +537,28 @@ func selectBookingSlot(ctx context.Context, page *rod.Page, timeCode string) *ro
|
|||||||
|
|
||||||
// Wait for 1215am
|
// Wait for 1215am
|
||||||
if needToWait {
|
if needToWait {
|
||||||
log.Println("Waiting for 1215am")
|
log.Printf("[%d] Waiting for 1215am", delay)
|
||||||
destinationTime := time.Date(time.Now().Year(), time.Now().Month(), time.Now().Day(), 0, 15, 1, 0, time.Now().Location())
|
destinationTime := time.Date(time.Now().Year(), time.Now().Month(), time.Now().Day(), 0, 15, 1, 0, time.Now().Location())
|
||||||
|
destinationTime = destinationTime.Add(time.Duration(delay) * time.Second)
|
||||||
needToWaitTimer := time.NewTimer(time.Until(destinationTime))
|
needToWaitTimer := time.NewTimer(time.Until(destinationTime))
|
||||||
select {
|
select {
|
||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
return page
|
return page
|
||||||
case <-needToWaitTimer.C:
|
case <-needToWaitTimer.C:
|
||||||
log.Println("1215am reached")
|
log.Printf("[%d] 1215am reached", delay)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
page.Eval(`RecaptchaCallback()`)
|
page.Eval(`RecaptchaCallback()`)
|
||||||
|
time.Sleep(500 * time.Millisecond)
|
||||||
|
page.MustWaitLoad()
|
||||||
|
log.Printf("[%d] Submitting captcha", delay)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check before exiting
|
// Check before exiting
|
||||||
bodyText := page.MustElement("body").MustText()
|
bodyText = page.MustElement("body").MustText()
|
||||||
if strings.Contains(bodyText, "System maintenance scheduled at 23:00 to 00:15 (UTC+8).") {
|
if strings.Contains(bodyText, "System maintenance scheduled at 23:00 to 00:15 (UTC+8).") {
|
||||||
log.Println("Maintenance modal detected on booking page after captcha")
|
log.Printf("[%d] Maintenance modal detected on booking page after captcha", delay)
|
||||||
completed = false
|
completed = false
|
||||||
|
|
||||||
closeModalButton := page.MustElement("#popupModalCloseButton")
|
closeModalButton := page.MustElement("#popupModalCloseButton")
|
||||||
@@ -561,7 +571,7 @@ func selectBookingSlot(ctx context.Context, page *rod.Page, timeCode string) *ro
|
|||||||
|
|
||||||
// Repeat if there's no seats -- seats might be released later
|
// Repeat if there's no seats -- seats might be released later
|
||||||
if strings.Contains(bodyText, "Not enough seat for onward trip") {
|
if strings.Contains(bodyText, "Not enough seat for onward trip") {
|
||||||
log.Println("Not enough seat for onward trip")
|
log.Printf("[%d] Not enough seat for onward trip", delay)
|
||||||
completed = false
|
completed = false
|
||||||
|
|
||||||
closeModalButton := page.MustElement("#popupModalCloseButton")
|
closeModalButton := page.MustElement("#popupModalCloseButton")
|
||||||
@@ -576,7 +586,7 @@ func selectBookingSlot(ctx context.Context, page *rod.Page, timeCode string) *ro
|
|||||||
if styleAttribute == nil || !strings.Contains(*styleAttribute, "display: none") {
|
if styleAttribute == nil || !strings.Contains(*styleAttribute, "display: none") {
|
||||||
completed = false
|
completed = false
|
||||||
} else {
|
} else {
|
||||||
log.Println("Completed probing")
|
log.Printf("[%d] Completed probing", delay)
|
||||||
completed = true
|
completed = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user