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})
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} )
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):
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'})
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