88551536e6
Amp-Thread-ID: https://ampcode.com/threads/T-019cc404-c628-759e-a50b-f5eeea35b91f Co-authored-by: Amp <amp@ampcode.com>
264 lines
8.0 KiB
Bash
264 lines
8.0 KiB
Bash
#!/bin/bash
|
|
|
|
#############################################################
|
|
#### ntfy Desktop Client Setup for Linux ####
|
|
#### Subscribe to ntfy push notifications with desktop ####
|
|
#### alerts via systemd user service ####
|
|
#### ####
|
|
#### Author: Phil Connor ####
|
|
#### Contact: contact@mylinux.work ####
|
|
#### License: MIT ####
|
|
#### Version: 1.0 ####
|
|
#### ####
|
|
#### Usage: ./ntfy-client-setup-linux.sh ####
|
|
#############################################################
|
|
|
|
set -euo pipefail
|
|
|
|
NTFY_VERSION="2.11.0"
|
|
|
|
# ── Detect the actual desktop user ─────────────────────────
|
|
# Handles both sudo and non-sudo execution
|
|
if [ -n "${SUDO_USER:-}" ]; then
|
|
DESKTOP_USER="$SUDO_USER"
|
|
DESKTOP_HOME=$(getent passwd "$SUDO_USER" | cut -d: -f6)
|
|
else
|
|
DESKTOP_USER="$USER"
|
|
DESKTOP_HOME="$HOME"
|
|
fi
|
|
|
|
CONFIG_DIR="$DESKTOP_HOME/.config/ntfy"
|
|
SYSTEMD_DIR="$DESKTOP_HOME/.config/systemd/user"
|
|
|
|
# ── Helper functions ───────────────────────────────────────
|
|
|
|
info() { echo -e " ✓ $*"; }
|
|
warn() { echo -e " ⚠ $*"; }
|
|
error() { echo -e " ✗ $*" >&2; }
|
|
|
|
run_as_user() {
|
|
# Run a command as the desktop user (handles sudo case)
|
|
if [ "$(id -u)" -eq 0 ] && [ "$DESKTOP_USER" != "root" ]; then
|
|
sudo -u "$DESKTOP_USER" "$@"
|
|
else
|
|
"$@"
|
|
fi
|
|
}
|
|
|
|
install_package() {
|
|
local pkg_apt="$1"
|
|
local pkg_dnf="${2:-$1}"
|
|
local pkg_pacman="${3:-$1}"
|
|
|
|
if command -v apt &> /dev/null; then
|
|
sudo apt install -y "$pkg_apt"
|
|
elif command -v dnf &> /dev/null; then
|
|
sudo dnf install -y "$pkg_dnf"
|
|
elif command -v pacman &> /dev/null; then
|
|
sudo pacman -S --noconfirm "$pkg_pacman"
|
|
else
|
|
error "Could not detect package manager. Please install '$pkg_apt' manually."
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
# ── Banner ─────────────────────────────────────────────────
|
|
|
|
echo ""
|
|
echo "==========================================="
|
|
echo " ntfy Desktop Client Setup for Linux"
|
|
echo "==========================================="
|
|
echo ""
|
|
echo " User: $DESKTOP_USER"
|
|
echo " Home: $DESKTOP_HOME"
|
|
echo ""
|
|
|
|
# ── Step 1: Install dependencies ───────────────────────────
|
|
|
|
echo "── Checking dependencies ──────────────────"
|
|
echo ""
|
|
|
|
if ! command -v notify-send &> /dev/null; then
|
|
echo " Installing libnotify for desktop notifications..."
|
|
install_package libnotify-bin libnotify libnotify
|
|
info "libnotify installed"
|
|
else
|
|
info "notify-send already available"
|
|
fi
|
|
|
|
if ! command -v curl &> /dev/null; then
|
|
echo " Installing curl..."
|
|
install_package curl curl curl
|
|
info "curl installed"
|
|
else
|
|
info "curl already available"
|
|
fi
|
|
|
|
echo ""
|
|
|
|
# ── Step 2: Install ntfy binary ────────────────────────────
|
|
|
|
echo "── Installing ntfy client ─────────────────"
|
|
echo ""
|
|
|
|
# Determine install location based on privileges
|
|
if [ "$(id -u)" -eq 0 ] || sudo -n true 2>/dev/null; then
|
|
NTFY_BIN="/usr/local/bin/ntfy"
|
|
INSTALL_SYSTEM=true
|
|
else
|
|
NTFY_BIN="$DESKTOP_HOME/.local/bin/ntfy"
|
|
INSTALL_SYSTEM=false
|
|
fi
|
|
|
|
if [ -x "$NTFY_BIN" ]; then
|
|
info "ntfy already installed at $NTFY_BIN"
|
|
else
|
|
# Detect architecture
|
|
ARCH=$(uname -m)
|
|
case "$ARCH" in
|
|
x86_64) NTFY_ARCH="amd64" ;;
|
|
aarch64) NTFY_ARCH="arm64" ;;
|
|
armv7l) NTFY_ARCH="armv7" ;;
|
|
*)
|
|
error "Unsupported architecture: $ARCH"
|
|
exit 1
|
|
;;
|
|
esac
|
|
|
|
DOWNLOAD_URL="https://github.com/binwiederhier/ntfy/releases/download/v${NTFY_VERSION}/ntfy_${NTFY_VERSION}_linux_${NTFY_ARCH}.tar.gz"
|
|
echo " Downloading ntfy v${NTFY_VERSION} (${NTFY_ARCH})..."
|
|
|
|
TEMP_DIR=$(mktemp -d)
|
|
trap 'rm -rf "$TEMP_DIR"' EXIT
|
|
|
|
curl -sL -o "$TEMP_DIR/ntfy.tar.gz" "$DOWNLOAD_URL"
|
|
tar -xzf "$TEMP_DIR/ntfy.tar.gz" -C "$TEMP_DIR"
|
|
|
|
if [ "$INSTALL_SYSTEM" = true ]; then
|
|
sudo find "$TEMP_DIR" -name "ntfy" -type f -exec mv {} "$NTFY_BIN" \;
|
|
sudo chmod +x "$NTFY_BIN"
|
|
else
|
|
mkdir -p "$(dirname "$NTFY_BIN")"
|
|
find "$TEMP_DIR" -name "ntfy" -type f -exec mv {} "$NTFY_BIN" \;
|
|
chmod +x "$NTFY_BIN"
|
|
fi
|
|
|
|
rm -rf "$TEMP_DIR"
|
|
trap - EXIT
|
|
|
|
info "ntfy installed to $NTFY_BIN"
|
|
fi
|
|
|
|
echo ""
|
|
|
|
# ── Step 3: Interactive configuration ──────────────────────
|
|
|
|
echo "── Configuration ──────────────────────────"
|
|
echo ""
|
|
|
|
read -rp " Server URL [https://ntfy.example.com]: " INPUT_SERVER
|
|
SERVER_URL="${INPUT_SERVER:-https://ntfy.example.com}"
|
|
|
|
echo ""
|
|
read -rp " Access token (leave empty for public topics): " ACCESS_TOKEN
|
|
|
|
echo ""
|
|
echo " Enter topics to subscribe to (space-separated)."
|
|
echo " Examples: alerts monitoring backup-status"
|
|
read -rp " Topics: " TOPICS
|
|
|
|
if [ -z "$TOPICS" ]; then
|
|
error "At least one topic is required."
|
|
exit 1
|
|
fi
|
|
|
|
echo ""
|
|
echo " Server: $SERVER_URL"
|
|
echo " Topics: $TOPICS"
|
|
echo " Token: ${ACCESS_TOKEN:+(set)}${ACCESS_TOKEN:-(none)}"
|
|
echo ""
|
|
|
|
# ── Step 4: Create client config ───────────────────────────
|
|
|
|
echo "── Creating configuration files ────────────"
|
|
echo ""
|
|
|
|
run_as_user mkdir -p "$CONFIG_DIR"
|
|
run_as_user mkdir -p "$SYSTEMD_DIR"
|
|
|
|
# Build the subscribe section for client.yml
|
|
SUBSCRIBE_BLOCK=""
|
|
for topic in $TOPICS; do
|
|
SUBSCRIBE_BLOCK+=" - topic: ${SERVER_URL}/${topic}"$'\n'
|
|
if [ -n "$ACCESS_TOKEN" ]; then
|
|
SUBSCRIBE_BLOCK+=" token: ${ACCESS_TOKEN}"$'\n'
|
|
fi
|
|
done
|
|
|
|
# Write client.yml
|
|
cat > "$CONFIG_DIR/client.yml" << EOF
|
|
# ntfy client configuration
|
|
# Documentation: https://docs.ntfy.sh/subscribe/cli/
|
|
|
|
subscribe:
|
|
${SUBSCRIBE_BLOCK}EOF
|
|
|
|
# Fix ownership if running as root
|
|
if [ "$(id -u)" -eq 0 ] && [ "$DESKTOP_USER" != "root" ]; then
|
|
chown -R "$DESKTOP_USER:$DESKTOP_USER" "$CONFIG_DIR"
|
|
fi
|
|
|
|
info "Config saved to $CONFIG_DIR/client.yml"
|
|
|
|
# ── Step 5: Create systemd user service ────────────────────
|
|
|
|
cat > "$SYSTEMD_DIR/ntfy-subscribe.service" << EOF
|
|
[Unit]
|
|
Description=ntfy desktop notification subscriber
|
|
After=network-online.target
|
|
Wants=network-online.target
|
|
|
|
[Service]
|
|
Type=simple
|
|
ExecStart=${NTFY_BIN} subscribe --from-config
|
|
Restart=on-failure
|
|
RestartSec=10
|
|
|
|
[Install]
|
|
WantedBy=default.target
|
|
EOF
|
|
|
|
# Fix ownership if running as root
|
|
if [ "$(id -u)" -eq 0 ] && [ "$DESKTOP_USER" != "root" ]; then
|
|
chown -R "$DESKTOP_USER:$DESKTOP_USER" "$SYSTEMD_DIR"
|
|
fi
|
|
|
|
info "Systemd user service created"
|
|
|
|
echo ""
|
|
|
|
# ── Done ───────────────────────────────────────────────────
|
|
|
|
echo "==========================================="
|
|
echo " Setup Complete"
|
|
echo "==========================================="
|
|
echo ""
|
|
echo " To start receiving notifications, run as $DESKTOP_USER"
|
|
echo " from a graphical desktop session:"
|
|
echo ""
|
|
echo " systemctl --user daemon-reload"
|
|
echo " systemctl --user enable --now ntfy-subscribe"
|
|
echo ""
|
|
echo " Useful commands:"
|
|
echo ""
|
|
echo " Status: systemctl --user status ntfy-subscribe"
|
|
echo " Logs: journalctl --user -u ntfy-subscribe -f"
|
|
echo " Restart: systemctl --user restart ntfy-subscribe"
|
|
echo " Stop: systemctl --user stop ntfy-subscribe"
|
|
echo " Disable: systemctl --user disable --now ntfy-subscribe"
|
|
echo ""
|
|
echo " Test with:"
|
|
echo ""
|
|
echo " curl -d 'Hello from ntfy!' ${SERVER_URL}/${TOPICS%% *}"
|
|
echo ""
|