102 lines
5.0 KiB
Bash
Executable File
102 lines
5.0 KiB
Bash
Executable File
#!/bin/bash
|
|
# shellcheck disable=SC2059
|
|
|
|
declare message_geofence_enter message_geofence_exit message_device_online message_device_unknown message_device_offline message_event_other signal_sender_phone_number signal_recipients_array signal_api_endpoint_full_path allow_unique_device_ids_posix_ere device_name event_type battery_level message
|
|
|
|
payload="${1}"
|
|
|
|
function load_config() {
|
|
local this_script_call_cmd this_script_resolved_abs_path conf_file_resolved_abs_path conf_file_resolved_file_name
|
|
this_script_call_cmd="${BASH_SOURCE[0]}"
|
|
this_script_resolved_abs_path="$(readlink -f "${this_script_call_cmd}")"
|
|
conf_file_resolved_abs_path="${this_script_resolved_abs_path}"'.conf'
|
|
conf_file_resolved_file_name="$(basename "${conf_file_resolved_abs_path}")"
|
|
if [[ -r "${conf_file_resolved_abs_path}" ]]; then
|
|
# shellcheck source="${conf_file_resolved_abs_path}"
|
|
source "${conf_file_resolved_abs_path}"
|
|
fi
|
|
# Optional, will use default values if not given by user
|
|
: "${allow_list_events:='^(deviceOnline|deviceUnknown|geofenceEnter|geofenceExit)$'}"
|
|
: "${message_event_type_not_allowed:='Event "%s" not allowed. Nothing to do.\n'}"
|
|
: "${message_geofence_enter:='%s entered geofence %s.'}"
|
|
: "${message_geofence_exit:='%s left geofence %s.'}"
|
|
: "${message_device_online:='On %s Traccar Client app is now active.'}"
|
|
: "${message_device_unknown:='On %s Traccar Client app has not checked in for 10 minutes, the app is likely off now.'}"
|
|
: "${message_device_unhandled:='For %s we do not want to send a message to Signal. Nothing to do.\n'}"
|
|
: "${message_event_other:='%s triggered event "%s" in Traccar server.'}"
|
|
: "${allow_unique_device_ids_posix_ere:=''}"
|
|
|
|
# Mandatory, user must specify
|
|
: "${signal_sender_phone_number:?'Please specify the signal-cli-rest-api phone number of your sender Signal account. Place a file named '"'${conf_file_resolved_file_name}'"' next to this script (same dir) and define a variable signal_sender_phone_number='"'"'value'"'"' in it.'}"
|
|
: "${signal_recipients_array:?'Please specify recipients like so: ["group.ImxvbmdpdH=","recipient.21","+18005550111","i-am-a-uuid"]. Place a file named '"'${conf_file_resolved_file_name}'"' next to this script (same dir) and define a variable signal_recipients_array='"'"'value'"'"' in it.'}"
|
|
: "${signal_api_endpoint_full_path:?'Please specify the signal-cli-rest-api full URL for sending a message like so: https://fully.qualified.domain.name/v2/send. Place a file named '"'${conf_file_resolved_file_name}'"' next to this script (same dir) and define a variable signal_api_endpoint_full_path='"'"'value'"'"' in it.'}"
|
|
}
|
|
|
|
function get_event_data() {
|
|
local device_unique_id
|
|
device_unique_id="$(<<<"${payload}" jq --raw-output '.device.uniqueId')"
|
|
|
|
device_name="$(<<<"${payload}" jq --raw-output '.device.name')"
|
|
event_type="$(<<<"${payload}" jq --raw-output '.event.type')"
|
|
|
|
# Discard event and stop any further action unless event is allow-listed
|
|
if ! [[ "${event_type}" =~ ${allow_list_events} ]]; then
|
|
printf -- "${message_event_type_not_allowed}" "${device_name}"
|
|
exit 0
|
|
fi
|
|
|
|
if [[ "${event_type}" = 'geofenceEnter' || "${event_type}" = 'geofenceExit' ]]; then
|
|
battery_level="$(<<<"${payload}" jq --raw-output '.position.attributes.batteryLevel')"
|
|
battery_level="$(echo "${battery_level}"' / 1' | bc)"
|
|
fi
|
|
|
|
if ! [[ "${device_unique_id}" =~ ${allow_unique_device_ids_posix_ere} ]]; then
|
|
printf -- "${message_device_unhandled}" "${device_name}"
|
|
exit 0
|
|
fi
|
|
}
|
|
|
|
function craft_message() {
|
|
local geofence_name
|
|
case "${event_type}" in
|
|
'geofenceEnter')
|
|
geofence_name="$(<<<"${payload}" jq --raw-output '.geofence.name')"
|
|
message="${message_geofence_enter}"
|
|
message="$(printf -- "${message}" "${device_name}" "${geofence_name}" "${battery_level}")"
|
|
;;
|
|
'geofenceExit')
|
|
geofence_name="$(<<<"${payload}" jq --raw-output '.geofence.name')"
|
|
message="${message_geofence_exit}"
|
|
message="$(printf -- "${message}" "${device_name}" "${geofence_name}" "${battery_level}")"
|
|
;;
|
|
'deviceOnline')
|
|
message="${message_device_online}"
|
|
message="$(printf -- "${message}" "${device_name}")"
|
|
;;
|
|
'deviceUnknown')
|
|
message="${message_device_unknown}"
|
|
message="$(printf -- "${message}" "${device_name}")"
|
|
;;
|
|
*)
|
|
message="${message_event_other}"
|
|
message="$(printf -- "${message}" "${device_name}" "${event_type}")"
|
|
;;
|
|
esac
|
|
}
|
|
|
|
function send_to_signal() {
|
|
local signal_message
|
|
signal_message="${1}"
|
|
curl \
|
|
--silent \
|
|
--request 'POST' \
|
|
--header 'Content-Type: application/json' \
|
|
--data '{"message":"'"${signal_message}"'","number":"'"${signal_sender_phone_number}"'","recipients":'"${signal_recipients_array}"'}' \
|
|
"${signal_api_endpoint_full_path}"
|
|
}
|
|
|
|
load_config
|
|
get_event_data
|
|
craft_message
|
|
send_to_signal "${message}"
|