Skip to content

Instantly share code, notes, and snippets.

@eliashaeussler
Last active October 30, 2023 17:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save eliashaeussler/d458e49721f2688c587b2a444913ad02 to your computer and use it in GitHub Desktop.
Save eliashaeussler/d458e49721f2688c587b2a444913ad02 to your computer and use it in GitHub Desktop.
Track customer count and travel time of a Telekom appointment
#!/usr/bin/env bash
# shellcheck disable=SC2155
set -e
#
# Script to track waiting customer count and estimated travel time
# of a Telekom appointment.
#
# Usage:
# ./telekom_appointment_tracker.sh <uuid>
#
# Arguments:
# uuid 6-digit UUID sent by Telekom via https://termin.telekom.de/?<uuid>
#
readonly uuid="$1"
readonly wait_interval=60
readonly ajax_url="https://termin.telekom.de/ajax.php"
readonly web_url="https://termin.telekom.de/?${uuid}"
readonly title="Telekom appointment #${uuid}"
state_changed=false
customers_count=0
travel_time=0
RED="\033[0;31m"
GREEN="\033[0;32m"
NC="\033[0m"
#
# Generate request payload for Telekom AJAX endpoint.
#
function generate_payload() {
echo "{\"uuid\":\"${uuid}\",\"humanInteraction\":true}" | base64
}
#
# Perform request to AJAX endpoint and parse result using jq with given query.
#
function perform_and_parse_request() {
local query="$1"
curl -X POST -sSL -d "$(generate_payload)" "${ajax_url}" | base64 -d | jq -r "$query"
}
#
# Count waiting customers in queue.
#
function count_customers() {
perform_and_parse_request '.kundenauftrag.auftragszaehler // empty'
}
#
# Fetch technician's estimated travel time.
#
function get_travel_time() {
perform_and_parse_request '.kundenauftrag.traveltime // empty'
}
#
# Check if appointment is in waiting state.
#
function is_in_waiting_state() {
local result="$(perform_and_parse_request 'if (.kundenauftrag | has("wartegrund")) then 0 else 1 end')"
if [ -z "$result" ]; then
return 1
fi
return "$result"
}
#
# Display number of waiting customers in queue.
#
# Prints a message to the console displaying the number of waiting customers
# in queue. In addition, a notification is raised to raise attention.
#
function display_customer_count() {
if [ "$customers_count" -le 0 ]; then
local message="A technician is on its way."
elif [ "$customers_count" -eq 1 ]; then
local message="One customer left."
else
local message="${customers_count} customers left."
fi
if "$state_changed"; then
echo -e "${GREEN}State changed:${NC} ${message}"
osascript -e "display notification \"${message}\" with title \"${title}\" subtitle \"State changed\""
else
echo "$message"
osascript -e "display notification \"${message}\" with title \"${title}\""
fi
}
#
# Display technician's travel time.
#
# Prints a message to the console displaying the technician's estimated
# travel time. In addition, a notification is raised to raise attention.
#
function display_travel_time() {
if [ "$travel_time" -le 0 ]; then
local message="A technician should have arrived."
elif [ "$travel_time" -eq 1 ]; then
local message="A technician should arrive in less than one minute."
else
local message="A technician should arrive in less than ${travel_time} minutes."
fi
if "$state_changed"; then
echo -e "${GREEN}State changed:${NC} ${message}"
osascript -e "display notification \"${message}\" with title \"${title}\" subtitle \"State changed\""
else
echo "$message"
osascript -e "display notification \"${message}\" with title \"${title}\""
fi
if [ "$travel_time" -le 0 ]; then
exit
fi
}
#
# Display error message.
#
function display_error() {
local message="$1"
echo >&2 -e "${RED}${message}${NC}"
}
# Validate jq binary
if ! which jq >/dev/null; then
display_error "jq needs to be installed in your system."
echo >&2 "Read more at https://jqlang.github.io/jq/download/."
exit 1
fi
# Validate given UUID
if [ -z "$uuid" ]; then
display_error "Please pass the 6-digit UUID you received from https://termin.telekom.de/?<uuid>."
exit 1
fi
# Exit early if appointment is in waiting state
if is_in_waiting_state; then
display_error "Appointment is currently in waiting state."
echo >&2 "For more details, visit ${web_url}."
exit
fi
# Show link to website
echo "Appointment website: ${web_url}"
# Check every x seconds for current customers count and/or technician's travel time
while true; do
current_count="$(count_customers)"
# If no customer count is provided, check if technician is already on its way
if [ -z "$current_count" ]; then
current_travel_time="$(get_travel_time)"
fi
# Show error if neither customer count nor travel time are accessible
if [ -z "$current_count" ] && [ -z "$current_travel_time" ]; then
display_error "Error while checking appointment details. Trying again in ${wait_interval} seconds..."
sleep "$wait_interval"
continue
fi
# Display notice if technician is on its way
if [ "$current_travel_time" -ne "$travel_time" ]; then
current_count=0
customers_count=0
travel_time="$current_travel_time"
display_travel_time
fi
# Display notice about customers in queue
if [ "${current_count:-0}" -ne "$customers_count" ]; then
customers_count="$current_count"
current_travel_time=0
travel_time=0
display_customer_count
fi
# Mark global state change
state_changed=true
# Exit if appointment is finished
if [ "$customers_count" -le 0 ] && [ "$current_travel_time" -le 0 ]; then
exit
fi
sleep "$wait_interval"
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment