diff --git a/README.md b/README.md index e48a580..3ca92cd 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,35 @@ # jellyfin-notification-webhook -Webhook for processing Jellyfin notifications. \ No newline at end of file +## Summary + +Webhook for processing Jellyfin notifications. +It used `webhook` (see below) to receive the notification payload, and then `ntfy` to send the prepared notification. + +## Why + +There is no Jellyfin plugin that supports `ntfy`, my chosen notification service. +While there is a generic webhook plugin for Jellyfin, editing and troubleshooting it is tedious and error-prone. + +## Setup + +1. Copy the content of `hooks.json` file to your your `webhook` configuration file. +2. In Jellyfin, install the Webhook notification plugin. +3. Restart Jellyfin. +4. Navigate to the plugin configuration page and click on `Add Generic Destination`. +5. Set webhook URL to whatever your `webhook` endpoint is. +6. Check these `Notification Type`: + - Authentication Failure + - Item Added + - Pending Restart + - Plugin Uninstalled + - User Deleted + - User Locked Out +7. Lastly, check the `Send All Properties (ignores template)` checkbox. +8. Copy the `jellyfin.sh` script to your `webhook` script folder. +9. Add the `execute` permission to it, for example by running `chmod +x jellyfin.sh`. +10. Edit the `jellyfin.sh` script, adjusting the values of `NTFY_SERVER_URL` and `NTFY_CHANNEL` based on your setup. + +## Links + +* https://github.com/adnanh/webhook +* https://github.com/binwiederhier/ntfy \ No newline at end of file diff --git a/hooks.json b/hooks.json new file mode 100644 index 0000000..a6bb486 --- /dev/null +++ b/hooks.json @@ -0,0 +1,12 @@ +[ + { + "id": "jellyfin-receive", + "execute-command": "jellyfin", + "command-working-directory": "/var/webhook", + "pass-arguments-to-command": [ + { + "source": "entire-payload" + } + ] + } +] diff --git a/jellyfin.sh b/jellyfin.sh new file mode 100755 index 0000000..ed3ad56 --- /dev/null +++ b/jellyfin.sh @@ -0,0 +1,98 @@ +#!/usr/bin/env bash +set -euo pipefail + +NTFY_SERVER_URL=${NTFY_SERVER_URL:-ntfy.sh} +NTFY_CHANNEL=${NTFY_CHANNEL:-jellyfin_notications} +ICON_URL=${ICON_URL:-https://raw.githubusercontent.com/NX211/homer-icons/master} +TMDB_URL="https://www.themoviedb.org" + +notify() { +# message title action tags priority + curl -s \ + -H "Title: ${2}" \ + -H "Icon: ${ICON_URL}/png/jellyfin.png" \ + -H "Actions: ${3}" \ + -H "Tags: ${4}" \ + -H "Priority: ${5}" \ + -d "${1}" "${NTFY_SERVER_URL}/${NTFY_CHANNEL}" +} + +get_value() { + jq "$1" <(echo "$JSON") | tr -d '"' +} + +JSON=$1 +ARTIST=$(get_value ".Artist") +YEAR=$(get_value ".Year") +TYPE=$(get_value ".NotificationType") +ITEM_TYPE=$(get_value ".ItemType") +ITEM_NAME=$(get_value ".Name") +NOTIFICATION_USERNAME=$(get_value ".NotificationUsername") +PLUGIN_NAME=$(get_value ".PluginName") +PLUGIN_VERSION=$(get_value ".PluginVersion") +SERVER=$(get_value .ServerName) +VERSION=$(get_value .ServerVersion) +SERIES_NAME=$(get_value .SeriesName) +EPISODE_NUMBER=$(get_value .EpisodeNumber00) +SEASON_NUMBER=$(get_value .SeasonNumber00) +PROVIDER_TMDB=$(get_value .Provider_tmdb) +PROVIDER_TVDB=$(get_value .Provider_tvdb) +TAGS="media" + +case "$TYPE" in + PluginUninstalled) + PRIORITY="2" + MESSAGE="Plugin $PLUGIN_NAME $PLUGIN_VERSION was uninstalled." + ;; + ItemAdded) + PRIORITY="2" + case "$ITEM_TYPE" in + MusicAlbum) + [ "$ARTIST" = "null" ] && ARTIST="Various Artists" + MESSAGE="New music has been added: $ITEM_NAME by $ARTIST ($YEAR)." + ;; + Episode) + MESSAGE="$SERIES_NAME ${SEASON_NUMBER}x${EPISODE_NUMBER} - $ITEM_NAME ($YEAR) has been added." + ACTION="view, TMDB, ${TMDB_URL}/series/${PROVIDER_TVDB}" + ;; + Movie) + MESSAGE="$ITEM_NAME ($YEAR) has been added." + ACTION="view, TMDB, ${TMDB_URL}/movie/${PROVIDER_TMDB}" + ;; + # ignore these + Audio | Season | Series) + ;; + *) + MESSAGE="Item of type $ITEM_TYPE with the name $ITEM_NAME has been added to the library." + ;; + esac + ;; + AuthenticationFailure) + PRIORITY="5" + MESSAGE="Authentication for user $NOTIFICATION_USERNAME has failed." + ;; + PendingRestart) + PRIORITY="4" + MESSAGE="Server needs to be restarted." + ;; + UserDeleted) + PRIORITY="3" + MESSAGE="User $NOTIFICATION_USERNAME has been deleted." + ;; + UserLockedOut) + PRIORITY="5" + MESSAGE="User $NOTIFICATION_USERNAME has been locked out." + ;; + *) + PRIORITY="3" + MESSAGE="Unrecognized NoticationType. See the logs." + ;; +esac + +# MESSAGE is empty if a NotificationType or ItemType was ignored +if [[ -z "${MESSAGE:-}" ]]; then + echo "MESSAGE is empty. Ignoring this notification." + exit 0 +fi + +notify "${MESSAGE:-Empty message.}" "Jellyfin $VERSION ($SERVER)" "${ACTION:-}" "${TAGS:-media}" "${PRIORITY:-3}"