def __init__(self,
              training_data_path,
              basic_intents_csv,
              intent_confidence_thresh=.25):
     self.response_builder = ResponseBuilder(training_data_path)
     self.basic_responder = BasicResponder(basic_intents_csv)
     self.intent_guesser = IntentGuesser(training_data_path)
     self.intent_thresh = intent_confidence_thresh
     self.conversation_context = {}
     self.watson = watson.ConversationAPI(
         watson.rohan_graduate_affairs_config())
 def exec_main_proc(self):
     yahoo = YahooUtil(client_id=os.environ['YAHOO_CLIENT_ID'],
                       secret=os.environ['YAHOO_SECRET'],
                       callback_url=os.environ['YAHOO_OAUTH_CALLBACK_URL'])
     try:
         authentication_url = yahoo.get_authorization_url(
             dynamodb=self.dynamodb)
     except (ClientError, YahooOauthError) as e:
         logging.info(self.event)
         logging.fatal(e)
         traceback.print_exc()
         return ResponseBuilder.response(
             status_code=500, body={'message': 'Internal server error'})
     return ResponseBuilder.response(status_code=200,
                                     body={'url': authentication_url})
 def exec_main_proc(self):
     twitter = TwitterUtil(
         consumer_key=os.environ['TWITTER_CONSUMER_KEY'],
         consumer_secret=os.environ['TWITTER_CONSUMER_SECRET'])
     try:
         authentication_url = twitter.generate_auth_url(
             callback_url=os.environ['TWITTER_OAUTH_CALLBACK_URL'])
     except TwitterOauthError as e:
         logging.info(self.event)
         logging.fatal(e)
         traceback.print_exc()
         return ResponseBuilder.response(
             status_code=500, body={'message': 'Internal server error'})
     return ResponseBuilder.response(status_code=200,
                                     body={'url': authentication_url})
Example #4
0
    def run(self, dispatcher, tracker, domain):
        location = tracker.get_slot('location')
        cuisine = tracker.get_slot('cuisine')
        budget = tracker.get_slot('budget')

        zomatoService = ZomatoService()
        city_id = zomatoService.get_city_id(location)
        responseBuilder = ResponseBuilder()
        response = responseBuilder.build_response(city_id, budget, cuisine)

        return_slots = []

        if response == 'No results found':
            response = "Sorry, we could not find any matching restaurants."
            return_slots.append(SlotSet('restaurant_found', False))
            return_slots.append(SlotSet('search_result', response))
        else:
            return_slots.append(SlotSet('restaurant_found', True))
            return_slots.append(SlotSet('search_result', response))

        dispatcher.utter_message(response)
        return return_slots
 def exec_main_proc(self):
     facebook = FacebookUtil(
        app_id=os.environ['FACEBOOK_APP_ID'],
        app_secret=os.environ['FACEBOOK_APP_SECRET'],
        callback_url=os.environ['FACEBOOK_OAUTH_CALLBACK_URL'],
        app_token=os.environ['FACEBOOK_APP_TOKEN']
     )
     try:
         authentication_url = facebook.get_authorization_url(
           dynamodb=self.dynamodb
         )
     except (ClientError) as e:
         logging.info(self.event)
         logging.fatal(e)
         traceback.print_exc()
         return ResponseBuilder.response(
             status_code=500,
             body={'message': 'Internal server error'}
         )
     return ResponseBuilder.response(
        status_code=200,
        body={'url': authentication_url}
     )
Example #6
0
from rasa_core_sdk import Action
from rasa_core_sdk.events import SlotSet
from response_builder import ResponseBuilder
import json

response_builder = ResponseBuilder()


class DisplayGeneralQuery(Action):
    def name(self):

        return "action_give_project_information"

    def run(self, dispatcher, tracker, domain):
        if tracker.get_slot('project'):
            response_builder.get_query(dispatcher, tracker)
        else:
            response = dict()
            response[
                'error'] = "no project slot is filled inside action give project information action"
            dispatcher.utter_custom_message(response)

        return []


class DisplayBundleDetailedQuery(Action):
    def name(self):

        return "action_show_detail_info_bundles"

    def run(self, dispatcher, tracker, domain):
