text: """Support for Dialogflow webhook."""
  import logging
  
  import voluptuous as vol
  from aiohttp import web
  
  from homeassistant.const import CONF_WEBHOOK_ID
  from homeassistant.exceptions import HomeAssistantError
  from homeassistant.helpers import intent, template, config_entry_flow
  
  from .const import DOMAIN
  
  
  _LOGGER = logging.getLogger(__name__)
  
  SOURCE = "Home Assistant Dialogflow"
  
  CONFIG_SCHEMA = vol.Schema({
      DOMAIN: {}
  }, extra=vol.ALLOW_EXTRA)
  
  
  class DialogFlowError(HomeAssistantError):
      """Raised when a DialogFlow error happens."""
  
  
  async def async_setup(hass, config):
      """Set up the Dialogflow component."""
      return True
  
  
  async def handle_webhook(hass, webhook_id, request):
      """Handle incoming webhook with Dialogflow requests."""
      message = await request.json()
  
      _LOGGER.debug("Received Dialogflow request: %s", message)
  
      try:
          response = await async_handle_message(hass, message)
          return b'' if response is None else web.json_response(response)
  
      except DialogFlowError as err:
          _LOGGER.warning(str(err))
          return web.json_response(dialogflow_error_response(message, str(err)))
  
      except intent.UnknownIntent as err:
          _LOGGER.warning(str(err))
          return web.json_response(
              dialogflow_error_response(
                  message,
                  "This intent is not yet configured within Home Assistant."
              )
          )
  
      except intent.InvalidSlotInfo as err:
          _LOGGER.warning(str(err))
          return web.json_response(
              dialogflow_error_response(
                  message,
                  "Invalid slot information received for this intent."
              )
          )
  
      except intent.IntentError as err:
          _LOGGER.warning(str(err))
          return web.json_response(
              dialogflow_error_response(message, "Error handling intent."))
  
  
  async def async_setup_entry(hass, entry):
      """Configure based on config entry."""
      hass.components.webhook.async_register(
          DOMAIN, 'DialogFlow', entry.data[CONF_WEBHOOK_ID], handle_webhook)
      return True
  
  
  async def async_unload_entry(hass, entry):
      """Unload a config entry."""
      hass.components.webhook.async_unregister(entry.data[CONF_WEBHOOK_ID])
      return True
  
  
  # pylint: disable=invalid-name
  async_remove_entry = config_entry_flow.webhook_async_remove_entry
  
  
  def dialogflow_error_response(message, error):
      """Return a response saying the error message."""
      dialogflow_response = DialogflowResponse(message['result']['parameters'])
      dialogflow_response.add_speech(error)
      return dialogflow_response.as_dict()
  
  
  async def async_handle_message(hass, message):
      """Handle a DialogFlow message."""
      req = message.get('result')
      action_incomplete = req['actionIncomplete']
  
      if action_incomplete:
          return None
  
      action = req.get('action', '')
      parameters = req.get('parameters').copy()
      parameters["dialogflow_query"] = message
      dialogflow_response = DialogflowResponse(parameters)
  
      if action == "":
          raise DialogFlowError(
              "You have not defined an action in your Dialogflow intent.")
  
      intent_response = await intent.async_handle(
          hass, DOMAIN, action,
          {key: {'value': value} for key, value
           in parameters.items()})
  
      if 'plain' in intent_response.speech:
          dialogflow_response.add_speech(
              intent_response.speech['plain']['speech'])
  
      return dialogflow_response.as_dict()
  
  
  class DialogflowResponse:
      """Help generating the response for Dialogflow."""
  
      def __init__(self, parameters):
          """Initialize the Dialogflow response."""
          self.speech = None
          self.parameters = {}
          # Parameter names replace '.' and '-' for '_'
          for key, value in parameters.items():
              underscored_key = key.replace('.', '_').replace('-', '_')
              self.parameters[underscored_key] = value
  
      def add_speech(self, text):
          """Add speech to the response."""
          assert self.speech is None
  
          if isinstance(text, template.Template):
              text = text.async_render(self.parameters)
  
          self.speech = text
  
      def as_dict(self):
          """Return response in a Dialogflow valid dictionary."""
          return {
              'speech': self.speech,
              'displayText': self.speech,
              'source': SOURCE,
          }
  