Home Assistant Unofficial Reference 2024.12.1
__init__.py
Go to the documentation of this file.
1 """Support to trigger Maker IFTTT recipes."""
2 
3 from __future__ import annotations
4 
5 from http import HTTPStatus
6 import json
7 import logging
8 
9 from aiohttp import web
10 import pyfttt
11 import requests
12 import voluptuous as vol
13 
14 from homeassistant.components import webhook
15 from homeassistant.config_entries import ConfigEntry
16 from homeassistant.const import CONF_WEBHOOK_ID
17 from homeassistant.core import HomeAssistant, ServiceCall
18 from homeassistant.helpers import config_entry_flow
20 from homeassistant.helpers.typing import ConfigType
21 
22 from .const import DOMAIN
23 
24 _LOGGER = logging.getLogger(__name__)
25 
26 EVENT_RECEIVED = "ifttt_webhook_received"
27 
28 ATTR_EVENT = "event"
29 ATTR_TARGET = "target"
30 ATTR_VALUE1 = "value1"
31 ATTR_VALUE2 = "value2"
32 ATTR_VALUE3 = "value3"
33 
34 CONF_KEY = "key"
35 
36 SERVICE_PUSH_ALARM_STATE = "push_alarm_state"
37 SERVICE_TRIGGER = "trigger"
38 
39 SERVICE_TRIGGER_SCHEMA = vol.Schema(
40  {
41  vol.Required(ATTR_EVENT): cv.string,
42  vol.Optional(ATTR_TARGET): vol.All(cv.ensure_list, [cv.string]),
43  vol.Optional(ATTR_VALUE1): cv.string,
44  vol.Optional(ATTR_VALUE2): cv.string,
45  vol.Optional(ATTR_VALUE3): cv.string,
46  }
47 )
48 
49 CONFIG_SCHEMA = vol.Schema(
50  {
51  vol.Optional(DOMAIN): vol.Schema(
52  {vol.Required(CONF_KEY): vol.Any({cv.string: cv.string}, cv.string)}
53  )
54  },
55  extra=vol.ALLOW_EXTRA,
56 )
57 
58 
59 async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
60  """Set up the IFTTT service component."""
61  if DOMAIN not in config:
62  return True
63 
64  api_keys = config[DOMAIN][CONF_KEY]
65  if isinstance(api_keys, str):
66  api_keys = {"default": api_keys}
67 
68  def trigger_service(call: ServiceCall) -> None:
69  """Handle IFTTT trigger service calls."""
70  event = call.data[ATTR_EVENT]
71  targets = call.data.get(ATTR_TARGET, list(api_keys))
72  value1 = call.data.get(ATTR_VALUE1)
73  value2 = call.data.get(ATTR_VALUE2)
74  value3 = call.data.get(ATTR_VALUE3)
75 
76  target_keys = {}
77  for target in targets:
78  if target not in api_keys:
79  _LOGGER.error("No IFTTT api key for %s", target)
80  continue
81  target_keys[target] = api_keys[target]
82 
83  try:
84  for target, key in target_keys.items():
85  res = pyfttt.send_event(key, event, value1, value2, value3)
86  if res.status_code != HTTPStatus.OK:
87  _LOGGER.error("IFTTT reported error sending event to %s", target)
88  except requests.exceptions.RequestException:
89  _LOGGER.exception("Error communicating with IFTTT")
90 
91  hass.services.async_register(
92  DOMAIN, SERVICE_TRIGGER, trigger_service, schema=SERVICE_TRIGGER_SCHEMA
93  )
94 
95  return True
96 
97 
98 async def handle_webhook(
99  hass: HomeAssistant, webhook_id: str, request: web.Request
100 ) -> None:
101  """Handle webhook callback."""
102  body = await request.text()
103  try:
104  data = json.loads(body) if body else {}
105  except ValueError:
106  _LOGGER.error(
107  "Received invalid data from IFTTT. Data needs to be formatted as JSON: %s",
108  body,
109  )
110  return
111 
112  if not isinstance(data, dict):
113  _LOGGER.error(
114  "Received invalid data from IFTTT. Data needs to be a dictionary: %s", data
115  )
116  return
117 
118  data["webhook_id"] = webhook_id
119  hass.bus.async_fire(EVENT_RECEIVED, data)
120 
121 
122 async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
123  """Configure based on config entry."""
124  webhook.async_register(
125  hass, DOMAIN, "IFTTT", entry.data[CONF_WEBHOOK_ID], handle_webhook
126  )
127  return True
128 
129 
130 async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
131  """Unload a config entry."""
132  webhook.async_unregister(hass, entry.data[CONF_WEBHOOK_ID])
133  return True
134 
135 
136 async_remove_entry = config_entry_flow.webhook_async_remove_entry
bool async_unload_entry(HomeAssistant hass, ConfigEntry entry)
Definition: __init__.py:130
None handle_webhook(HomeAssistant hass, str webhook_id, web.Request request)
Definition: __init__.py:100
bool async_setup(HomeAssistant hass, ConfigType config)
Definition: __init__.py:59
bool async_setup_entry(HomeAssistant hass, ConfigEntry entry)
Definition: __init__.py:122