#!/usr/bin/env bash # Taken from here: https://raw.githubusercontent.com/vlevit/notify-send.sh/master/notify-action.sh GDBUS_MONITOR_PID=/tmp/notify-action-dbus-monitor.$$.pid GDBUS_MONITOR=(gdbus monitor --session --dest org.freedesktop.Notifications --object-path /org/freedesktop/Notifications) NOTIFICATION_ID="$1" if [[ -z "$NOTIFICATION_ID" ]]; then echo "no notification id passed: $@" exit 1; fi shift ACTION_COMMANDS=("$@") if [[ -z "$ACTION_COMMANDS" ]]; then echo "no action commands passed: $@" exit 1; fi cleanup() { rm -f "$GDBUS_MONITOR_PID" } create_pid_file(){ rm -f "$GDBUS_MONITOR_PID" umask 077 touch "$GDBUS_MONITOR_PID" } invoke_action() { invoked_action_id="$1" local action="" cmd="" for index in "${!ACTION_COMMANDS[@]}"; do if [[ $((index % 2)) == 0 ]]; then action="${ACTION_COMMANDS[$index]}" else cmd="${ACTION_COMMANDS[$index]}" if [[ "$action" == "$invoked_action_id" ]]; then bash -c "${cmd}" & fi fi done } monitor() { create_pid_file ( "${GDBUS_MONITOR[@]}" & echo $! >&3 ) 3>"$GDBUS_MONITOR_PID" | while read -r line do local closed_notification_id="$(sed '/^\/org\/freedesktop\/Notifications: org.freedesktop.Notifications.NotificationClosed (uint32 \([0-9]\+\), uint32 [0-9]\+)$/!d;s//\1/' <<< "$line")" if [[ -n "$closed_notification_id" ]]; then if [[ "$closed_notification_id" == "$NOTIFICATION_ID" ]]; then invoke_action close break fi else local action_invoked="$(sed '/\/org\/freedesktop\/Notifications: org.freedesktop.Notifications.ActionInvoked (uint32 \([0-9]\+\), '\''\(.*\)'\'')$/!d;s//\1:\2/' <<< "$line")" IFS=: read invoked_id action_id <<< "$action_invoked" if [[ "$invoked_id" == "$NOTIFICATION_ID" ]]; then invoke_action "$action_id" break fi fi done kill $(<"$GDBUS_MONITOR_PID") cleanup } monitor