You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
harbor-bot/prompts.txt

80 lines
8.1 KiB
Plaintext

* We want to create a pickleball court reservation Python bot that uses curl_cffi to make rest calls and mimics a regular browser -- this bot will be hitting external APIs that we do not control, so we need to be smart about handling behavior anomalies.
* The bot needs to load a configuration file in json on startup which has the "BaseAPIUrl" as a configuration (which we'll set to "https://future.ourclublogin.com/api" ). We will also need to add the login username and password to the configuration -- note that in the configuration we will have a password like "Goliath00!!@", but when we use the value it becomes "Goliath00\041\041@" (notice the ascii escaping).
* Here is an example login query using cURL (we want the bot to mimic the headers):
curl 'https://future.ourclublogin.com/api/CustomerAuth/CustomerLogin' \
-X POST \
-H 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:146.0) Gecko/20100101 Firefox/146.0' \
-H 'Accept: application/json, text/plain, */*' \
-H 'Accept-Language: en-US,en;q=0.5' \
-H 'Accept-Encoding: gzip, deflate, br, zstd' \
-H 'Content-Type: application/json' \
-H 'If-Modified-Since: Mon, 26 Jul 1997 05:00:00 GMT' \
-H 'Cache-Control: no-cache' \
-H 'Pragma: no-cache' \
-H 'x-companyid: 510743' \
-H 'x-customerid: 0' \
-H 'Origin: https://future.ourclublogin.com' \
-H 'Connection: keep-alive' \
-H 'Referer: https://future.ourclublogin.com/login/510743' \
-H 'Cookie: coid=510743' \
-H 'Sec-Fetch-Dest: empty' \
-H 'Sec-Fetch-Mode: cors' \
-H 'Sec-Fetch-Site: same-origin' \
-H 'Priority: u=0' \
--data-raw $'{"UserLogin":"iysaleh","Pswd":"Goliath00\041\041@"}'
*** This is an example login query response when it succeeds:
{"LoginResult":1,"LoginError":null,"CustomerId":21873,"CustomerName":{"FirstName":"Ibraheem","MiddleInitial":"","LastName":"Saleh","PreferredName":"","DisplayName":"Saleh, Ibraheem"},"BarcodeId":"13710","FamilyMemberCount":0,"HomeClub":2,"LastSuccessfulLogin":"2026-01-12T01:31:17.785+00:00","CustomerPermissions":13326059,"data":{"token":"eyJhbGciOiJodHRwOi8vd3d3LnczLm9yZy8yMDAxLzA0L3htbGRzaWctbW9yZSNobWFjLXNoYTI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI3YjBhMWJmMC00NjY0LTRiNzctYWYwMC1jYTgwYTZmNmVjMTUiLCJ2YWxpZCI6IjEiLCJjdXN0b21lcmxvZ2luIjoiaXlzYWxlaCIsImV4cCI6MTc2OTM5MTEyOSwiaXNzIjoiaHR0cDovL2NvcmUtYmV0YS5qZmlzb2Z0d2FyZS5uZXQiLCJhdWQiOiJodHRwOi8vY29yZS1iZXRhLmpmaXNvZnR3YXJlLm5ldCJ9.Y4AkZTdOLMi20hTWGNGcRBNVyGxCILLHLK-mrSG4sQM","tokenExpiration":"2026-01-26T01:32:09.7845457Z"},"Branding":{"BrandingLogo":null,"BrandingTheme":{"BRND_BannerBGColor":"FFFFFF","BRND_BoxHeadingBGColor":"404041","BRND_BoxHeadingFontColor":"FFFFFF","BRND_BtnBGColor":"4987A1","BRND_BtnFontColor":"FFFFFF","BRND_FeatureCalloutBGColor":"88A1A3","BRND_FeatureHeadingFontColor":"0D1312","BRND_HeadingColor":"F7931D","BRND_LogoFileName":"","BRND_MenuActiveBG":"CCCCCC","BRND_MenuActiveBGFont":"000000","BRND_MenuBGColor":"404040","BRND_MenuFontColor":"FFFFFF","BRND_MenuFontROColor":"FFFFFF","BRND_MenuRollOverBG":"000000","BRND_PageBGcolor":"D0D2D4","BRND_ProspectBtnBGColor":"4987A1","BRND_ProspectBtnFontColor":"FFFFFF","GBL_NotifyClubEmail":"","GBL_NotifyClubOnSales":"N","GBL_SellAddOns":"N","GBL_SendContractViaEmail":"N"}},"CaptchaPublicKey":"6Lf4KYcaAAAAADFezRWdBkMsCZvIBPR-KCosrTpa","CustomerNeedsDob":false,"UserName":"iysaleh"}
*** We need to store the login query token and expiration in a file and use it for future requests. We should also store the time we generated the token in the file. We want to have the bot automatically login every time the token is 3 days old OR whenever we are past the tokenExpiration date.
* In the configuration file, we need a "Reservations" section that allows us to configure when the bot should be reservering. An example reservation configuration would be like: Day: Wednesday, Time: 19:00:00-08:00, Courts: [{Court: Court_1, Account: ToniB}, {Court: Court_2, Account: Lee}, {Court: Court_3, Account: Treve}, {Court: Court_4, Account: JoCampbell}, Reservation_Making_Behavior: Weekday_Reservation_Type]
** We also need a way to configure reservation accounts, an example reservation account configuration would be like: {Name: ToniB, Id: 6964}
** We also need a way to configure pickleball courts, an example pickleball court reservation would be like: {"Court": "Court_1", "Id":1, "Name":"Pickleball Court - 1","ResourceTypeId":2,"AssignedResourceId":130,"IsAssignedResourceSelectable":true}
** We also need a way to configure reservation making behavior types -- EG to reserve the court 7 days in advance, at 04:29:00-08:00 try twice with 10 second delay, at 4:30 try 10 times with 10 second delay, at 4:31 try 10 times with 10 second delay, at 4:35 try once (obviously make this in a configurable way).
--- obviously all of these types and examples need to reflect proper json formatting (and there should be validation on app startup to check if something is wrong)
* Here is an example API request for reserving a court that we want to support ("PrimaryCustomerId" is the field that needs to match the configured account ID.):
curl 'https://future.ourclublogin.com/api/TransactionProcessing/BookAppointmentOnAccount' \
-X POST \
-H 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:146.0) Gecko/20100101 Firefox/146.0' \
-H 'Accept: application/json, text/plain, */*' \
-H 'Accept-Language: en-US,en;q=0.5' \
-H 'Accept-Encoding: gzip, deflate, br, zstd' \
-H 'Content-Type: application/json' \
-H 'If-Modified-Since: Mon, 26 Jul 1997 05:00:00 GMT' \
-H 'Cache-Control: no-cache' \
-H 'Pragma: no-cache' \
-H 'Authorization: Bearer eyJhbGciOiJodHRwOi8vd3d3LnczLm9yZy8yMDAxLzA0L3htbGRzaWctbW9yZSNobWFjLXNoYTI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI1ODYwYzE2ZC05N2FmLTQxZjctODU1OS03Njg0YWE2ZGJlMDIiLCJ2YWxpZCI6IjEiLCJjdXN0b21lcmxvZ2luIjoiaXlzYWxlaCIsImV4cCI6MTc2OTI2NTU0OSwiaXNzIjoiaHR0cDovL2NvcmUtYmV0YS5qZmlzb2Z0d2FyZS5uZXQiLCJhdWQiOiJodHRwOi8vY29yZS1iZXRhLmpmaXNvZnR3YXJlLm5ldCJ9.e2zMkyZCaI3gqLvOxZ9O1CEQqwBOfVvZ7ab_KtIcbd8' \
-H 'x-companyid: 510743' \
-H 'x-customerid: 21873' \
-H 'Origin: https://future.ourclublogin.com' \
-H 'Connection: keep-alive' \
-H 'Referer: https://future.ourclublogin.com/Appointments' \
-H 'Cookie: coid=510743' \
-H 'Sec-Fetch-Dest: empty' \
-H 'Sec-Fetch-Mode: cors' \
-H 'Sec-Fetch-Site: same-origin' \
-H 'Priority: u=0' \
--data-raw '{"ClubId":2,"LoggedInCustomerId":21873,"PrimaryCustomerId":14563,"AdditionalCustomerIds":[],"AppointmentItemId":323,"SelectedBooks":[{"Id":139,"Name":"Pickleball Court - 4","ResourceTypeId":2,"AssignedResourceId":130,"IsAssignedResourceSelectable":true}],"PackageItemId":0,"PackageQuantity":0,"ChangeFeeId":0,"StartDate":"2026-01-15T17:30:00-08:00","UserDisplayedPayNowGrandTotal":0,"DisplayedAmountDueAtTimeOfService":0,"CancellationAppointmentId":0}'
** Note that we do not want the bot to actually make court reservations yet, just build the code for doing it, but don't have it actually be triggered yet. Have a dummy print happen at the trigger time instead.
** When success happens for court reservation, the response looks like:
{"Success":true,"AllowRetry":false,"Message":"","ResultId":0}
** When success fails for court reservation, the response looks like:
{"Success":false,"AllowRetry":false,"Message":"We apologize, but this appointment time is no longer available.","ResultId":0}
** We need to add behavior so that if a reservation succeeds, future attempts for that configuration do not try again.
8 months ago
* Prompt 2:
* I tried to book a court for 7 days in advance with a weekend reservation type, and it booked the court right away, instead of waiting for the specified booking times. The bot should only attempt to make the reservations in live mode at the time of the reservation.
* Instead of having to start the bot every day, update it to just run continuously. If it every crashes, the service will just auto-restart... No reason to require 7 cron jobs--1 for every day.
# Dry-Run
python harbor_bot.py --test-book Court_1 Saleh 2026-01-19 "19:00:00-08:00"
8 months ago
python harbor_bot.py --test-book Court_1 Saleh 2026-01-19 "19:00:00-08:00" --live
python harbor_bot.py --daemon --live