homeassistant-ntfy/notify.py

121 lines
4.1 KiB
Python

"""ntfy platform for notify component."""
import logging
from http import HTTPStatus
import homeassistant.helpers.config_validation as cv
import requests
import voluptuous as vol
from homeassistant.components.notify import (ATTR_TARGET, ATTR_TITLE,
PLATFORM_SCHEMA,
BaseNotificationService)
from homeassistant.const import (CONF_NAME, CONF_PASSWORD, CONF_URL,
CONF_USERNAME, CONF_VERIFY_SSL,
HTTP_BASIC_AUTHENTICATION)
from .const import DEFAULT_NAME, DEFAULT_VERIFY_SSL, ATTR_DEFAULT_TOPIC
from homeassistant.helpers.template import Template
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
{
vol.Required(CONF_URL): cv.url,
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
vol.Optional(CONF_PASSWORD): cv.string,
vol.Optional(CONF_USERNAME): cv.string,
vol.Optional(CONF_VERIFY_SSL, default=DEFAULT_VERIFY_SSL): cv.boolean,
}
)
_LOGGER = logging.getLogger(__name__)
async def async_get_service(hass, config, discovery_info=None):
"""Get the ntfy notification service."""
ntfy_url = config.get(CONF_URL)
username = config.get(CONF_USERNAME)
password = config.get(CONF_PASSWORD)
verify_ssl = config.get(CONF_VERIFY_SSL)
if username and password:
auth = requests.auth.HTTPBasicAuth(username, password)
else:
auth = None
return NtfyNotificationService(
hass,
ntfy_url,
auth,
verify_ssl,
)
class NtfyNotificationService(BaseNotificationService):
"""Implementation of a notification service for ntfy."""
def __init__(
self,
hass,
ntfy_url,
auth,
verify_ssl,
):
"""Initialize the service."""
self._ntfy_url = ntfy_url
self._hass = hass
self._auth = auth
self._verify_ssl = verify_ssl
def send_message(self, message="", **kwargs):
"""Send a message to a topic."""
data = {"message": message}
# Target is a list as of 0.29 and we don't want to break existing
# integrations, so just return the first target in the list.
data["topic"] = kwargs.get(ATTR_TARGET, [ATTR_DEFAULT_TOPIC])[0]
if ATTR_TITLE in kwargs:
data["title"] = kwargs[ATTR_TITLE]
if "data" in kwargs:
if "tags" in kwargs["data"]:
data["tags"] = list(kwargs["data"]["tags"])
if "priority" in kwargs["data"]:
prio = int(kwargs["data"]["priority"])
if not prio in range(1, 6):
raise ValueError("priority must be between 1-5")
data["priority"] = prio
if "actions" in kwargs["data"]:
data["actions"] = list(kwargs["data"]["actions"])
for attr in ["click", "attach", "filename", "delay", "email"]:
if attr in kwargs["data"]:
data[attr] = str(kwargs["data"][attr])
response = requests.post(
self._ntfy_url,
json=data,
timeout=10,
auth=self._auth,
verify=self._verify_ssl,
)
if (
response.status_code >= HTTPStatus.INTERNAL_SERVER_ERROR
and response.status_code < 600
):
_LOGGER.exception(
"Server error. Response %d: %s:", response.status_code, response.reason
)
elif (
response.status_code >= HTTPStatus.BAD_REQUEST
and response.status_code < HTTPStatus.INTERNAL_SERVER_ERROR
):
_LOGGER.exception(
"Client error. Response %d: %s:", response.status_code, response.reason
)
elif (
response.status_code >= HTTPStatus.OK
and response.status_code < HTTPStatus.MULTIPLE_CHOICES
):
_LOGGER.debug(
"Success. Response %d: %s:", response.status_code, response.reason
)
else:
_LOGGER.debug("Response %d: %s:", response.status_code, response.reason)