impf-bot
impf-bot copied to clipboard
Vermittlungscodes sind server- und nicht standortgebunden
Hallo,
ich bin ein absoluter Noob, was Github angeht, möchte aber weiterhelfen. Dieser Post hier ist bestimmt auf der falschen Seite, verschiebe ihn einfach.
Ich habe durch Zufall herausgefunden, dass die Vermittlungscodes nicht standort-, sondern servergebunden sind. Der Vermittlungscode, der für "https://005-iz.impfterminservice.de/impftermine/service/75555" gilt, gilt NICHT für "https://002-iz.impfterminservice.de/impftermine/service/75555", aber auch für "https://005-iz.impfterminservice.de/impftermine/service/75556".
Zudem ist dein offizieller Weg, auf die Vermittlungscodes zu warten, viel zu umständlich. Wenn du die Antwort des Servers auf die Terminabfrage abfängst und abänderst, können sofort Vermittlungscodes erstellt werden. Aus
{"termineVorhanden":false,"vorhandeneLeistungsmerkmale":[]}
wird somit z.B.
{"termineVorhanden":true,"vorhandeneLeistungsmerkmale":["L921"]}
für Moderna und Biontech. 2x geändert und es kann über die Webseite ein Code generiert werden.
Man läuft halt relativ schnell in die Bot Protection rein und bekommt einen 429 zurück und ist dann kurz geblockt. Das war zumindest immer meine Erfahrung wenn man direkt an die Rest-API dahinter ran geht
Bzw. welchen request abfangen meinst du @chim0rin ?
Als Ich den Bot gebastelt habe, hatte ich auch schon nach Alternativen recherchiert. Das hatte ich dann auch gesehen, dass andere Bots ne API verwenden aber wohl genau deshalb seit Anfang April aufgrund von Gegenmaßnahmen nicht mehr funktionieren. Ohne damit zu rechnen, dass es überhaupt klappt (keine Capteres oä.) war ich dann überrascht, dass es mit der Browser-Automation dann so zuverlässig und schnell funktioniert hat.
Da ich kein Bedarf mehr habe und er für mein Setup auch völlig ausreichend war, würde ich von weiteren Optimierungen absehen. Die Details wie sich das System weiter austrixen lässt ("Terminabfrage abfängst und abänderst") interessieren mich allerdings trotzdem. Und ich werde auch selbstverständlich jeden Merge-Request, der eine Verbesserung bringt, annehmen😉
@chim0rin mich würde ebenfalls interessieren, wie du die Server-Response abfängst und änderst. Nutzt du einen lokalen Proxy oder ähnliches?
Ich kann die Frage selbst beantworten: Mithilfe von Fiddler Classic lässt sich (zumindest unter Windows) die Server-Response abfangen und verändern, bevor sie den Browser erreicht. Dazu in Fiddler über Tools -> Options -> HTTPS den Haken bei "Decrypt HTTPS traffic" setzen und die Meldungen abnicken - damit wird das Fiddler Root Zertifikat im Windows Trust Store installiert. Hinweis: Fiddler kann damit jeglichen HTTPS-Traffic aller Anwendungen mitlesen! Dann über Rules -> Customize Rules den Fiddler ScriptEditor öffnen und in der Funktion OnBeforeResponse
folgendes hinzufügen und speichern:
if (oSession.uriContains("impfterminservice") && oSession.uriContains("termincheck")) {
oSession.utilSetResponseBody('{"termineVorhanden":true,"vorhandeneLeistungsmerkmale":["L921"]}')
}
Dann kann über Chrome (Firefox geht nicht, der hat seinen eigenen Trust Store) ganz normal (von Hand 😉) die Seite aufgerufen werden und es lässt sich sofort ein Vermittlungscode anfordern.
Hey das ist ja super, vielen Dank fürs Teilen der Fiddler Lösung, auch wenn es ja leider nichts bringt, da man ja wirklich nur ein Code braucht um alle Standorte abzutesten solange man auf dem selben Server bleibt. Wenn ich die Automatisierung laufen lasse, habe ich manchmal das Problem, dass er nicht den 229-iz Server nimmt sondern z. B. 02-iz und dann steht da, dass der Vermittlungscode ungültig ist und das Script bleibt hängen. Kann ich das irgendwie beeinflussen?
Ich kann die Frage selbst beantworten: Mithilfe von Fiddler Classic lässt sich (zumindest unter Windows) die Server-Response abfangen und verändern, bevor sie den Browser erreicht. Dazu in Fiddler über Tools -> Options -> HTTPS den Haken bei "Decrypt HTTPS traffic" setzen und die Meldungen abnicken - damit wird das Fiddler Root Zertifikat im Windows Trust Store installiert. Hinweis: Fiddler kann damit jeglichen HTTPS-Traffic aller Anwendungen mitlesen! Dann über Rules -> Customize Rules den Fiddler ScriptEditor öffnen und in der Funktion
OnBeforeResponse
folgendes hinzufügen und speichern:if (oSession.uriContains("impfterminservice") && oSession.uriContains("termincheck")) { oSession.utilSetResponseBody('{"termineVorhanden":true,"vorhandeneLeistungsmerkmale":["L921"]}') }
Dann kann über Chrome (Firefox geht nicht, der hat seinen eigenen Trust Store) ganz normal (von Hand wink) die Seite aufgerufen werden und es lässt sich sofort ein Vermittlungscode anfordern.
Genau so habe ich es gemacht :) Bzw. mit Rules --> Automatic Breakpoints --> After Responses
Hey das ist ja super, vielen Dank fürs Teilen der Fiddler Lösung, auch wenn es ja leider nichts bringt, da man ja wirklich nur ein Code braucht um alle Standorte abzutesten solange man auf dem selben Server bleibt. Wenn ich die Automatisierung laufen lasse, habe ich manchmal das Problem, dass er nicht den 229-iz Server nimmt sondern z. B. 02-iz und dann steht da, dass der Vermittlungscode ungültig ist und das Script bleibt hängen. Kann ich das irgendwie beeinflussen?
Jedem Impfzentrum ist Anbieter-seitig ein bestimmter Server zugewiesen: https://www.impfterminservice.de/assets/static/impfzentren.json (vermutlich wegen Load Balancing) Ich könnte mir vorstellen, dass das Frontend während der Browser-Automatisierung grundsätzlich auf den "zugehörigen" Server wechselt und es deswegen bei dir kollidiert?
Du hast Recht, das steht ja in der Json Datei, habs komplett übersehen, danke für den Hinweis. Das zusammen mit dem Tip wie man die Codes generieren kann ist wirklich hilfreich. Leider gibt's einfach keine Termine.
Loadbalancing 1998 style
Vorher waren Wartungsarbeiten.

