Compare commits

...

3 Commits

@ -392,7 +392,7 @@ curl 'https://future.ourclublogin.com/api/Scheduling/CancelAppointment' \
-H 'Sec-Fetch-Mode: cors' \ -H 'Sec-Fetch-Mode: cors' \
-H 'Sec-Fetch-Site: same-origin' \ -H 'Sec-Fetch-Site: same-origin' \
-H 'Priority: u=0' \ -H 'Priority: u=0' \
--data-raw '{"ClubId":2,"LoggedInCustomerId":21873,"PrimaryCustomerId":6964,"AdditionalCustomerIds":[],"AppointmentItemId":323,"SelectedBooks":[{"Id":2,"Name":"Pickleball Court - 2","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}' --data-raw '{"ClubId":2,"LoggedInCustomerId":21873,"PrimaryCustomerId":6964,"AdditionalCustomerIds":[],"AppointmentItemId":323,"SelectedBooks":[{"Id":2,"Name":"Pickleball Court - 2","ResourceTypeId":2,"AssignedResourceId":130,"IsAssignedResourceSelectable":true}],"PackageItemId":0,"PackageQuantity":0,"ChangeFeeId":0,"StartDate":"2026-01-19T17:30:00-08:00","UserDisplayedPayNowGrandTotal":0,"DisplayedAmountDueAtTimeOfService":0,"CancellationAppointmentId":0}'
curl 'https://future.ourclublogin.com/api/TransactionProcessing/BookAppointmentOnAccount' \ curl 'https://future.ourclublogin.com/api/TransactionProcessing/BookAppointmentOnAccount' \
@ -416,7 +416,7 @@ curl 'https://future.ourclublogin.com/api/Scheduling/CancelAppointment' \
-H 'Sec-Fetch-Mode: cors' \ -H 'Sec-Fetch-Mode: cors' \
-H 'Sec-Fetch-Site: same-origin' \ -H 'Sec-Fetch-Site: same-origin' \
-H 'Priority: u=0' \ -H 'Priority: u=0' \
--data-raw '{"ClubId":2,"LoggedInCustomerId":21873,"PrimaryCustomerId":16250,"AdditionalCustomerIds":[],"AppointmentItemId":323,"SelectedBooks":[{"Id":3,"Name":"Pickleball Court - 3","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}' --data-raw '{"ClubId":2,"LoggedInCustomerId":21873,"PrimaryCustomerId":16250,"AdditionalCustomerIds":[],"AppointmentItemId":323,"SelectedBooks":[{"Id":3,"Name":"Pickleball Court - 3","ResourceTypeId":2,"AssignedResourceId":130,"IsAssignedResourceSelectable":true}],"PackageItemId":0,"PackageQuantity":0,"ChangeFeeId":0,"StartDate":"2026-01-19T17:30:00-08:00","UserDisplayedPayNowGrandTotal":0,"DisplayedAmountDueAtTimeOfService":0,"CancellationAppointmentId":0}'
curl 'https://future.ourclublogin.com/api/TransactionProcessing/BookAppointmentOnAccount' \ curl 'https://future.ourclublogin.com/api/TransactionProcessing/BookAppointmentOnAccount' \
@ -440,7 +440,7 @@ curl 'https://future.ourclublogin.com/api/Scheduling/CancelAppointment' \
-H 'Sec-Fetch-Mode: cors' \ -H 'Sec-Fetch-Mode: cors' \
-H 'Sec-Fetch-Site: same-origin' \ -H 'Sec-Fetch-Site: same-origin' \
-H 'Priority: u=0' \ -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}' --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-19T17:30:00-08:00","UserDisplayedPayNowGrandTotal":0,"DisplayedAmountDueAtTimeOfService":0,"CancellationAppointmentId":0}'
# do this court 1 last!!! # do this court 1 last!!!
curl 'https://future.ourclublogin.com/api/TransactionProcessing/BookAppointmentOnAccount' \ curl 'https://future.ourclublogin.com/api/TransactionProcessing/BookAppointmentOnAccount' \
@ -464,7 +464,7 @@ curl 'https://future.ourclublogin.com/api/Scheduling/CancelAppointment' \
-H 'Sec-Fetch-Mode: cors' \ -H 'Sec-Fetch-Mode: cors' \
-H 'Sec-Fetch-Site: same-origin' \ -H 'Sec-Fetch-Site: same-origin' \
-H 'Priority: u=0' \ -H 'Priority: u=0' \
--data-raw '{"ClubId":2,"LoggedInCustomerId":21873,"PrimaryCustomerId":21873,"AdditionalCustomerIds":[],"AppointmentItemId":323,"SelectedBooks":[{"Id":1,"Name":"Pickleball Court - 1","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}' --data-raw '{"ClubId":2,"LoggedInCustomerId":21873,"PrimaryCustomerId":21873,"AdditionalCustomerIds":[],"AppointmentItemId":323,"SelectedBooks":[{"Id":1,"Name":"Pickleball Court - 1","ResourceTypeId":2,"AssignedResourceId":130,"IsAssignedResourceSelectable":true}],"PackageItemId":0,"PackageQuantity":0,"ChangeFeeId":0,"StartDate":"2026-01-19T17:30:00-08:00","UserDisplayedPayNowGrandTotal":0,"DisplayedAmountDueAtTimeOfService":0,"CancellationAppointmentId":0}'
# When it fails to book!!!!! # When it fails to book!!!!!

@ -0,0 +1,5 @@
alias HARBORBOT_RESTART="sudo systemctl daemon-reload;sudo systemctl restart harbor-bot"
alias HARBORBOT_LOGS="sudo journalctl -u harbor-bot -f"
alias HARBORBOT_STOP="sudo systemctl stop harbor-bot"
alias HARBORBOT_START="sudo systemctl start harbor-bot"
alias HARBORBOT_STATUS="sudo systemctl status harbor-bot"

