Exemple #1
0
    def handle_message(self, message, bot_service):
        """
        Process incoming message generating a response to the sender.
        
        :param message: Generic message received from provider
        :param bot_service: Service Integration
        :type bot_service: IntegrationBot :class:`IntegrationBot <permabots.models.bot.IntegrationBot>`

        .. note:: Message content will be extracted by IntegrationBot
        """
        urlpatterns = []
        state_context = {}
        chat_state = bot_service.get_chat_state(message)
        for handler in caching.get_or_set_related(self, 'handlers', 'response',
                                                  'request', 'target_state'):
            if handler.enabled:
                source_states = caching.get_or_set_related(
                    handler, 'source_states')
                if chat_state:
                    state_context = chat_state.ctx
                if not source_states or (chat_state and chat_state.state
                                         in source_states):
                    urlpatterns.append(handler.urlpattern())

        resolver = RegexURLResolver(r'^', urlpatterns)
        try:
            resolver_match = resolver.resolve(
                bot_service.message_text(message))
        except Resolver404:
            logger.warning("Handler not found for %s" % message)
        else:
            callback, callback_args, callback_kwargs = resolver_match
            logger.debug("Calling callback:%s for message %s with %s" %
                         (callback, message, callback_kwargs))
            text, keyboard, target_state, context = callback(
                self,
                message=message,
                service=bot_service.identity,
                state_context=state_context,
                **callback_kwargs)
            if target_state:
                self.update_chat_state(bot_service, message, chat_state,
                                       target_state, context)
            keyboard = bot_service.build_keyboard(keyboard)
            bot_service.send_message(bot_service.get_chat_id(message), text,
                                     keyboard, message)
Exemple #2
0
    def handle_message(self, message, bot_service):
        """
        Process incoming message generating a response to the sender.
        
        :param message: Generic message received from provider
        :param bot_service: Service Integration
        :type bot_service: IntegrationBot :class:`IntegrationBot <permabots.models.bot.IntegrationBot>`

        .. note:: Message content will be extracted by IntegrationBot
        """
        urlpatterns = []
        state_context = {}
        chat_state = bot_service.get_chat_state(message)
        for handler in caching.get_or_set_related(self, 'handlers', 'response', 'request', 'target_state'):
            if handler.enabled:
                source_states = caching.get_or_set_related(handler, 'source_states')
                if chat_state:
                    state_context = chat_state.ctx
                if not source_states or (chat_state and chat_state.state in source_states):
                        urlpatterns.append(handler.urlpattern())
                    
        resolver = RegexURLResolver(r'^', urlpatterns)
        try:
            resolver_match = resolver.resolve(bot_service.message_text(message))
        except Resolver404:
            logger.warning("Handler not found for %s" % message)
        else:
            callback, callback_args, callback_kwargs = resolver_match
            logger.debug("Calling callback:%s for message %s with %s" % 
                         (callback, message, callback_kwargs))
            text, keyboard, target_state, context = callback(self, message=message, service=bot_service.identity, 
                                                             state_context=state_context, **callback_kwargs)
            if target_state:
                self.update_chat_state(bot_service, message, chat_state, target_state, context)
            keyboard = bot_service.build_keyboard(keyboard)
            bot_service.send_message(bot_service.get_chat_id(message), text, keyboard, message)
Exemple #3
0
 def process(self, bot, message, service, state_context, **pattern_context):
     """
     Process conversation message.
     
     1. Generates context
         * service: name of integration service
         * state_context: historic dict of previous contexts. identified by state
         * pattern: url pattern dict
         * env: dict of environment variables associated to this bot
         * message: provider message
         * emoji: dict of emojis  use named notation with underscores `<http://apps.timwhitlock.info/emoji/tables/unicode>` _.
         
     2. Process request (if required)
     
     3. Generates response. Text and Keyboard
     
     4. Prepare target_state and context for updating chat&state info
     
     :param bot: Bot the handler belongs to
     :type Bot: :class:`Bot <permabots.models.bot.Bot>`
     :param message: Message from provider
     :param service: Identity integration
     :type service: string
     :param state_context: Previous contexts
     :type state_context: dict
     :param pattern_context: Dict variables obtained from handler pattern regular expression.
     :type pattern_context: dict
     :returns: Text and keyboard response, new state for the chat and context used.
     """
     env = {}
     for env_var in caching.get_or_set_related(bot, 'env_vars'):
         env.update(env_var.as_json())
     context = {
         'service': service,
         'state_context': state_context,
         'pattern': pattern_context,
         'env': env,
         'message': message.to_dict(),
         'emoji': self._create_emoji_context()
     }
     response_context = {}
     success = True
     if self.request:
         r = self.request.process(**context)
         logger.debug("Handler %s get request %s" % (self, r))
         success = is_success(r.status_code)
         response_context['status'] = r.status_code
         try:
             response_context['data'] = r.json()
         except:
             response_context['data'] = {}
     context['response'] = response_context
     response_text, response_keyboard = self.response.process(**context)
     # update ChatState
     if self.target_state and success:
         context.pop('message', None)
         context.pop('env', None)
         context.pop('state_context', None)
         context.pop('service', None)
         context.pop('emoji', None)
         target_state = self.target_state
     else:
         target_state = None
         logger.warning("No target state for handler:%s for message %s" %
                        (self, message))
     return response_text, response_keyboard, target_state, context
Exemple #4
0
 def process(self, bot, message, service, state_context, **pattern_context):
     """
     Process conversation message.
     
     1. Generates context
         * service: name of integration service
         * state_context: historic dict of previous contexts. identified by state
         * pattern: url pattern dict
         * env: dict of environment variables associated to this bot
         * message: provider message
         * emoji: dict of emojis  use named notation with underscores `<http://apps.timwhitlock.info/emoji/tables/unicode>` _.
         
     2. Process request (if required)
     
     3. Generates response. Text and Keyboard
     
     4. Prepare target_state and context for updating chat&state info
     
     :param bot: Bot the handler belongs to
     :type Bot: :class:`Bot <permabots.models.bot.Bot>`
     :param message: Message from provider
     :param service: Identity integration
     :type service: string
     :param state_context: Previous contexts
     :type state_context: dict
     :param pattern_context: Dict variables obtained from handler pattern regular expression.
     :type pattern_context: dict
     :returns: Text and keyboard response, new state for the chat and context used.
     """
     env = {}
     for env_var in caching.get_or_set_related(bot, 'env_vars'):
         env.update(env_var.as_json())
     context = {'service': service,
                'state_context': state_context,
                'pattern': pattern_context,
                'env': env,
                'message': message.to_dict(),
                'emoji': self._create_emoji_context()}
     response_context = {}
     success = True
     if self.request:
         r = self.request.process(**context)
         logger.debug("Handler %s get request %s" % (self, r))        
         success = is_success(r.status_code)
         response_context['status'] = r.status_code
         try:
             response_context['data'] = r.json()
         except:
             response_context['data'] = {}
     context['response'] = response_context
     response_text, response_keyboard = self.response.process(**context)
     # update ChatState
     if self.target_state and success:
         context.pop('message', None)
         context.pop('env', None)
         context.pop('state_context', None)
         context.pop('service', None)
         context.pop('emoji', None)
         target_state = self.target_state
     else:
         target_state = None
         logger.warning("No target state for handler:%s for message %s" % 
                        (self, message))
     return response_text, response_keyboard, target_state, context