feat(script): Add script
This commit is contained in:
parent
013648addc
commit
108be98ec3
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
.idea
|
||||
*.conf
|
97
notify_signal_about_traccar_events.sh
Executable file
97
notify_signal_about_traccar_events.sh
Executable file
@ -0,0 +1,97 @@
|
||||
#!/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
|
||||
: "${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_offline:='On %s Traccar Client app is now off.'}"
|
||||
: "${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')"
|
||||
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}")"
|
||||
;;
|
||||
'deviceOffline')
|
||||
message="${message_device_offline}"
|
||||
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}"
|
||||
echo "${signal_message}"
|
||||
curl \
|
||||
--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}"
|
39
notify_signal_about_traccar_events.sh.conf.example
Normal file
39
notify_signal_about_traccar_events.sh.conf.example
Normal file
@ -0,0 +1,39 @@
|
||||
# First positional argument '%s' is Traccar device name, second
|
||||
# positional argument '%s' is geofence name, third one is battery level.
|
||||
# This cannot be switched around, please word your message accordingly.
|
||||
# Notice how a line break takes the form '\\n', that's two backslashes.
|
||||
message_geofence_enter='%s entered geofence %s.\\n\\nBattery level %s%%.'
|
||||
message_geofence_exit='%s left geofence %s.\\n\\nBattery level %s%%.'
|
||||
|
||||
# Argument '%s' is Traccar device name
|
||||
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_offline='On %s Traccar Client app is now off.'
|
||||
|
||||
# Argument '%s' is Traccar device name but this one unlike the three
|
||||
# message strings before is used as stdout log output when the device ID
|
||||
# that triggered an event doesn't match our allow list in
|
||||
# allow_unique_device_ids_posix_ere, see below. Note a trailing '\n'
|
||||
# (backslash-n) at the end of this string. This is a Bash printf
|
||||
# replacement string.
|
||||
message_device_unhandled='For %s we do not want to send Signal messages. Nothing to do.\n'
|
||||
|
||||
# First positional argument '%s' is Traccar device name, second
|
||||
# positional argument '%s' is event name. This cannot be switched
|
||||
# around, please word your message accordingly.
|
||||
message_event_other='%s triggered event "%s" in Traccar server.'
|
||||
|
||||
# If this is a non-empty value we'll use it to only handle Traccar
|
||||
# events for these unique device IDs. Events triggered by other device
|
||||
# IDs will be discarded. If this is an empty string or if it's not
|
||||
# declared at all we'll handle events for all device IDs. In Traccar
|
||||
# server every device has a unique ID that's distinct from its
|
||||
# pretty-printed device name. This is a Posix Extended Regular
|
||||
# Expression (ERE). Most Perl-Compatible Regular Expression (PCRE)
|
||||
# syntax works. Most notably lookarounds are unsupported in ERE.
|
||||
allow_unique_device_ids_posix_ere='^(901874|81919333|9991212)$'
|
||||
|
||||
# signal-cli-rest-api config
|
||||
signal_sender_phone_number='+18005550199'
|
||||
signal_recipients_array='["group.ImxvbmdpdH=","recipient.21","+18005550111","i-am-a-uuid"]'
|
||||
signal_api_endpoint_full_path='https://fully.qualified.domain.name/v2/send'
|
Loading…
x
Reference in New Issue
Block a user