From 37396aad71ebaf980d345adb64e82f344c328e23 Mon Sep 17 00:00:00 2001 From: schlump Date: Thu, 8 Feb 2024 17:17:40 +0100 Subject: [PATCH] Add Pushover Support --- front/plugins/_publisher_pushover/README.md | 8 + front/plugins/_publisher_pushover/config.json | 409 ++++++++++++++++++ front/plugins/_publisher_pushover/pushover.py | 105 +++++ 3 files changed, 522 insertions(+) create mode 100755 front/plugins/_publisher_pushover/README.md create mode 100755 front/plugins/_publisher_pushover/config.json create mode 100755 front/plugins/_publisher_pushover/pushover.py diff --git a/front/plugins/_publisher_pushover/README.md b/front/plugins/_publisher_pushover/README.md new file mode 100755 index 00000000..2717edd4 --- /dev/null +++ b/front/plugins/_publisher_pushover/README.md @@ -0,0 +1,8 @@ +## Overview + +A plugin to publish a notification via the Pushover gateway. Enable sending notifications via Pushover. + +### Usage + +- Go to settings and fill in relevant details. + diff --git a/front/plugins/_publisher_pushover/config.json b/front/plugins/_publisher_pushover/config.json new file mode 100755 index 00000000..cec4be3a --- /dev/null +++ b/front/plugins/_publisher_pushover/config.json @@ -0,0 +1,409 @@ +{ + "code_name": "_publisher_pushover", + "unique_prefix": "PUSHOVER", + "plugin_type": "publisher", + "enabled": true, + "data_source": "script", + "show_ui": true, + "localized": [ + "display_name", + "description", + "icon" + ], + "display_name": [ + { + "language_code": "en_us", + "string": "Pushover publisher" + }, + { + "language_code": "es_es", + "string": "Habilitar Pushover" + } + ], + "icon": [ + { + "language_code": "en_us", + "string": "" + } + ], + "description": [ + { + "language_code": "en_us", + "string": "A plugin to publish a notification via the pushover.net" + } + ], + "params": [], + "database_column_definitions": [ + { + "column": "Index", + "css_classes": "col-sm-2", + "show": false, + "type": "label", + "default_value": "", + "options": [], + "localized": [ + "name" + ], + "name": [ + { + "language_code": "en_us", + "string": "N/A" + }, + { + "language_code": "es_es", + "string": "N/A" + } + ] + }, + { + "column": "Plugin", + "css_classes": "col-sm-2", + "show": false, + "type": "label", + "default_value": "", + "options": [], + "localized": [ + "name" + ], + "name": [ + { + "language_code": "en_us", + "string": "N/A" + }, + { + "language_code": "es_es", + "string": "N/A" + } + ] + }, + { + "column": "Object_PrimaryID", + "css_classes": "col-sm-2", + "show": false, + "type": "label", + "default_value": "", + "options": [], + "localized": [ + "name" + ], + "name": [ + { + "language_code": "en_us", + "string": "N/A" + } + ] + }, + { + "column": "Object_SecondaryID", + "css_classes": "col-sm-2", + "show": true, + "type": "label", + "default_value": "", + "options": [], + "localized": [ + "name" + ], + "name": [ + { + "language_code": "en_us", + "string": "Sent when" + } + ] + }, + { + "column": "Watched_Value1", + "css_classes": "col-sm-3", + "show": true, + "type": "eval", + "default_value": "", + "options": [ + { + "type": "eval", + "param": "`${value}`" + } + ], + "localized": [ + "name" + ], + "name": [ + { + "language_code": "en_us", + "string": "Notification GUID" + } + ] + }, + { + "column": "Watched_Value2", + "css_classes": "col-sm-2", + "show": true, + "type": "textarea_readonly", + "default_value": "", + "options": [], + "localized": [ + "name" + ], + "name": [ + { + "language_code": "en_us", + "string": "Response" + } + ] + }, + { + "column": "Watched_Value3", + "css_classes": "col-sm-2", + "show": true, + "type": "label", + "default_value": "", + "options": [], + "localized": [ + "name" + ], + "name": [ + { + "language_code": "en_us", + "string": "Response code" + } + ] + }, + { + "column": "Watched_Value4", + "css_classes": "col-sm-2", + "show": false, + "type": "device_mac", + "default_value": "", + "options": [], + "localized": [ + "name" + ], + "name": [ + { + "language_code": "en_us", + "string": "Device" + } + ] + }, + { + "column": "UserData", + "css_classes": "col-sm-2", + "show": false, + "type": "textbox_save", + "default_value": "", + "options": [], + "localized": [ + "name" + ], + "name": [ + { + "language_code": "en_us", + "string": "Comments" + }, + { + "language_code": "es_es", + "string": "Comentarios" + } + ] + }, + { + "column": "Status", + "css_classes": "col-sm-1", + "show": false, + "type": "replace", + "default_value": "", + "options": [ + { + "equals": "watched-not-changed", + "replacement": "
" + }, + { + "equals": "watched-changed", + "replacement": "
" + }, + { + "equals": "new", + "replacement": "
" + }, + { + "equals": "missing-in-last-scan", + "replacement": "
" + } + ], + "localized": [ + "name" + ], + "name": [ + { + "language_code": "en_us", + "string": "Status" + }, + { + "language_code": "es_es", + "string": "Estado" + } + ] + }, + { + "column": "Extra", + "css_classes": "col-sm-3", + "show": false, + "type": "label", + "default_value": "", + "options": [], + "localized": [ + "name" + ], + "name": [ + { + "language_code": "en_us", + "string": "Extra" + }, + { + "language_code": "es_es", + "string": "Extra" + } + ] + } + ], + "settings": [ + { + "function": "RUN", + "events": [ + "test" + ], + "type": "text.select", + "default_value": "disabled", + "options": [ + "disabled", + "on_notification" + ], + "localized": [ + "name", + "description" + ], + "name": [ + { + "language_code": "en_us", + "string": "When to run" + }, + { + "language_code": "es_es", + "string": "Cuando ejecuta" + } + ], + "description": [ + { + "language_code": "en_us", + "string": "Enable sending notifications via Pushover." + }, + { + "language_code": "es_es", + "string": "Habilitar el envío de notificaciones a través de Pushover." + } + ] + }, + { + "function": "CMD", + "type": "readonly", + "default_value": "python3 /home/pi/pialert/front/plugins/_publisher_pushover/pushover.py", + "options": [], + "localized": [ + "name", + "description" + ], + "name": [ + { + "language_code": "en_us", + "string": "Command" + }, + { + "language_code": "es_es", + "string": "Comando" + } + ], + "description": [ + { + "language_code": "en_us", + "string": "Command to run" + }, + { + "language_code": "es_es", + "string": "Comando a ejecutar" + } + ] + }, + { + "function": "RUN_TIMEOUT", + "type": "integer", + "default_value": 10, + "options": [], + "localized": [ + "name", + "description" + ], + "name": [ + { + "language_code": "en_us", + "string": "Run timeout" + }, + { + "language_code": "es_es", + "string": "Tiempo de espera de ejecución" + }, + { + "language_code": "de_de", + "string": "Wartezeit" + } + ], + "description": [ + { + "language_code": "en_us", + "string": "Maximum time in seconds to wait for the script to finish. If this time is exceeded the script is aborted." + } + ] + }, + { + "function": "USER_KEY", + "type": "text", + "default_value": "USER_KEY", + "options": [], + "localized": [ + "name", + "description" + ], + "name": [ + { + "language_code": "en_us", + "string": "Pushover USER key" + } + ], + "description": [ + { + "language_code": "en_us", + "string": "Your secret Pushsafer USER key." + } + ] + }, + { + "function": "APP_TOKEN", + "type": "text", + "default_value": "APP_TOKEN", + "options": [], + "localized": [ + "name", + "description" + ], + "name": [ + { + "language_code": "en_us", + "string": "Pushover APP Token" + } + ], + "description": [ + { + "language_code": "en_us", + "string": "Your Pushover APP Token." + } + ] + } + ] +} \ No newline at end of file diff --git a/front/plugins/_publisher_pushover/pushover.py b/front/plugins/_publisher_pushover/pushover.py new file mode 100755 index 00000000..78c8c4b3 --- /dev/null +++ b/front/plugins/_publisher_pushover/pushover.py @@ -0,0 +1,105 @@ +#!/usr/bin/env python3 +import os +import pathlib +import sys +import json +import requests + +# Replace these paths with the actual paths to your Pi.Alert directories +sys.path.extend(["/home/pi/pialert/front/plugins", "/home/pi/pialert/pialert"]) + +from plugin_helper import Plugin_Objects, handleEmpty # noqa: E402 +from logger import mylog # noqa: E402 +from helper import timeNowTZ, get_setting_value, hide_string # noqa: E402 +from notification import Notification_obj # noqa: E402 +from database import DB # noqa: E402 + +CUR_PATH = str(pathlib.Path(__file__).parent.resolve()) +RESULT_FILE = os.path.join(CUR_PATH, "last_result.log") + +pluginName = "PUSHOVER" + + +def main(): + mylog("verbose", f"[{pluginName}](publisher) In script") + + # Check if basic config settings supplied + if not validate_config(): + mylog( + "none", + f"[{pluginName}] ⚠ ERROR: Publisher notification gateway not set up correctly. " + f"Check your pialert.conf {pluginName}_* variables.", + ) + return + + # Create a database connection + db = DB() # instance of class DB + db.open() + + # Initialize the Plugin obj output file + plugin_objects = Plugin_Objects(RESULT_FILE) + + # Create a Notification_obj instance + notifications = Notification_obj(db) + + # Retrieve new notifications + new_notifications = notifications.getNew() + + # Process the new notifications + for notification in new_notifications: + # Send notification + response_text, response_status_code = send(notification["Text"]) + + # Log result + plugin_objects.add_object( + primaryId=pluginName, + secondaryId=timeNowTZ(), + watched1=notification["GUID"], + watched2=handleEmpty(response_text), + watched3=response_status_code, + watched4="null", + extra="null", + foreignKey=notification["GUID"], + ) + + plugin_objects.write_result_file() + + +def send(text): + response_text = "" + response_status_code = "" + + user_key = get_setting_value("PUSHOVER_USER_KEY") + app_token = get_setting_value("PUSHOVER_APP_TOKEN") + + mylog("verbose", f'[{pluginName}] PUSHOVER_USER_KEY: "{hide_string(user_key)}"') + mylog("verbose", f'[{pluginName}] PUSHOVER_APP_TOKEN: "{hide_string(app_token)}"') + + try: + response = requests.post( + "https://api.pushover.net/1/messages.json", + data={"token": app_token, "user": user_key, "message": text}, + ) + + # Check if the request was successful (status code 200) + if response.status_code == 200: + response_text = response.text # This captures the response body/message + else: + response_text = json.dumps(response.text) + + except requests.exceptions.RequestException as e: + mylog("none", f"[{pluginName}] ⚠ ERROR: {e}") + response_text = str(e) + + return response_text, response_status_code + + +def validate_config(): + user_key = get_setting_value("PUSHOVER_USER_KEY") + app_token = get_setting_value("PUSHOVER_APP_TOKEN") + + return user_key != "USER_KEY" and app_token != "APP_TOKEN" + + +if __name__ == "__main__": + sys.exit(main())