diff --git a/kubernetes/apps/anime/sonarr/app/helmrelease.yaml b/kubernetes/apps/anime/sonarr/app/helmrelease.yaml
index 68326e9c..31f5bbc1 100644
--- a/kubernetes/apps/anime/sonarr/app/helmrelease.yaml
+++ b/kubernetes/apps/anime/sonarr/app/helmrelease.yaml
@@ -117,3 +117,14 @@ spec:
path: /moria/media/
globalMounts:
- path: /data/moria-media
+ scripts:
+ type: configMap
+ name: sonarr-configmap
+ defaultMode: 0775
+ globalMounts:
+ - path: /scripts/pushover-notify.sh
+ subPath: pushover-notify.sh
+ readOnly: true
+ - path: /scripts/refresh-series.sh
+ subPath: refresh-series.sh
+ readOnly: true
diff --git a/kubernetes/apps/anime/sonarr/app/kustomization.yaml b/kubernetes/apps/anime/sonarr/app/kustomization.yaml
index be13d2db..e07328f3 100644
--- a/kubernetes/apps/anime/sonarr/app/kustomization.yaml
+++ b/kubernetes/apps/anime/sonarr/app/kustomization.yaml
@@ -6,3 +6,12 @@ resources:
- ./externalsecret.yaml
- ./helmrelease.yaml
- ../../../../templates/volsync
+configMapGenerator:
+ - name: sonarr-configmap
+ files:
+ - pushover-notify.sh=./resources/pushover-notify.sh
+ - refresh-series.sh=./resources/refresh-series.sh
+generatorOptions:
+ disableNameSuffixHash: true
+ annotations:
+ kustomize.toolkit.fluxcd.io/substitute: disabled
diff --git a/kubernetes/apps/anime/sonarr/app/resources/pushover-notify.sh b/kubernetes/apps/anime/sonarr/app/resources/pushover-notify.sh
new file mode 100644
index 00000000..38423526
--- /dev/null
+++ b/kubernetes/apps/anime/sonarr/app/resources/pushover-notify.sh
@@ -0,0 +1,85 @@
+#!/usr/bin/env bash
+# shellcheck disable=SC2154
+set -euo pipefail
+
+# User defined variables for pushover
+PUSHOVER_USER_KEY="${PUSHOVER_USER_KEY:-required}"
+PUSHOVER_TOKEN="${PUSHOVER_TOKEN:-required}"
+PUSHOVER_PRIORITY="${PUSHOVER_PRIORITY:-"-2"}"
+
+if [[ "${sonarr_eventtype:-}" == "Test" ]]; then
+ PUSHOVER_PRIORITY="1"
+ printf -v PUSHOVER_TITLE \
+ "Test Notification"
+ printf -v PUSHOVER_MESSAGE \
+ "Howdy this is a test notification from %s" \
+ "${sonarr_instancename:-Sonarr}"
+ printf -v PUSHOVER_URL \
+ "%s" \
+ "${sonarr_applicationurl:-localhost}"
+ printf -v PUSHOVER_URL_TITLE \
+ "Open %s" \
+ "${sonarr_instancename:-Sonarr}"
+fi
+
+if [[ "${sonarr_eventtype:-}" == "Download" ]]; then
+ printf -v PUSHOVER_TITLE \
+ "Episode %s" \
+ "$( [[ "${sonarr_isupgrade}" == "True" ]] && echo "Upgraded" || echo "Downloaded" )"
+ printf -v PUSHOVER_MESSAGE \
+ "%s (S%02dE%02d)\n%s\n\nQuality: %s\nClient: %s" \
+ "${sonarr_series_title}" \
+ "${sonarr_episodefile_seasonnumber}" \
+ "${sonarr_episodefile_episodenumbers}" \
+ "${sonarr_episodefile_episodetitles}" \
+ "${sonarr_episodefile_quality:-Unknown}" \
+ "${sonarr_download_client:-Unknown}"
+ printf -v PUSHOVER_URL \
+ "%s/series/%s" \
+ "${sonarr_applicationurl:-localhost}" \
+ "${sonarr_series_titleslug}"
+ printf -v PUSHOVER_URL_TITLE \
+ "View series in %s" \
+ "${sonarr_instancename:-Sonarr}"
+fi
+
+if [[ "${sonarr_eventtype:-}" == "ManualInteractionRequired" ]]; then
+ PUSHOVER_PRIORITY="1"
+ printf -v PUSHOVER_TITLE \
+ "Episode import requires intervention"
+ printf -v PUSHOVER_MESSAGE \
+ "%s\nClient: %s" \
+ "${sonarr_series_title}" \
+ "${sonarr_download_client:-Unknown}"
+ printf -v PUSHOVER_URL \
+ "%s/activity/queue" \
+ "${sonarr_applicationurl:-localhost}"
+ printf -v PUSHOVER_URL_TITLE \
+ "View queue in %s" \
+ "${sonarr_instancename:-Sonarr}"
+fi
+
+json_data=$(jo \
+ token="${PUSHOVER_TOKEN}" \
+ user="${PUSHOVER_USER_KEY}" \
+ title="${PUSHOVER_TITLE}" \
+ message="${PUSHOVER_MESSAGE}" \
+ url="${PUSHOVER_URL}" \
+ url_title="${PUSHOVER_URL_TITLE}" \
+ priority="${PUSHOVER_PRIORITY}" \
+ html="1"
+)
+
+status_code=$(curl \
+ --silent \
+ --write-out "%{http_code}" \
+ --output /dev/null \
+ --request POST \
+ --header "Content-Type: application/json" \
+ --data-binary "${json_data}" \
+ "https://api.pushover.net/1/messages.json" \
+)
+
+printf "pushover notification returned with HTTP status code %s and payload: %s\n" \
+ "${status_code}" \
+ "$(echo "${json_data}" | jq --compact-output)" >&2
diff --git a/kubernetes/apps/anime/sonarr/app/resources/refresh-series.sh b/kubernetes/apps/anime/sonarr/app/resources/refresh-series.sh
new file mode 100644
index 00000000..be570f16
--- /dev/null
+++ b/kubernetes/apps/anime/sonarr/app/resources/refresh-series.sh
@@ -0,0 +1,21 @@
+#!/usr/bin/env bash
+# shellcheck disable=SC2154
+set -euo pipefail
+
+CURL_CMD=(curl -fsSL --header "X-Api-Key: ${SONARR__AUTH__APIKEY:-}")
+SONARR_API_URL="http://localhost:${SONARR__SERVER__PORT:-}/api/v3"
+
+if [[ "${sonarr_eventtype:-}" == "Grab" ]]; then
+ tba=$("${CURL_CMD[@]}" "${SONARR_API_URL}/episode?seriesId=${sonarr_series_id:-}" | jq --raw-output '
+ [.[] | select((.title == "TBA") or (.title == "TBD"))] | length
+ ')
+
+ if (( tba > 0 )); then
+ echo "INFO: Refreshing series ${sonarr_series_id:-} due to TBA/TBD episodes found"
+ "${CURL_CMD[@]}" \
+ --request POST \
+ --header "Content-Type: application/json" \
+ --data-binary '{"name": "RefreshSeries", "seriesId": '"${sonarr_series_id:-}"'}' \
+ "${SONARR_API_URL}/command" &>/dev/null
+ fi
+fi