Example #7
0
    def exec_main_proc(self):
        body = json.loads(self.event.get('body'))
        code = body['code']
        client_id = os.environ['LINE_CHANNEL_ID']
        client_secret = os.environ['LINE_CHANNEL_SECRET']

        try:
            # JWTの取得
            got_jwt = self.__get_line_jwt(code, client_id, client_secret,
                                          settings.LINE_REQUEST_HEADER)

        except LineOauthError as e:
            logging.info(self.event)
            logging.fatal(e)
            traceback.print_exc()
            return ResponseBuilder.response(
                status_code=e.status_code,
                body={'message': json.loads(e.message)})
        # JWTのデコード
        decoded_id_token = self.__decode_jwt(got_jwt, client_secret, client_id)

        user_id = settings.LINE_USERNAME_PREFIX + decoded_id_token['sub']

        if UserUtil.exists_user(self.dynamodb, user_id):
            try:
                external_provider_users = self.dynamodb.Table(
                    os.environ['EXTERNAL_PROVIDER_USERS_TABLE_NAME'])
                external_provider_user = external_provider_users.get_item(
                    Key={
                        'external_provider_user_id': user_id
                    }).get('Item')
                hash_data = external_provider_user['password']
                byte_hash_data = hash_data.encode()
                decoded_iv = external_provider_user['iv']
                iv = decoded_iv.encode()
                password = CryptoUtil.decrypt_password(byte_hash_data, iv)

                has_user_id = UserUtil.has_user_id(self.dynamodb, user_id)
                if external_provider_user is not None and 'user_id' in external_provider_user:
                    user_id = external_provider_user['user_id']

                response = UserUtil.external_provider_login(
                    cognito=self.cognito,
                    user_pool_id=os.environ['COGNITO_USER_POOL_ID'],
                    user_pool_app_id=os.environ['COGNITO_USER_POOL_APP_ID'],
                    user_id=user_id,
                    password=password,
                    provider=os.environ['EXTERNAL_PROVIDER_LOGIN_MARK'])

                return ResponseBuilder.response(
                    status_code=200,
                    body={
                        'access_token':
                        response['AuthenticationResult']['AccessToken'],
                        'id_token':
                        response['AuthenticationResult']['IdToken'],
                        'refresh_token':
                        response['AuthenticationResult']['RefreshToken'],
                        'last_auth_user':
                        user_id,
                        'has_user_id':
                        has_user_id,
                        'status':
                        'login'
                    })

            except ClientError as e:
                logging.info(self.event)
                logging.fatal(e)
                traceback.print_exc()
                return ResponseBuilder.response(
                    status_code=500, body={'message': 'Internal server error'})
        else:
            try:
                if 'email' not in decoded_id_token:
                    return ResponseBuilder.response(
                        status_code=400, body={'message': 'NotRegistered'})
                if not decoded_id_token['email']:
                    email = user_id + '@' + settings.FAKE_USER_EMAIL_DOMAIN
                else:
                    email = decoded_id_token['email']
                backed_temp_password = os.environ[
                    'EXTERNAL_PROVIDER_LOGIN_COMMON_TEMP_PASSWORD']
                backed_password = UserUtil.generate_password()
                response = UserUtil.create_external_provider_user(
                    cognito=self.cognito,
                    user_pool_id=os.environ['COGNITO_USER_POOL_ID'],
                    user_pool_app_id=os.environ['COGNITO_USER_POOL_APP_ID'],
                    user_id=user_id,
                    email=email,
                    backed_temp_password=backed_temp_password,
                    backed_password=backed_password,
                    provider=os.environ['EXTERNAL_PROVIDER_LOGIN_MARK'])

                aes_iv = os.urandom(settings.AES_IV_BYTES)
                encrypted_password = CryptoUtil.encrypt_password(
                    backed_password, aes_iv)
                iv = base64.b64encode(aes_iv).decode()

                UserUtil.add_external_provider_user_info(
                    dynamodb=self.dynamodb,
                    external_provider_user_id=user_id,
                    password=encrypted_password,
                    iv=iv,
                    email=email)
                return ResponseBuilder.response(
                    status_code=200,
                    body={
                        'access_token':
                        response['AuthenticationResult']['AccessToken'],
                        'id_token':
                        response['AuthenticationResult']['IdToken'],
                        'refresh_token':
                        response['AuthenticationResult']['RefreshToken'],
                        'last_auth_user':
                        user_id,
                        'has_user_id':
                        False,
                        'status':
                        'sign_up'
                    })
            except ClientError as e:
                logging.info(self.event)
                logging.fatal(e)
                traceback.print_exc()
                if e.response['Error']['Code'] == 'UsernameExistsException':
                    return ResponseBuilder.response(
                        status_code=400,
                        body={'message': 'EmailExistsException'})
                return ResponseBuilder.response(
                    status_code=500, body={'message': 'Internal server error'})