@ -45,8 +45,7 @@
{"Time": "04:29:00-08:00", "Attempts": 2, "DelaySeconds": 10}, {"Time": "04:29:00-08:00", "Attempts": 2, "DelaySeconds": 10},
{"Time": "04:31:00-08:00", "Attempts": 2, "DelaySeconds": 10}, {"Time": "04:31:00-08:00", "Attempts": 2, "DelaySeconds": 10},
{"Time": "04:35:00-08:00", "Attempts": 1, "DelaySeconds": 0}, {"Time": "04:35:00-08:00", "Attempts": 1, "DelaySeconds": 0},
{"Time": "20:05:00-08:00", "Attempts": 4, "DelaySeconds": 10}, {"Time": "21:37:00-08:00", "Attempts": 4, "DelaySeconds": 10}
{"Time": "20:11:00-08:00", "Attempts": 4, "DelaySeconds": 10}
] ]
}, },
{ {
@ -57,8 +56,8 @@
{"Time": "06:30:00-08:00", "Attempts": 2, "DelaySeconds": 10}, {"Time": "06:30:00-08:00", "Attempts": 2, "DelaySeconds": 10},
{"Time": "06:55:00-08:00", "Attempts": 2, "DelaySeconds": 10}, {"Time": "06:55:00-08:00", "Attempts": 2, "DelaySeconds": 10},
{"Time": "07:00:00-08:00", "Attempts": 1, "DelaySeconds": 0}, {"Time": "07:00:00-08:00", "Attempts": 1, "DelaySeconds": 0},
{"Time": "07:01:00-08:00", "Attempts": 2, "DelaySeconds": 10}, {"Time": "07:01:00-08:00", "Attempts": 2, "DelaySeconds": 10},
{"Time": "07:02:00-08:00", "Attempts": 2, "DelaySeconds": 10} {"Time": "07:02:00-08:00", "Attempts": 2, "DelaySeconds": 10}
] ]
} }
], ],
@ -118,14 +117,6 @@
{"Court": "Court_4", "Account": "Treve"} {"Court": "Court_4", "Account": "Treve"}
] ]
}, },
{
"Day": "Sunday",
"Time": "15:30:00-08:00",
"ReservationBehavior": "Test_Reservation_Type",
"Courts": [
{"Court": "Court_3", "Account": "Saleh"}
]
},
{ {
"Day": "Saturday", "Day": "Saturday",
"Time": "14:00:00-08:00", "Time": "14:00:00-08:00",

@ -0,0 +1,17 @@
[Unit]
Description=Harbor Bot Pickleball Reservation Service -- put in /etc/systemd/system/harbor-bot.service
After=network.target
[Service]
Type=simple
User=pi
WorkingDirectory=/home/pi/harbor-bot
ExecStart=/usr/bin/python3 -u /home/pi/harbor-bot/harbor_bot.py --daemon --live
Restart=always
RestartSec=30
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target

@ -724,9 +724,20 @@ class HarborBot:
self._print_upcoming_reservations() self._print_upcoming_reservations()
last_status_print = datetime.now() last_status_print = datetime.now()
last_date = datetime.now().date()
while True: while True:
try: try:
# Check for day change
current_date = datetime.now().date()
if current_date != last_date:
print(f"\n[INFO] {'='*50}")
print(f"[INFO] New day detected: {current_date.strftime('%A, %B %d, %Y')}")
print(f"[INFO] {'='*50}")
self._print_upcoming_reservations()
last_date = current_date
last_status_print = datetime.now()
self._daemon_iteration(dry_run) self._daemon_iteration(dry_run)
# Print status every 30 minutes # Print status every 30 minutes
@ -746,6 +757,7 @@ class HarborBot:
traceback.print_exc() traceback.print_exc()
print("[INFO] Sleeping 60s before retry...") print("[INFO] Sleeping 60s before retry...")
time.sleep(60) time.sleep(60)
time.sleep(60)
def _print_upcoming_reservations(self): def _print_upcoming_reservations(self):
"""Print status of upcoming reservations.""" """Print status of upcoming reservations."""

@ -69,7 +69,7 @@ curl 'https://future.ourclublogin.com/api/CustomerAuth/CustomerLogin' \
* Add startup configuration validation to ensure that the AttemptSchedule is configured properly, with scheduled times incrementing as required by the algorithm. * Add startup configuration validation to ensure that the AttemptSchedule is configured properly, with scheduled times incrementing as required by the algorithm.
## ##
* This will run on a raspberry pi on linux, implement a pure python method for sending an email everytime a court is successfully booked. Be sure to include what court was booked, what time it was booked for, and the user name and ID that the booking was creating under. * This will run on a raspberry pi on linux, implement a pure python method for sending an email everytime a court is successfully booked. Be sure to include what court was booked, what time it was booked for, and the user name and ID that the booking was creating under. config.json will obviously need to be updated to support any number of emails that are expected to receive these success emails.
@ -82,3 +82,5 @@ python harbor_bot.py --test-book Court_1 Saleh 2026-01-19 "19:00:00-08:00"
python harbor_bot.py --test-book Court_1 Saleh 2026-01-19 "19:00:00-08:00" --live python harbor_bot.py --test-book Court_1 Saleh 2026-01-19 "19:00:00-08:00" --live
python harbor_bot.py --daemon --live python harbor_bot.py --daemon --live
# python harbor_bot.py --test-email (See smtp-email-notifications-attempt branch, gmail smtp doesn't actually work)
python harbor_bot.py --show-config
Loading…
Cancel
Save