1 """Support for Dialogflow webhook."""
5 from aiohttp
import web
6 import voluptuous
as vol
15 from .const
import DOMAIN
17 _LOGGER = logging.getLogger(__name__)
19 SOURCE =
"Home Assistant Dialogflow"
21 CONFIG_SCHEMA = vol.Schema({DOMAIN: {}}, extra=vol.ALLOW_EXTRA)
28 """Raised when a DialogFlow error happens."""
32 hass: HomeAssistant, webhook_id: str, request: web.Request
33 ) -> web.Response |
None:
34 """Handle incoming webhook with Dialogflow requests."""
35 message = await request.json()
37 _LOGGER.debug(
"Received Dialogflow request: %s", message)
41 return None if response
is None else web.json_response(response)
43 except DialogFlowError
as err:
44 _LOGGER.warning(
str(err))
47 except intent.UnknownIntent
as err:
48 _LOGGER.warning(
str(err))
49 return web.json_response(
51 message,
"This intent is not yet configured within Home Assistant."
55 except intent.InvalidSlotInfo
as err:
56 _LOGGER.warning(
str(err))
57 return web.json_response(
59 message,
"Invalid slot information received for this intent."
63 except intent.IntentError
as err:
64 _LOGGER.warning(
str(err))
65 return web.json_response(
71 """Configure based on config entry."""
72 webhook.async_register(
73 hass, DOMAIN,
"DialogFlow", entry.data[CONF_WEBHOOK_ID], handle_webhook
79 """Unload a config entry."""
80 webhook.async_unregister(hass, entry.data[CONF_WEBHOOK_ID])
84 async_remove_entry = config_entry_flow.webhook_async_remove_entry
88 """Return a response saying the error message."""
91 parameters = message[
"result"][
"parameters"]
92 elif api_version
is V2:
93 parameters = message[
"queryResult"][
"parameters"]
95 dialogflow_response.add_speech(error)
96 return dialogflow_response.as_dict()
100 """Get API version of Dialogflow message."""
101 if message.get(
"id")
is not None:
103 if message.get(
"responseId")
is not None:
106 raise ValueError(f
"Unable to extract API version from message: {message}")
110 """Handle a DialogFlow message."""
112 if _api_version
is V1:
114 "Dialogflow V1 API will be removed on October 23, 2019. Please change your"
115 " DialogFlow settings to use the V2 api"
117 req = message.get(
"result")
118 if req.get(
"actionIncomplete",
True):
121 elif _api_version
is V2:
122 req = message.get(
"queryResult")
123 if req.get(
"allRequiredParamsPresent",
False)
is False:
126 action = req.get(
"action",
"")
127 parameters = req.get(
"parameters").copy()
128 parameters[
"dialogflow_query"] = message
133 "You have not defined an action in your Dialogflow intent."
136 intent_response = await intent.async_handle(
140 {key: {
"value": value}
for key, value
in parameters.items()},
143 if "plain" in intent_response.speech:
144 dialogflow_response.add_speech(intent_response.speech[
"plain"][
"speech"])
146 return dialogflow_response.as_dict()
150 """Help generating the response for Dialogflow."""
153 """Initialize the Dialogflow response."""
158 for key, value
in parameters.items():
159 underscored_key = key.replace(
".",
"_").replace(
"-",
"_")
160 self.
parametersparameters[underscored_key] = value
163 """Add speech to the response."""
164 assert self.
speechspeech
is None
166 if isinstance(text, template.Template):
167 text = text.async_render(self.
parametersparameters, parse_result=
False)
172 """Return response in a Dialogflow valid dictionary."""
174 return {
"speech": self.
speechspeech,
"displayText": self.
speechspeech,
"source": SOURCE}
177 return {
"fulfillmentText": self.
speechspeech,
"source": SOURCE}
179 raise ValueError(f
"Invalid API version: {self.api_version}")
def __init__(self, parameters, api_version)
def add_speech(self, text)
bool async_unload_entry(HomeAssistant hass, ConfigEntry entry)
bool async_setup_entry(HomeAssistant hass, ConfigEntry entry)
def dialogflow_error_response(message, error)
def get_api_version(message)
def async_handle_message(hass, message)
web.Response|None handle_webhook(HomeAssistant hass, str webhook_id, web.Request request)