Example #8
0
    def exec_main_proc(self):
        yahoo = YahooUtil(client_id=os.environ['YAHOO_CLIENT_ID'],
                          secret=os.environ['YAHOO_SECRET'],
                          callback_url=os.environ['YAHOO_OAUTH_CALLBACK_URL'])
        try:
            yahoo.verify_state_nonce(dynamodb=self.dynamodb,
                                     state=self.params['state'])

            token = yahoo.get_access_token(code=self.params['code'])

            yahoo.verify_access_token(dynamodb=self.dynamodb,
                                      access_token=token['access_token'],
                                      id_token=token['id_token'])

            user_info = yahoo.get_user_info(access_token=token['access_token'])
        except YahooOauthError as e:
            if e.status_code == 401:
                message = json.loads(e.message)
                return ResponseBuilder.response(
                    status_code=401,
                    body={'message': message['error_description']})
            logging.info(self.event)
            logging.fatal(e)
            traceback.print_exc()
            return ResponseBuilder.response(
                status_code=500, body={'message': 'Internal server error'})

        except (jwt.ExpiredSignatureError, jwt.InvalidTokenError, ClientError,
                YahooVerifyException) as e:
            logging.info(self.event)
            logging.fatal(e)
            traceback.print_exc()
            return ResponseBuilder.response(
                status_code=500, body={'message': 'Internal server error'})

        if UserUtil.exists_user(self.dynamodb, user_info['user_id']):
            try:
                has_user_id = UserUtil.has_user_id(
                    dynamodb=self.dynamodb,
                    external_provider_user_id=user_info['user_id'],
                )
                if has_user_id is True:
                    user_id = UserUtil.get_user_id(
                        dynamodb=self.dynamodb,
                        external_provider_user_id=user_info['user_id'])
                else:
                    user_id = user_info['user_id']

                # パスワードの取得、デコード処理追加
                password = CryptoUtil.get_external_provider_password(
                    dynamodb=self.dynamodb, user_id=user_info['user_id'])

                response = UserUtil.external_provider_login(
                    cognito=self.cognito,
                    user_pool_id=os.environ['COGNITO_USER_POOL_ID'],
                    user_pool_app_id=os.environ['COGNITO_USER_POOL_APP_ID'],
                    user_id=user_id,
                    password=password,
                    provider=os.environ['EXTERNAL_PROVIDER_LOGIN_MARK'])
                return ResponseBuilder.response(
                    status_code=200,
                    body={
                        'access_token':
                        response['AuthenticationResult']['AccessToken'],
                        'id_token':
                        response['AuthenticationResult']['IdToken'],
                        'refresh_token':
                        response['AuthenticationResult']['RefreshToken'],
                        'last_auth_user':
                        user_id,
                        'has_user_id':
                        has_user_id,
                        'status':
                        'login'
                    })
            except ClientError as e:
                logging.info(self.event)
                logging.fatal(e)
                traceback.print_exc()
                return ResponseBuilder.response(
                    status_code=500, body={'message': 'Internal server error'})

        try:
            backed_password = UserUtil.generate_backend_password()
            response = UserUtil.create_external_provider_user(
                cognito=self.cognito,
                user_pool_id=os.environ['COGNITO_USER_POOL_ID'],
                user_pool_app_id=os.environ['COGNITO_USER_POOL_APP_ID'],
                user_id=user_info['user_id'],
                email=user_info['email'],
                backed_temp_password=os.
                environ['EXTERNAL_PROVIDER_LOGIN_COMMON_TEMP_PASSWORD'],
                backed_password=backed_password,
                provider=os.environ['EXTERNAL_PROVIDER_LOGIN_MARK'])

            aes_iv = os.urandom(settings.AES_IV_BYTES)
            encrypted_password = CryptoUtil.encrypt_password(
                backed_password, aes_iv)
            iv = base64.b64encode(aes_iv).decode()

            UserUtil.add_external_provider_user_info(
                dynamodb=self.dynamodb,
                external_provider_user_id=user_info['user_id'],
                password=encrypted_password,
                iv=iv,
                email=user_info['email'])
            return ResponseBuilder.response(
                status_code=200,
                body={
                    'access_token':
                    response['AuthenticationResult']['AccessToken'],
                    'id_token':
                    response['AuthenticationResult']['IdToken'],
                    'refresh_token':
                    response['AuthenticationResult']['RefreshToken'],
                    'last_auth_user':
                    user_info['user_id'],
                    'has_user_id':
                    False,
                    'status':
                    'sign_up'
                })

        except ClientError as e:
            logging.info(self.event)
            logging.fatal(e)
            traceback.print_exc()
            if e.response['Error']['Code'] == 'UsernameExistsException':
                return ResponseBuilder.response(
                    status_code=400, body={'message': 'EmailExistsException'})
            return ResponseBuilder.response(
                status_code=500, body={'message': 'Internal server error'})
