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)
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)
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
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