def _match_view_func(self): view_func = None intent_actions = self._intent_action_funcs.get(self.intent, []) if len(intent_actions) == 0: logger.critical("No action funcs defined for intent: {}".format( self.intent)) return view_func if self.has_live_context(): view_func = self._choose_context_view() if not view_func and self._missing_params: prompts = self._intent_prompts.get(self.intent) if prompts: param_choice = self._missing_params.pop() view_func = prompts.get(param_choice) logger.debug( "Matching prompt func {} for missing param {}".format( view_func.__name__, param_choice)) if not view_func and len(intent_actions) == 1: view_func = self._intent_action_funcs[self.intent][0] # TODO: Do not match func if context not satisfied if not view_func and len(intent_actions) > 1: view_func = intent_actions[0] msg = "Multiple actions defined but no context was applied, will use first action func" logger.warning(msg) return view_func
def _map_arg_from_context(self, arg_name): for context_obj in self.context_in: if arg_name in context_obj["parameters"]: logger.debug( "Retrieved {} param value from {} context".format( arg_name, context_obj["name"] ) ) return context_obj["parameters"][arg_name]
def _context_views(self): """Returns view functions for which the context requirements are met""" possible_views = [] for func in self._func_contexts: if self._context_satified(func): logger.debug("{} context conditions satisified".format(func.__name__)) possible_views.append(func) return possible_views
def _flask_assitant_view_func(self, nlp_result=None, *args, **kwargs): if nlp_result: # pass API query result directly self.request = nlp_result else: # called as webhook self.request = self._dialogflow_request(verify=False) logger.debug(json.dumps(self.request, indent=2)) try: self.intent = self.request["queryResult"]["intent"]["displayName"] self.context_in = self.request["queryResult"].get( "outputContexts", []) self.session_id = self._parse_session_id() assert self.session_id is not None except KeyError: raise DeprecationWarning( """It appears your agent is still using the Dialogflow V1 API, please update to V2 in the Dialogflow console.""") # update context_manager's assist reference # TODO: acces context_manager from assist, instead of own object self.context_manager._assist = self original_request = self.request.get("originalDetectIntentRequest") if original_request: payload = original_request.get("payload") if payload and payload.get("user"): self.user = original_request["payload"]["user"] self._set_user_profile() # Get access token from request if original_request and original_request.get("user"): self.access_token = original_request["user"].get("accessToken") self._update_contexts() self._dump_request() view_func = self._match_view_func() if view_func is None: logger.error("Failed to match an action function") return "", 400 logger.info("Matched action function: {}".format(view_func.__name__)) result = self._map_intent_to_view_func(view_func)() if result is not None: if isinstance(result, _Response): self._dump_result(view_func, result) resp = result.render_response() return resp return result logger.error("Action func returned empty response") return "", 400
def _integrate_with_df_messenger(self, speech=None, display_text=None): logger.debug("Integrating with dialogflow messenger") content = {"richContent": [[]]} for m in self._platform_messages.get("DIALOGFLOW_MESSENGER", []): content["richContent"][0].append(m) payload = {"payload": content} self._messages.append(payload)
def render_response(self): self._include_contexts() if self._render_func: self._render_func() self._integrate_with_df_messenger() self._integrate_with_hangouts(self._speech, self._display_text) logger.debug(json.dumps(self._response, indent=2)) resp = make_response(json.dumps(self._response)) resp.headers["Content-Type"] = "application/json" return resp
def _choose_context_view(self): choice = None for view in self._context_views: if view in self._intent_action_funcs[self.intent]: logger.debug("Matched {} based on active contexts".format( view.__name__)) choice = view if choice: return choice else: active_contexts = [c.name for c in self.context_manager.active] intent_actions = [ f.__name__ for f in self._intent_action_funcs[self.intent] ] msg = "No {} action func matched based on active contexts" logger.debug(msg)
def _dbgdump(obj, indent=2, default=None, cls=None): msg = json.dumps(obj, indent=indent, default=default, cls=cls) logger.debug(msg)