class Engine:
    def __init__(self,
                 training_data_path,
                 basic_intents_csv,
                 intent_confidence_thresh=.25):
        self.response_builder = ResponseBuilder(training_data_path)
        self.basic_responder = BasicResponder(basic_intents_csv)
        self.intent_guesser = IntentGuesser(training_data_path)
        self.intent_thresh = intent_confidence_thresh
        self.conversation_context = {}
        self.watson = watson.ConversationAPI(
            watson.rohan_graduate_affairs_config())

    def initialize_context(self, conv_id):
        print self.conversation_context
        if conv_id not in self.conversation_context:
            print "Initializing context for {}".format(conv_id)
            v = {'entities': set(), 'intent': None, 'response': None}
            self.conversation_context[conv_id] = v

    def clear_context(self, conv_id):
        print "Clearing context"
        self.conversation_context.pop(conv_id, None)

    def extract_entities(self, conv_id, response):
        entities = [x['entity'] for x in response['entities']]
        self.conversation_context[conv_id]['entities'].update(entities)

    def guess_intent(self, conv_id):
        intent_guess = self.intent_guesser.guess_intent(
            list(self.conversation_context[conv_id]['entities']))
        return intent_guess

    def extract_intent(self, conv_id, response):
        intents = [
            x['intent'] for x in response['intents']
            if x['confidence'] > self.intent_thresh
        ]
        if len(intents) > 0:
            self.conversation_context[conv_id]['intent'] = intents[0]

        #  if no intents from watson, try to guess using the entities
        # from the response
        else:
            entities = [x['entity'] for x in response['entities']]
            intent_guess = self.intent_guesser.guess_intent(entities)
            if intent_guess:
                self.conversation_context[conv_id]['intent'] = intent_guess

    def preprocess_token(self, token):
        token = nlp.strip_nonalpha_numeric(token)
        # TODO Add autocorrect. Word might be mispelled..Integrate in nlp component not here.
        return token

    def preprocess_sentence(self, sentence):
        tokens = nlp.tokenize_text(sentence)
        ret = ""
        for token in tokens:
            ret += self.preprocess_token(token) + " "
        return ret.strip()

    # Process message focuses on the question or intent of the message above all else. For sentences that don't express intent, it collects entities. If it doesn't find an intent but finds entities it will make it's best guess at an intent, and corresponding response. Message is self_contained if it's in an email or feedback form. For instant message, self_contained should be false.
    def process_message(self,
                        conv_id,
                        message,
                        clear_context=True,
                        self_contained=False,
                        guess=False):
        # This is to manage interactions like "hi!" or "hello", etc.
        basic_response = self.basic_responder.check_and_respond(message)
        if basic_response:
            return {
                'entities': set(),
                'intent': basic_response[0],
                'response': basic_response[1]
            }

        self.initialize_context(conv_id)
        sentences = nlp.get_sentences(message)
        print message
        print type(message)
        full_watson_response = self.watson.json_response(
            conv_id, self.preprocess_sentence(message))
        print "Full watson response {}".format(full_watson_response)
        # self.extract_entities(conv_id, watson_response)
        for sentence in sentences:
            sentence = sentence.strip()
            clean_sentence = self.preprocess_sentence(sentence)
            clean_sentence += "?"
            watson_response = self.watson.json_response(
                conv_id, clean_sentence)
            print watson_response
            print sentence
            if nlp.sentence_is_question(sentence.strip()):
                print "Processing question"
                self.extract_entities(conv_id, watson_response)
                self.extract_intent(conv_id, watson_response)
                context = self.conversation_context[conv_id]
                intent = context['intent']
                entities = list(context['entities'])
                context['response'] = \
                                      self.response_builder.get_best_response(intent, entities)
                if not context['response']:
                    # NOTE: this order matters. we should extract entities before guessing intent and then build response
                    self.extract_entities(conv_id, full_watson_response)
                    if not intent:
                        self.extract_intent(conv_id, full_watson_response)
                    intent = context['intent']
                    entities = list(context['entities'])
                    context['response'] = \
                                          self.response_builder.get_best_response(intent, entities)
                # If we haven't yet found an intent using watson,
                # we can guess using the extracted entities. Only if self.guess is True
                if guess and (not context['intent']
                              or not context['response']):
                    context['intent'] = self.guess_intent(conv_id)
                    context[
                        'response'] = self.response_builder.get_best_response(
                            context['intent'], context['entities'])

                ret = copy.deepcopy(context)
                self.clear_context(conv_id)
                return ret

        # Try using the full message to build the response
        context = self.conversation_context[conv_id]
        self.extract_entities(conv_id, full_watson_response)
        self.extract_intent(conv_id, full_watson_response)

        if (self_contained):
            context['response'] = self.response_builder.get_best_response(
                context['intent'], context['entities'])

        # If we haven't yet found an intent using watson,
        # we can guess using the extracted entities. Only if self.guess is True
        if self_contained and guess and \
           (not context['intent'] or not context['response']):
            context['intent'] = self.guess_intent(conv_id)
            context['response'] = \
                                  self.response_builder.get_best_response(
                                      context['intent'],
                                      context['entities'])

        ret = copy.deepcopy(context)
        if clear_context:
            self.clear_context(conv_id)
        return ret