Last active
June 24, 2023 15:10
-
-
Save jonathan-reisdorf/e3d92add55750117cc02b6b9854dafcd to your computer and use it in GitHub Desktop.
add "taken" page
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==UserScript== | |
// @name Bürgeramt Termin Hunting | |
// @description Helfer fürs Bürgeramt | |
// @include htt*://service.berlin.de/terminvereinbarung* | |
// @version 2.02 | |
// ==/UserScript== | |
const MIN_RELOAD_DELAY = 60000; | |
const ADDITIONAL_RELOAD_DELAY = Math.round(Math.random() * 30000); | |
const HUNTING_CONFIG = { | |
acceptableDayRange: 99, | |
excludeSameDay: true, | |
isTestMode: false, | |
name: | |
localStorage.getItem('buergeramt_name') || | |
localStorage.setItem('buergeramt_name', prompt('Vor- und Nachname eintragen') || ''), | |
email: | |
localStorage.getItem('buergeramt_email') || | |
localStorage.setItem('buergeramt_email', prompt('E-Mail-Adresse eintragen') || ''), | |
phone: | |
localStorage.getItem('buergeramt_phone') || | |
localStorage.setItem('buergeramt_phone', prompt('Telefonnummer eintragen') || ''), | |
}; | |
class BuergeramtTerminHunting { | |
constructor() { | |
window.CheckInput = () => true; // bypass form check | |
if (!this.areNotificationsAllowed && !this.areNotificationsRejected) { | |
Notification.requestPermission(); | |
} | |
document.readyState === 'complete' && this.start(); | |
document.onreadystatechange = () => document.readyState === 'complete' && this.start(); | |
} | |
get currentPage() { | |
const { href } = document.location; | |
const pageMap = { | |
taken: href.includes('terminvereinbarung/termin/taken'), | |
calendar: href.includes('terminvereinbarung/termin/day'), | |
captcha: href.includes('terminvereinbarung/termin/human'), | |
appointment: href.includes('terminvereinbarung/termin/time'), | |
book: href.includes('terminvereinbarung/termin/register'), | |
}; | |
return Object.keys(pageMap).find((key) => pageMap[key]) ?? 'unknown'; | |
} | |
get areNotificationsAllowed() { | |
return Notification.permission === 'granted'; | |
} | |
get areNotificationsRejected() { | |
return Notification.permission === 'denied'; | |
} | |
start() { | |
const { currentPage } = this; | |
currentPage === 'taken' && this.handleTakenPage(); | |
currentPage === 'calendar' && this.handleCalendarPage(); | |
currentPage === 'captcha' && this.handleCaptchaPage(); | |
currentPage === 'appointment' && this.handleAppointmentPage(); | |
currentPage === 'book' && this.handleBookPage(); | |
currentPage === 'unknown' && this.handleUnknownPage(); | |
} | |
notify(text, halt = false) { | |
this.areNotificationsAllowed && new Notification(text); | |
halt && alert(text); | |
} | |
reloadPage() { | |
setTimeout(() => document.location.reload(), MIN_RELOAD_DELAY + ADDITIONAL_RELOAD_DELAY); | |
} | |
handleTakenPage() { | |
setInterval(() => document.querySelector('form[action*="termin/restart"] button:not([disabled])')?.click(), 1000); | |
} | |
handleCalendarPage() { | |
const SELECTOR_NON_BOOKABLE = '.calendar-month-table td.nichtbuchbar'; | |
const SELECTOR_BOOKABLE = '.calendar-month-table td.buchbar'; | |
const CLASSNAME_TODAY = 'heutemarkierung'; | |
const allNodes = [...document.querySelectorAll(`${SELECTOR_BOOKABLE}, ${SELECTOR_NON_BOOKABLE}`)]; | |
const bookableNode = [...document.querySelectorAll(SELECTOR_BOOKABLE)].find((node) => { | |
const index = allNodes.indexOf(node); | |
const isToday = [...node.classList].includes(CLASSNAME_TODAY); | |
return index + 1 < HUNTING_CONFIG.acceptableDayRange && (!HUNTING_CONFIG.excludeSameDay || !isToday); | |
}); | |
if (bookableNode) { | |
this.notify('[Bürgeramt] Termin gefunden!'); | |
bookableNode.querySelector('a').click(); | |
} else { | |
this.reloadPage(); | |
} | |
} | |
handleCaptchaPage() { | |
this.notify('[Bürgeramt] Captcha lösen!', true); | |
} | |
handleAppointmentPage() { | |
const SELECTOR_BOOKABLE = '.calendar-table a[href^="/terminvereinbarung/termin/time/"]'; | |
const bookableNodeLink = document.querySelector(SELECTOR_BOOKABLE); | |
if (!bookableNodeLink) { | |
document.location.href = 'https://service.berlin.de/terminvereinbarung/termin/day/'; | |
return; | |
} | |
bookableNodeLink.click(); | |
} | |
handleBookPage() { | |
this.notify('[Bürgeramt] Terminbuchung wird abgeschlossen!'); | |
const formNameEl = document.querySelector('input[name=familyName]'); | |
const formEmailEl = document.querySelector('input[name=email]'); | |
const formPhoneEl = document.querySelector('input[name=telephone]'); | |
const formSurveyAcceptedEl = document.querySelector('select[name=surveyAccepted]'); | |
const formAcceptTermsEl = document.querySelector('input[name=agbgelesen]'); | |
const formSubmitEl = document.getElementById('register_submit'); | |
formNameEl && (formNameEl.value = HUNTING_CONFIG.name); | |
formEmailEl && (formEmailEl.value = HUNTING_CONFIG.email); | |
formPhoneEl && (formPhoneEl.value = HUNTING_CONFIG.phone); | |
formSurveyAcceptedEl && (formSurveyAcceptedEl.value = '0'); | |
formAcceptTermsEl && (formAcceptTermsEl.checked = true); | |
!HUNTING_CONFIG.isTestMode && formSubmitEl && formSubmitEl.click(); | |
} | |
handleUnknownPage() { | |
this.reloadPage(); | |
} | |
} | |
new BuergeramtTerminHunting(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Tested with Chrome + Tampermonkey (should work with FF + Greasemonkey, too)