Bei mir funktioniert das Abfangen und Abändern nicht mehr. Geht's bei euch noch?
Geht noch, aber nach den Wartungsarbeiten wurde die Anzahl der Warteräume gefühlt dramatisch hochgefahren
okay, danke für die Rückmeldung. Dann versuche ich es heute Nacht nochmal. Vielleicht sind dann die "Warteräume" nicht so gefüllt. :)
Gefühlt klappt es glaube ich morgens am besten. Gestern morgen einen Termin bekommen und heute morgen die restlichen zwei die ich noch gebraucht habe. Dazwischen war nix.
Mit der Methode mit Fiddler und dann dem Bot ist das echt super. Am besten noch den Bot mit Slack verbinden, Slack aufs Handy und dann hat man die Benachrichtigung direkt an der Smartwatch sobald man zum PC rennen muss.
Die Timing Einstellungen sind nun auch in den Properties konfigurierbar und der "Virtueller Warteraum" wind nun berücksichtigt.
Hallo miteinander,
Gibt es irgend eine Limitierung wenn man mehrere Impfzentren mit dem gleichen Server / Vermittlungscode abklappert?
Dieser weiterlaufende Timer gibt mir irgendwie zu denken 🤔 Kriegt man in den 10 Minuten überhaupt eine neue Antwort?
Ich habe noch einen Vermittlungscode eines eigentlich anderen Testzentrums und diesen mit dem Server-code im impf-bot hinterlegt. Der Impf-Bot bekommt jedoch immer in Chrome den Fehler "Es ist ein unerwartetes Problem aufgetreten".
Als URL wird hierzu 226-iz.impfterminservice.de/impftermine/service?=plz=70629 automatisiert eingegeben.
Wenn ich diese jedoch manuell an einem Computer (mit anderer IP) eingebe, klappt auch der Vermittlungscode (jedoch eben keine freien Termine).
Ist das ein bekannter Fehler bzw. was könnte die Ursache für die Meldung "Es ist ein unerwartetes Problem aufgetreten" sein?
Möglicherweise kann dies umgangen werden, in dem statt der o.g. URL dann
[Server-Code]-iz.impfterminservice.de/impftermine/suche/[Vermittlungscode]/[PLZ]
eingetragen wird. Dann landet man direkt auf der Terminseite und überspringt die Eingabe.
Das direkte Aufrufen der Terminseite über den Direktlink hat bei meinem Script (selbst geschrieben) leider nicht zuverlässig funktioniert, sondern man wird häufig/meistens auf die Startseite weitergeleitet. Warum der Direktlink manchmal funktioniert und manchmal nicht konnte ich nicht herausfinden.
Daher ist es hier vermutlich auch so, dass der Weg über die Startseite -> Auswahl Bundesland/Impfzentrum -> Eingabe des Vermittlungscodes geschieht. Bei dieser Variante wird man dann allerdings immer an den Server des Impfzentrums weitergeleitet...
@lk3de @chim0rin any solution or update for the fiddler solution due to change on the website with birthday ?
@marceldrhr Rules --> Automatic Breakpoints --> After Responses in Fiddler still seems to work in combination with the code in OnBeforeResponse
. After the breakpoint is reached, just open the respective request in Fiddler and click the button to continue. I just tried it by myself and it worked. Without setting the breakpoint, it also didn't work. No idea why. Probably they changed something on the client side of the website.
Doesn't seem to work for me anyways. Tried with After Responses Breakpoint but it doesnt redirect me to the site where i enter email and phone.
Seems
Ich kann die Frage selbst beantworten: Mithilfe von Fiddler Classic lässt sich (zumindest unter Windows) die Server-Response abfangen und verändern, bevor sie den Browser erreicht. Dazu in Fiddler über Tools -> Options -> HTTPS den Haken bei "Decrypt HTTPS traffic" setzen und die Meldungen abnicken - damit wird das Fiddler Root Zertifikat im Windows Trust Store installiert. Hinweis: Fiddler kann damit jeglichen HTTPS-Traffic aller Anwendungen mitlesen! Dann über Rules -> Customize Rules den Fiddler ScriptEditor öffnen und in der Funktion
OnBeforeResponse
folgendes hinzufügen und speichern:if (oSession.uriContains("impfterminservice") && oSession.uriContains("termincheck")) { oSession.utilSetResponseBody('{"termineVorhanden":true,"vorhandeneLeistungsmerkmale":["L921"]}') }
Dann kann über Chrome (Firefox geht nicht, der hat seinen eigenen Trust Store) ganz normal (von Hand wink) die Seite aufgerufen werden und es lässt sich sofort ein Vermittlungscode anfordern.
Genau so habe ich es gemacht :) Bzw. mit Rules --> Automatic Breakpoints --> After Responses
Scheint nicht mehr zu funktionieren... hat schon jemand nen fix gefunden? Oder nen Ansatzpunkt zum Suchen?
Da ich keine Codes mehr benötige, suche ich nun nicht weiter, aber ein Ansatzpunkt zum Suchen wäre folgender:
Nach der Eingabe des Geburtsdatums und dem Klick auf Termin suchen wird ein POST request an
https://SERVERNUMMER-iz.impfterminservice.de/rest/suche/termincheck/alter
mit dem JSON {"geburtsdatum":"2000-01-01","plz":"12345"}
geschickt und als Antwort kommt (wenn man das automatische Austauschen in Customize Rules nicht aktiviert hat): "{"errors":[{"code":"WP033","text":"Keine verfügbaren Impfstoffe für die Altersgruppe"}]}"
Ich vermute man muss den Code WP0033 entsprechend ändern. Beim Ändern zu WP0032 kommt z.B., dass die Altersgruppe u16 keine Termine ausmachen darf. Einen passenden Code habe ich aber auch die Schnelle nicht gefunden. Vielleicht hat jedes Alter tatsächlich auch einen eigenen Code, damit der Impfstoff auf alle Altersgruppen "gerecht"/gleichmäßig verteilt wird...
Aber ist vielleicht ein Ansatz zum weiter suchen ;)
Ich habe gerade eben bei einem Impfzentrum in Brandenburg (dort gibt es wenigstens noch Codes 😄) folgendes herausgefunden:
Klick auf "Nein, Anspruch prüfen" führt zu:
Request: GET /rest/suche/termincheck?plz=16866&leistungsmerkmale=L920,L921,L922,L923
Response Body: {"termineVorhanden":true,"vorhandeneLeistungsmerkmale":["L920"]}
L920
entspricht BioNTech für 16-17-Jährige (siehe Liste - warum auch immer 🙃
Eingabe des Geburtsdatums (01.01.2000) führt zu:
Request: POST /rest/suche/termincheck/alter
mit den POST-Daten {"geburtsdatum":"2000-01-01","plz":"16866"}
Response Body: {"einzeltermineVorhanden":false,"terminpaareVorhanden":true}
mit HTTP 200 (statt 400)
Dementsprechend muss das Fiddler-Script nur ein wenig angepasst werden, um einen HTTP 200 und diesen Response Body zurückzuliefern:
if (oSession.uriContains("/rest/suche/termincheck?plz")) {
oSession.utilSetResponseBody('{"termineVorhanden":true,"vorhandeneLeistungsmerkmale":["L921"]}')
}
if (oSession.uriContains("/rest/suche/termincheck/alter")) {
oSession.responseCode = 200;
oSession.oResponse.headers.HTTPResponseCode = 200;
oSession.oResponse.headers.HTTPResponseStatus = "200 OK";
oSession.utilSetResponseBody('{"einzeltermineVorhanden":false,"terminpaareVorhanden":true}')
}
Der "Umweg" über Automatic Breakpoints ist trotzdem weiterhin notwendig. Zumindest schafft mein Fiddler es sonst nicht mehr, die Response auszutauschen.
Da ich keine Codes mehr benötige, suche ich nun nicht weiter, aber ein Ansatzpunkt zum Suchen wäre folgender:
Nach der Eingabe des Geburtsdatums und dem Klick auf Termin suchen wird ein POST request an
https://SERVERNUMMER-iz.impfterminservice.de/rest/suche/termincheck/alter
mit dem JSON{"geburtsdatum":"2000-01-01","plz":"12345"}
geschickt und als Antwort kommt (wenn man das automatische Austauschen in Customize Rules nicht aktiviert hat):"{"errors":[{"code":"WP033","text":"Keine verfügbaren Impfstoffe für die Altersgruppe"}]}"
Ich vermute man muss den Code WP0033 entsprechend ändern. Beim Ändern zu WP0032 kommt z.B., dass die Altersgruppe u16 keine Termine ausmachen darf. Einen passenden Code habe ich aber auch die Schnelle nicht gefunden. Vielleicht hat jedes Alter tatsächlich auch einen eigenen Code, damit der Impfstoff auf alle Altersgruppen "gerecht"/gleichmäßig verteilt wird...
Aber ist vielleicht ein Ansatz zum weiter suchen ;)
Vielen Dank für die ausführliche Rückmeldung. Konnte ich nachvollziehen, soweit bin ich dann jetzt auch gekommen :)
In Brandenburg - Penzlau ist gerade relativ frei, da kommt man bis zur Email / Handynummer Maske durch. Hier wird dann folgendes zurückgegeben:
https://357-iz.impfterminservice.de/rest/suche/termincheck/alter {"einzeltermineVorhanden":false,"terminpaareVorhanden":true}
Wenn ich das allerdings in z.B. BaWü versuche zu überschreiben komme ich zwar mit dem bereits im Forum geposteten Code zur Frage, ob ich einer impfberechtigten Personengruppe angehöre, allerdings kommt beim Absenden zu nem 400er:
{einzeltermineVorhanden: false, terminpaareVorhanden: true} einzeltermineVorhanden: false terminpaareVorhanden: true
Vielleicht hat jemand noch ne Idee? Vielen Dank schonmal für eure Mühe!