>>106431090
bb.edn
{:tasks
{server {:doc "Run a server on `/tmp/notify-send.sock`."
:task (shell "socat UNIX-LISTEN:/tmp/notify-send.sock,fork EXEC:./notify.clj")}
client {:doc "Pipe an EDN expression through socat to send a request to the server."
:task (shell "socat - UNIX-CONNECT:/tmp/notify-send.sock")}
ssh {:doc "Forward unix domain socket to a remote server."
:task (let [remote (System/getenv "REMOTE")]
(shell "ssh" "-R" "/tmp/notify-send.sock:/tmp/notify-send.sock" remote))}
autossh {:doc "Forward unix domain socket to a remote server using autossh instead of ssh."
:task (let [remote (System/getenv "REMOTE")]
(shell "autossh" "-M" "0" remote "-N" "-R" "/tmp/notify-send.sock:/tmp/notify-send.sock"))}
}}
notify.clj
#!/usr/bin/env bb
(ns script
(:require [clojure.edn :as edn]
[babashka.process :refer [shell]]))
(def defaults "Default options for notify-send" {})
(defn notify
"Shell out to notify-send with the given parameters."
([message]
(notify {} "ATTENTION" message))
([title message]
(notify {} title message))
([opts title message]
(let [final (merge defaults opts)]
(->> final
(map (fn [[key value]] [key value]))
(flatten)
(#(conj % "notify-send")) ; prepend to beginning
(vec)
(#(conj % title)) ; append to end
(#(conj % message)) ; append to end
(apply shell)
))))
;; Read one EDN expression from `*in*` and use it as arguments to `notify`.
(apply notify (edn/read *in*))
I wanted remote servers to be able to send me local desktop notifications, so I used babashka and socat to write a wrapper around notify-send to make it a server.
Run server locally
bb server
Test server locally
echo '["hello"]' | bb client
Expose server to remote
env REMOTE=anon@remote.org bb ssh