From d451e54e3418b7210c93b11315526895ed0488a3 Mon Sep 17 00:00:00 2001
From: Bernhard B <bernhard@beroun.io>
Date: Mon, 9 Dec 2019 00:27:06 +0100
Subject: [PATCH] Add Signal Messenger integration (#28537)

* added signalmessenger integration

* allows to send a message (with an attachment) to one or more
  recipients

* added signalmessenger documentation to manifest file

* remove debug logging from signalmessenger integration

* add signalmessenger to .coveragerc

* fixed typo in signalmessenger manifes

* moved service specific code to own pypi library

* updated pysignalclirestapi dependeny in manifest.json

* added pysignalclirestapi requirement for signalmessenger component

* fixed typo in codeowners

* reworked signalmessenger integration based on code review input

* updated requirements for signalmessenger

* small code improvements in signalmessenger integration

* no need to use the get() method to access dict parameters that are
required

* small changes in signalmessenger integration

* re-ordered import statements
* removed empty "requirements" list (not needed)

* changed import order in signalmessenger integration according to PEP 8

* used isort to order includes in signalmessenger integration

* renamed signalmessenger to signal_messenger

* renamed signalmessenger to signal_messenger in CODEOWNERS file

* changed documentation url in signal_messenger integration to new name

* changed signal messenger naming in .coveragerc
---
 .coveragerc                                   |  2 +
 CODEOWNERS                                    |  1 +
 .../components/signal_messenger/__init__.py   |  1 +
 .../components/signal_messenger/manifest.json | 10 +++
 .../components/signal_messenger/notify.py     | 71 +++++++++++++++++++
 requirements_all.txt                          |  3 +
 6 files changed, 88 insertions(+)
 create mode 100644 homeassistant/components/signal_messenger/__init__.py
 create mode 100644 homeassistant/components/signal_messenger/manifest.json
 create mode 100644 homeassistant/components/signal_messenger/notify.py

diff --git a/.coveragerc b/.coveragerc
index e85c97ef80c..b974356e0fe 100644
--- a/.coveragerc
+++ b/.coveragerc
@@ -611,6 +611,8 @@ omit =
     homeassistant/components/shodan/sensor.py
     homeassistant/components/sht31/sensor.py
     homeassistant/components/sigfox/sensor.py
+    homeassistant/components/signal_messenger/__init__.py
+    homeassistant/components/signal_messenger/notify.py
     homeassistant/components/simplepush/notify.py
     homeassistant/components/simplisafe/__init__.py
     homeassistant/components/simplisafe/alarm_control_panel.py
diff --git a/CODEOWNERS b/CODEOWNERS
index 472798f72a6..6723244c089 100644
--- a/CODEOWNERS
+++ b/CODEOWNERS
@@ -281,6 +281,7 @@ homeassistant/components/seventeentrack/* @bachya
 homeassistant/components/shell_command/* @home-assistant/core
 homeassistant/components/shiftr/* @fabaff
 homeassistant/components/shodan/* @fabaff
+homeassistant/components/signal_messenger/* @bbernhard
 homeassistant/components/simplisafe/* @bachya
 homeassistant/components/sinch/* @bendikrb
 homeassistant/components/slide/* @ualex73
diff --git a/homeassistant/components/signal_messenger/__init__.py b/homeassistant/components/signal_messenger/__init__.py
new file mode 100644
index 00000000000..045eb95f1b3
--- /dev/null
+++ b/homeassistant/components/signal_messenger/__init__.py
@@ -0,0 +1 @@
+"""The signalmessenger component."""
diff --git a/homeassistant/components/signal_messenger/manifest.json b/homeassistant/components/signal_messenger/manifest.json
new file mode 100644
index 00000000000..b3494ce8bab
--- /dev/null
+++ b/homeassistant/components/signal_messenger/manifest.json
@@ -0,0 +1,10 @@
+{
+  "domain": "signal_messenger",
+  "name": "signal_messenger",
+  "documentation": "https://www.home-assistant.io/integrations/signal_messenger",
+  "dependencies": [],
+  "codeowners": ["@bbernhard"],
+  "requirements": [
+    "pysignalclirestapi==0.1.4"
+  ]
+}
diff --git a/homeassistant/components/signal_messenger/notify.py b/homeassistant/components/signal_messenger/notify.py
new file mode 100644
index 00000000000..8fbf9c70873
--- /dev/null
+++ b/homeassistant/components/signal_messenger/notify.py
@@ -0,0 +1,71 @@
+"""Signal Messenger for notify component."""
+import logging
+
+from pysignalclirestapi import SignalCliRestApi, SignalCliRestApiError
+import voluptuous as vol
+
+from homeassistant.components.notify import (
+    ATTR_DATA,
+    PLATFORM_SCHEMA,
+    BaseNotificationService,
+)
+import homeassistant.helpers.config_validation as cv
+
+_LOGGER = logging.getLogger(__name__)
+
+CONF_SENDER_NR = "number"
+CONF_RECP_NR = "recipients"
+CONF_SIGNAL_CLI_REST_API = "url"
+ATTR_FILENAME = "attachment"
+
+PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
+    {
+        vol.Required(CONF_SENDER_NR): cv.string,
+        vol.Required(CONF_SIGNAL_CLI_REST_API): cv.string,
+        vol.Required(CONF_RECP_NR): vol.All(cv.ensure_list, [cv.string]),
+    }
+)
+
+
+def get_service(hass, config, discovery_info=None):
+    """Get the SignalMessenger notification service."""
+
+    sender_nr = config[CONF_SENDER_NR]
+    recp_nrs = config[CONF_RECP_NR]
+    signal_cli_rest_api_url = config[CONF_SIGNAL_CLI_REST_API]
+
+    signal_cli_rest_api = SignalCliRestApi(
+        signal_cli_rest_api_url, sender_nr, api_version=1
+    )
+
+    return SignalNotificationService(recp_nrs, signal_cli_rest_api)
+
+
+class SignalNotificationService(BaseNotificationService):
+    """Implement the notification service for SignalMessenger."""
+
+    def __init__(self, recp_nrs, signal_cli_rest_api):
+        """Initialize the service."""
+
+        self._recp_nrs = recp_nrs
+        self._signal_cli_rest_api = signal_cli_rest_api
+
+    def send_message(self, message="", **kwargs):
+        """Send a message to a one or more recipients.
+
+        Additionally a file can be attached.
+        """
+
+        _LOGGER.debug("Sending signal message")
+
+        data = kwargs.get(ATTR_DATA)
+
+        filename = None
+        if data is not None and ATTR_FILENAME in data:
+            filename = data[ATTR_FILENAME]
+
+        try:
+            self._signal_cli_rest_api.send_message(message, self._recp_nrs, filename)
+        except SignalCliRestApiError as ex:
+            _LOGGER.error("%s", ex)
+            raise ex
diff --git a/requirements_all.txt b/requirements_all.txt
index 87ca2a46177..e5983972243 100644
--- a/requirements_all.txt
+++ b/requirements_all.txt
@@ -1482,6 +1482,9 @@ pysesame2==1.0.1
 # homeassistant.components.goalfeed
 pysher==1.0.1
 
+# homeassistant.components.signal_messenger
+pysignalclirestapi==0.1.4
+
 # homeassistant.components.sma
 pysma==0.3.4
 
-- 
GitLab