def reset_stored_values(self): logger.debug("**************** entering {}.{}".format(self.__class__.__name__, self.intent_name)) established_dialog = self.peek_established_dialog() if established_dialog['confirmation'] == 'yes': self.session.reset_stored_values() reply_dialog = self.reply_dialog[self.intent_name] return Reply.build(reply_dialog['conditions']['yes'], self.event) else: # established_dialog['confirmation'] == 'no': reply_dialog = self.reply_dialog[self.intent_name] logger.debug( "conditions_no=={}".format(json.dumps(reply_dialog['conditions']['no'], sort_keys=True, indent=4))) reply = Reply.build(reply_dialog['conditions']['no'], self.event) return reply
def launch_request(self): logger.debug("**************** entering {}.launch_request".format( self.__class__.__name__)) self._intent_name = 'welcome_request' reply_dialog = self.reply_dialog[self.intent_name] reply = Reply.build(reply_dialog, self.event) return reply
def set_current_time_zone(self): logger.debug("**************** entering {}.{}".format(self.__class__.__name__, self.intent_name)) valid_time_zones = ['Pacific', 'Mountain', 'Central', 'Eastern', 'Alaska', 'Hawaii', 'Arizona'] # is this a good state? established_dialog = self.peek_established_dialog() state_good = True if established_dialog is None: state_good = False else: if established_dialog['intent_name'] != self.intent_name: state_good = False if state_good: self.slot_data_to_intent_attributes() time_adj = None if 'time_zone' in established_dialog: time_zone = established_dialog['time_zone'] time_zone = time_zone.title() if time_zone in valid_time_zones: time_adj = TimeOfDay.time_adj_given_tz("US/{}".format(time_zone)) self.session.attributes['time_zone'] = time_zone if time_adj is not None: self.pop_established_dialog() self.session.attributes['time_adj'] = str(time_adj) self.session.save() established_dialog = self.peek_established_dialog() self._intent_name = established_dialog['intent_name'] return self.execute_method(self._intent_name) else: reply_dialog = self.reply_dialog[self.intent_name] return Reply.build(reply_dialog['conditions']['retry'], self.event) else: return self.handle_session_end_confused()
def get_first_event_intent(self): logger.debug("**************** entering {}.{}".format(self.__class__.__name__, self.intent_name)) date_str = self.request.attributes['day'] try: date = datetime.datetime.strptime(date_str, "%Y-%m-%d") month = date.strftime('%B') day = str(date.day) history_buff = HistoryBuff() events = history_buff.get_history_for_date(month, day) if len(events) >= 3: self.request.attributes['event_1'] = events.pop() self.request.attributes['event_2'] = events.pop() self.request.attributes['event_3'] = events.pop() self.session.attributes['month'] = month self.session.attributes['day_nbr'] = day self.session.attributes['events'] = events condition = 'have_events' else: condition = 'no_events' except ValueError: condition = 'bad_date' reply_dialog = self.reply_dialog[self.intent_name]['conditions'][condition] return Reply.build(reply_dialog, self.event)
def launch_request(self): logger.debug("**************** entering DiabetesDialog.launch_request") self._intent_name = 'welcome_request' reply_dialog = self.reply_dialog[self.intent_name] reply = Reply.build(reply_dialog, self.event) # logger.debug("Reply=={}".format(json.dumps(reply, sort_keys=True, indent=4))) return reply
def account_link_intent(self): """ Called to generate an Account Link Card """ logger.debug("**************** entering {}.{}".format( self.__class__.__name__, self.intent_name)) reply_dialog = self.reply_dialog['account_link_intent'] return Reply.build(reply_dialog)
def timezone_intent(self): logger.debug("**************** entering {}.{}".format( self.__class__.__name__, self.intent_name)) amazon_profile = AmazonProfile(self.session.access_token) zip_code = amazon_profile.get_zip_code() zip_code_db = ZipcodeDB() user_timezone = zip_code_db.get_timezone_for_zip_code(zip_code) self.session.attributes["user_timezone"] = user_timezone reply_dialog = self.reply_dialog['timezone_intent'] return Reply.build(reply_dialog, self.event)
def add_player_intent(self): logger.debug("**************** entering {}.{}".format( self.__class__.__name__, self.intent_name)) scorekeeper = Scorekeeper(self.session.attributes['game']) scorekeeper.add_player(self.request.attributes['PlayerName']) self.session.attributes['game'] = scorekeeper.game self.session.save() reply_dialog = self.reply_dialog[self.intent_name] return Reply.build(reply_dialog, self.event)
def whos_there_intent(self): logger.debug("**************** entering {}.{}".format( self.__class__.__name__, self.intent_name)) if self.session.attributes['expect_intent'] != 'whos_there_intent': condition = 'unexpected' else: self.session.attributes['expect_intent'] = 'setup_name_who_intent' condition = 'expected' reply_dialog = self.reply_dialog[self.intent_name] reply_dialog = reply_dialog['conditions'][condition] return Reply.build(reply_dialog, self.event)
def whats_my_color_intent(self): logger.debug("**************** entering {}.{}".format( self.__class__.__name__, self.intent_name)) # 1. Get the processing details for this intent from amy_dialog_model reply_dialog = self.reply_dialog[self.intent_name] # 2. See if we have a session Attribute for Color if self.session.attribute_exists('Color'): reply_dialog = reply_dialog['conditions']['have_color'] else: reply_dialog = reply_dialog['conditions']['dont_have_color'] return Reply.build(reply_dialog, self.event)
def process_request(self, required, function_to_call): required_fields_fun = required_fields(required) # call @required_fields decorator directly so we can add the suffix to the correction_factor_ wrapper_fun = required_fields_fun(function_to_call) response = wrapper_fun(self) if isinstance(response, dict): return response else: dose_no_dose = 'dose' if response <= 0: dose_no_dose = 'no_dose' self.session.save() reply_dialog = self.reply_dialog[self.intent_name] return Reply.build(reply_dialog['conditions'][dose_no_dose], self.event)
def launch_request(self): logger.debug("**************** entering {}.launch_request".format( self.__class__.__name__)) self._intent_name = 'welcome_request' scorekeeper = Scorekeeper(self.session.attributes['game']) condition = 'no_players' if scorekeeper.number_of_players > 0: payer_players = lambda players: '1 player' if players == 1 else str( players) + ' players' self.request.attributes['players_text'] = payer_players( scorekeeper.number_of_players) condition = 'has_players' reply_dialog = self.reply_dialog[self.intent_name] return Reply.build(reply_dialog['conditions'][condition], self.event)
def dialog_tide_intent(self): logger.debug("**************** entering {}.{}".format( self.__class__.__name__, self.intent_name)) # required_fields decorator will redirect us if we do not have all the needed fields tides = TideInfo.tide_http_call(self.request.attributes['City'], self.request.attributes['Date']) condition = 'failed_to_find_tides' if tides is not None: for key in tides.keys(): self.session.attributes[key] = tides[key] condition = 'found_tides' reply_dialog = self.reply_dialog[ self.intent_name]['conditions'][condition] return Reply.build(reply_dialog, self.event)
def setup_name_who_intent(self): logger.debug("**************** entering {}.{}".format( self.__class__.__name__, self.intent_name)) if self.session.attributes['expect_intent'] != 'setup_name_who_intent': condition = 'unexpected' else: setup_name = self.request.value_for_slot_name('SetupName') who = self.session.attributes['who'] if setup_name != who: condition = 'unexpected' else: condition = 'expected' reply_dialog = self.reply_dialog[self.intent_name] reply_dialog = reply_dialog['conditions'][condition] return Reply.build(reply_dialog, self.event)
def get_next_event_intent(self): logger.debug("**************** entering {}.{}".format(self.__class__.__name__, self.intent_name)) if not self.session.attribute_exists('events'): condition = 'no_events' else: events = self.session.attributes['events'] if len(events) >= 3: self.request.attributes['event_1'] = events.pop() self.request.attributes['event_2'] = events.pop() self.request.attributes['event_3'] = events.pop() condition = 'have_events' else: condition = 'no_more_events' reply_dialog = self.reply_dialog[self.intent_name]['conditions'][condition] return Reply.build(reply_dialog, self.event)
def tell_scores_intent(self): logger.debug("**************** entering {}.{}".format( self.__class__.__name__, self.intent_name)) scorekeeper = Scorekeeper(self.session.attributes['game']) condition = 'no_players' if scorekeeper.number_of_players > 0: leader_board = '' condition = 'has_players' for player, score in scorekeeper.leader_board(): point_or_points = lambda score: ' point \n' if score == 1 else ' points \n' leader_board += player + ' has ' + str( score) + point_or_points(score) self.request.attributes['leader_board'] = leader_board reply_dialog = self.reply_dialog[self.intent_name] return Reply.build(reply_dialog['conditions'][condition], self.event)
def handle_default_intent(self, use_default_message=None): logger.debug( '**************** entering DefaultDialog.handle_default_intent') try: reply_dialog = self.reply_dialog[self.intent_name] except KeyError as error: if use_default_message is not None: reply_dialog = { "speech_out_text": "Good Bye.", "should_end_session": True } else: raise DialogIntentError( "No key found for Intent in Dialog: {}".format( self.intent_name)) from error reply = Reply.build(reply_dialog, self.event) return reply
def lambda_handler(event_dict, context): logger.warning("**************** entering NEW lambda_handler") try: logger.warning("REQUEST {}".format( json.dumps(event_dict, sort_keys=True, indent=4))) dialog_obj = SkillFactory.build() response = dialog_obj.begin(event_dict) logger.warning("REPLY {}".format( json.dumps(response, sort_keys=True, indent=4))) except ASKAmyError as error: logger.critical("ASK Amy failed with critical Error: {}".format(error)) response_dict = { "speech_out_text": "Error while processing your request, Please try again. Good Bye.", "should_end_session": True } response = Reply.build(response_dict) return response
def need_valid_data(self, validation_errors): logger.debug( "**************** entering StackDialogManager.need_valid_data") for validation_error in validation_errors: slot_name = validation_error[0] status_code = validation_error[1] expected_intent = self.get_expected_intent_for_data(slot_name) new_intent_attributes = self.push_established_dialog( expected_intent) new_intent_attributes['slot_name'] = slot_name slot_details = self.get_value_from_dict(['slots', slot_name]) slot_details['should_end_session'] = False msg_text = 'msg_{0:02d}_text'.format(status_code) slot_details['speech_out_text'] = slot_details['validation'][ msg_text] reply = Reply.build(slot_details, self.event) return reply
def wrapper(*args, **kwargs): obj = args[0] if isinstance(obj, StackDialogManager): established_dialog = obj.peek_established_dialog() if established_dialog is None: obj.push_established_dialog(obj.intent_name) obj.push_established_dialog('confirmation_intent') reply_dialog = obj.reply_dialog[obj.intent_name] return Reply.build( reply_dialog['conditions']['confirmation'], obj.event) else: if established_dialog['intent_name'] != obj.intent_name: return obj.handle_session_end_confused() if established_dialog['confirmation'] not in ['yes', 'no']: return obj.handle_session_end_confused() ret_val = func(*args, **kwargs) else: ret_val = func(*args, **kwargs) return ret_val
def add_score_intent(self): logger.debug("**************** entering {}.{}".format( self.__class__.__name__, self.intent_name)) scorekeeper = Scorekeeper(self.session.attributes['game']) score_str = self.request.attributes['ScoreNumber'] player_name = self.request.attributes['ScoreName'] if not scorekeeper.is_player(player_name): condition = 'invalid_player_provided' else: condition = 'score_added' scorekeeper.add_score(player_name, score_str) self.session.attributes['game'] = scorekeeper.game score_points = lambda score: '1 point' if score == 1 else str( score) + ' points' self.request.attributes['score_points'] = score_points( int(score_str)) self.session.save() reply_dialog = self.reply_dialog[self.intent_name] return Reply.build(reply_dialog['conditions'][condition], self.event)
def required_fields_process(self, required_fields): """ review the required fields to process this intent if we have all the data move forward if not create a reply that will call an appropriate intent to get the missing data :param required_fields: :return: """ logger.debug( "**************** entering StackDialogManager.required_fields_process" ) reply_dict = None intent_attributes = self.peek_established_dialog() for key in required_fields: if key not in intent_attributes.keys(): expected_intent = self.get_expected_intent_for_data(key) new_intent_attributes = self.push_established_dialog( expected_intent) new_intent_attributes['slot_name'] = key reply_slot_dict = self.get_slot_data_details(key) return Reply.build(reply_slot_dict, self.event) return reply_dict
def get_address_intent(self): logger.debug("**************** entering {}.{}".format( self.__class__.__name__, self.intent_name)) permissions = self.context.system.consent_token if not permissions: # The app does not have permissions condition = 'no_permissions' else: address_service = AddressService() address_response = address_service.get_full_address( self.context.system.api_endpoint, self.context.system.device_id, self.context.system.api_access_token) if address_response['status_cd'] == 200: address = address_response['body'] # We should check if we have all the data we need if 'addressLine1' in address and address[ 'addressLine1'] is not None: condition = 'address_found' self.request.attributes['address_line1'] = address[ 'addressLine1'] self.request.attributes['city'] = address['city'] state_nm = USSateNamesUtility.state_nm_for_cd( address['stateOrRegion']) self.request.attributes['state'] = state_nm else: condition = 'address_found_with_no_data' else: condition = 'address_not_found' self.session.attributes['status_cd'] = address_response[ 'status_cd'] self.session.attributes['reason'] = address_response['reason'] reply_dialog = self.reply_dialog[ self.intent_name]['conditions'][condition] return Reply.build(reply_dialog, self.event)
def number_guess_intent(self): """ This method is called when we provide Alexa with a guess Note: That even though the slot type is defined as an AMAZON.NUMBER it is not guaranteed to be one so you should do some checking before processing """ logger.debug("**************** entering {}.{}".format( self.__class__.__name__, self.intent_name)) # 1. Get the processing details for this intent from amy_dialog_model reply_dialog = self.reply_dialog[self.intent_name] # 2. See if we have any slots filled guessed_number_str = self.request.value_for_slot_name('number') if guessed_number_str is not None: self.request.attributes['guessed_number'] = guessed_number_str # 3. Take a turn at the game high_low_game = HighLowGame( self.session.attributes['winning_number']) guess_result = high_low_game.guess(guessed_number_str) # 4. Process results if guess_result == HighLowGame.Winner: reply_dialog = reply_dialog['conditions']['winner'] self.session.attributes['games_played'] += 1 self.session.save() elif guess_result == HighLowGame.ToLow: self.request.attributes['to_high_to_low'] = 'low' reply_dialog = reply_dialog['conditions']['to_high_to_low'] elif guess_result == HighLowGame.ToHigh: self.request.attributes['to_high_to_low'] = 'high' reply_dialog = reply_dialog['conditions']['to_high_to_low'] else: # out of Range reply_dialog = reply_dialog['conditions']['range_error'] return Reply.build(reply_dialog, self.event)
def handle_session_end_confused(self): """ Called if we are in an intent but don't have the info to move forward and are not sure how or why alex called us here (obviously this should not be a common occurrence.) :return: """ logger.debug( '**************** entering StackDialogManager.handle_session_end_confused' ) # can we re_prompt? MAX_RETRY = 4 dialog_state = self.peek_established_dialog() if dialog_state is None: dialog_state = {} if 'retry_attempted' not in dialog_state.keys(): dialog_state['retry_attempted'] = 1 if dialog_state['retry_attempted'] <= MAX_RETRY: prompt_dict = { "speech_out_text": "Could you please repeat or say help.", "should_end_session": False } if 'slot_name' in dialog_state.keys(): requested_value_nm = dialog_state['slot_name'] prompt_dict = self.get_re_prompt_for_slot_data( requested_value_nm) dialog_state['retry_attempted'] += 1 return Reply.build(prompt_dict, self.event) else: # we are done self._intent_name = 'handle_session_end_confused' return self.handle_default_intent()