Pushover Applications
Thanks for this great tool. I can think of several use cases where applications I use support Gotify but not Pushover. However, as I am a heavy Pushover user, these alerts can get a bit lost since I cannot specify an application token as an environment variable. If I am not mistaken this script uses the ntfy library under the covers, and it does support the application token as described here. Not being a developer I do not have a good sense of how much effort this would be, but I figured I would ask. Cheers!
Hey, sorry for the delay.
This should indeed be possible. I'd love to tackle this but my home lab is currently non functional because of failing hardware.
I will take a look at this once this is resolved.
I've made some minor changes to allow mapping of Gotify Apps to Pushover Applications, it works for me but @sebw need to review and update his docker if he deems this is an appropriate solution.
You need to add some additional environment variables:
export PUSHOVER_APP1_TOKEN=[your pushover app token1]
export PUSHOVER_APP2_TOKEN=[your pushover app token2]
I've made it so if no pushover token is mapped the message is dropped, this suits my needs but it could easily be be adapted to send those messages directly to the root Pushover user (the way Pushtify is currently works).
import os
import json
import websocket
import ntfy
# Load environment
pushover_userkey = os.environ.get("PUSHOVER_USERKEY")
gotify_host = os.environ.get("GOTIFY_HOST")
gotify_token = os.environ.get("GOTIFY_TOKEN")
# Mapping Gotify app IDs -> Pushover API tokens
# Define your mappings here or via environment variables
APP_MAP = {
"1": os.environ.get("PUSHOVER_APP1_TOKEN"),
"2": os.environ.get("PUSHOVER_APP2_TOKEN"),
# Add more as needed
}
if not (pushover_userkey and gotify_host and gotify_token):
raise RuntimeError("Missing one of PUSHOVER_USERKEY, GOTIFY_HOST, GOTIFY_TOKEN")
# Protocol mapping
websocket_protocol = {"http": "ws", "https": "wss"}.get(
os.environ.get("GOTIFY_PROTOCOL", "https"), "wss"
)
def map_priority(priority: int) -> str:
if priority <= 0: return "-1"
if priority <= 3: return "0"
if priority <= 7: return "1"
return "2"
def on_message(ws, message):
try:
msg = json.loads(message)
pushover_prio = map_priority(msg.get("priority", 0))
appid = str(msg.get("appid"))
pushover_api_token = APP_MAP.get(appid)
if not pushover_api_token:
print(f"⚠️ No Pushover token mapped for Gotify appid {appid}, skipping")
return
ntfy.notify(
msg.get("message", ""),
msg.get("title", "Gotify"),
priority=pushover_prio,
backend="pushover",
user_key=pushover_userkey,
api_token=pushover_api_token
)
print(f"Forwarded Gotify appid {appid}: {msg.get('title')} -> Pushover")
except Exception as e:
print(f"Error handling message: {e}")
def on_error(ws, error):
print(f"WebSocket error: {error}")
def on_close(ws, close_status_code, close_msg):
print(f"Closed connection: {close_status_code} {close_msg}")
def on_open(ws):
print("Connected to Gotify")
if __name__ == "__main__":
headers = [f"X-Gotify-Key: {gotify_token}"]
ws_url = f"{websocket_protocol}://{gotify_host}/stream"
wsapp = websocket.WebSocketApp(
ws_url,
header=headers,
on_open=on_open,
on_message=on_message,
on_error=on_error,
on_close=on_close,
)
wsapp.run_forever()