示例#1
0
def handle_quick_reply(user_id, context, cmd):
    # Yelp YES response to "Do you want more result?"
    if cmd == 'yelp-more-yes':
        offset = g.user['yelp_offset'] + 5
        Mongo.increment_yelp_offset(users, g.user, 5) # actually update
        result = yelp_search(context['terms'], context['location'], context['coordinates'], 5, offset)

        if result['status'] == 1: # Successful search
            FB.send_message(app.config['PAT'], user_id, "Okay, I've found %s places:"%(len(result['businesses'])))
            FB.send_yelp_results(app.config['PAT'], user_id, result['businesses'])
            FB.send_quick_replies_yelp_search(app.config['PAT'], user_id)
            return 'pseudo'
        else:
            Mongo.pop_context(users, g.user)
            Mongo.reset_yelp_offset(users, g.user)
            return "That's all I found for now :)"

    # Yelp NO response to "Do you want more result?"
    elif cmd == 'yelp-more-no':
        context = g.user['contexts'][-1]
        Mongo.reset_yelp_offset(users, g.user)

        if context['location_from_memory'] == 1:
            Mongo.pop_context(users, g.user)
            return "Glad I can help :)"

        if context['context'] == 'find-food' and context['location'] is not None and context['coordinates'] is not None:
            latest_location = context['location']
            FB.send_quick_replies_yelp_save_location(app.config['PAT'], user_id, latest_location)
            return 'pseudo'

        elif context['context'] == 'find-food' and context['coordinates'] is not None and context['location'] is None:
            # Suggest saving this location
            FB.send_quick_replies_yelp_save_location(app.config['PAT'], user_id)
            return 'pseudo'

        else:
            Mongo.pop_context(users, g.user)
            return "Glad I can help :)"
    
    # Yelp YES response to "Do you want to save this location"
    elif cmd == 'yelp-save-location-yes':
        context = g.user['contexts'][-1]
        latest_coords = context['coordinates']
        latest_location = context['location']
        
        if context['location'] == None: # A search with only coordinates
            contextNow = {'context':'yelp-rename',
                  'name': 'untitled',
                  'coordinates': latest_coords,
                  }
            Mongo.pop_context(users, g.user) # pop find-food context
            Mongo.add_context(users, g.user, contextNow)
            return "What do you want to call it? :D"

        else:
            Mongo.add_yelp_location_history(users, g.user, latest_coords, latest_location)
            Mongo.pop_context(users, g.user)
            Mongo.reset_yelp_offset(users, g.user)
            return "Ta da! I wrote it to my cloudy memory :D"

    # Yelp NO response to "Do you want to save this location"
    elif cmd == 'yelp-save-location-no':
        Mongo.pop_context(users, g.user)
        Mongo.reset_yelp_offset(users, g.user)
        return "OK (y) Hope you like those places I found :D"
    
    # Yelp RENAME response to "Do you want to save this location"
    elif cmd == 'yelp-save-location-rename':
        context = g.user['contexts'][-1]
        latest_location = context['location']
        latest_coords = context['coordinates']
        contextNow = {'context':'yelp-rename', 
                  'name': latest_location,
                  'coordinates': latest_coords,
                  }
        Mongo.pop_context(users, g.user) # pop find-food context
        Mongo.add_context(users, g.user, contextNow)
        return "What do you want to call it? :D"

    # Yelp choose one of the saved location
    elif 'yelp-cached-location-' in cmd:
        idx = int(cmd[-1]) # last character of payload string code
        location = get_recent_locations_yelp(idx)
        FB.send_message(app.config['PAT'], user_id, "Looking around %s :D"%(location['name']))
        message = {}
        message['data'] = location['coordinates']
        return handle_find_food(user_id, context, None, None, message, None, 'receive_location_gps', 1)
示例#2
0
def handle_find_food(user_id, context, sentence, nounPhrase, message, incomingMessage, stage, location_from_memory=0):
    
    if stage == 'receive_request':
        # "Stage 1"
        contextNow = {'context':'find-food', 
                      'location': None,
                      'coordinates': None,
                      'terms': nounPhrase,
                      'location_from_memory': location_from_memory
                      }
        Mongo.add_context(users, g.user, contextNow)
        FB.send_message(app.config['PAT'], user_id, "Can you send me your location? :D")
        if len(g.user['yelp_location_history']) > 0:
            FB.send_quick_replies_yelp_suggest_location(app.config['PAT'], user_id, get_recent_locations_yelp())
        return 'pseudo'
        
    elif stage == 'receive_location_gps':
        # "Stage 2-GPS"
        if location_from_memory == 1:
            Mongo.update_context(users, g.user, 'find-food', 'location_from_memory', 1)

        location = message['data']
        Mongo.update_context(users, g.user, 'find-food', 'coordinates', location)
        FB.send_message(app.config['PAT'], user_id, NLP.oneOf(NLP.looking_replies))
        FB.show_typing(app.config['PAT'], user_id)     

        result = yelp_search(context['terms'], None, location)
        FB.show_typing(app.config['PAT'], user_id, 'typing_off')

        if result['status'] == 1:
            FB.send_message(app.config['PAT'], user_id, "Okay, I've found %s places:"%(len(result['businesses'])))
            FB.send_yelp_results(app.config['PAT'], user_id, result['businesses'])
            FB.send_quick_replies_yelp_search(app.config['PAT'], user_id)
            return 'pseudo'
        else:    
            return "Sorry I couldn't find anything :("

    elif stage == 'receive_location_text':
        # "Stage 2 - Text"

        if context['location'] == None and context['coordinates'] == None:
            context['location'] = nounPhrase
            try:
                geolocator = Nominatim()
                location_lookup = geolocator.geocode(nounPhrase)
                coords = [location_lookup.latitude, location_lookup.longitude]
                Mongo.update_context(users, g.user, 'find-food', 'coordinates', coords)
                Mongo.update_context(users, g.user, 'find-food', 'location', nounPhrase)
                FB.show_typing(app.config['PAT'], user_id)
                FB.send_message(app.config['PAT'], user_id, NLP.oneOf(NLP.looking_replies))
                result = yelp_search(context['terms'], None, coords)

            except Exception, e:
                print e
                Mongo.update_context(users, g.user, 'find-food', 'location', nounPhrase)
                FB.send_message(app.config['PAT'], user_id, NLP.oneOf(NLP.looking_replies))
                result = yelp_search(context['terms'], nounPhrase)
            
            FB.show_typing(app.config['PAT'], user_id, 'typing_off')
            if result['status'] == 1: # Successful search
                FB.send_message(app.config['PAT'], user_id, "Okay, I've found %s places:"%(len(result['businesses'])))
                FB.send_yelp_results(app.config['PAT'], user_id, result['businesses'])
                FB.send_quick_replies_yelp_search(app.config['PAT'], user_id)
                return 'pseudo'
            else:
                Mongo.pop_context(users, g.user)
                return "Sorry I can't find any results for that :("
                # Follow up?
        else:
            Mongo.pop_context(users, g.user)
            return
示例#3
0
def processIncoming(user_id, message, just_text=False):
    # First time user
    if not Mongo.user_exists(users, user_id):
        g.user = Mongo.get_user_mongo(users, user_id)
        return handle_first_time_user(users, g.user)
    else:
        g.user = Mongo.get_user_mongo(users, user_id)

    last_seen = datetime.strptime(g.user['last_seen'],"%Y-%m-%d %H:%M:%S")
    recent5min = datetime.now() - timedelta(minutes=5)

    if last_seen < recent5min:
        Mongo.update_last_seen(users, g.user)

    contextData = g.user['contexts']

    # Text message type =========================================================
    if just_text or message['type'] == 'text':
        # just_text is transcribe audio
        message_text = message if just_text else message['data']

        if dev_area(message_text): # go through development codes
            return 'pseudo'

        if message_text.lower() == "help":
            handle_help(user_id)
            return 'pseudo'
        
        if message_text[-1] != ".": # help separate sentence for parsetree
            dotted_message = message_text + "."
        s = parsetree(dotted_message, relations=True, lemmata=True)
        sentence = s[0]
        nounPhrase = NLP.findNounPhrase(sentence)

        

        if NLP.isAskingBotInformation(sentence):
            return NLP.handleBotInfo(sentence)

        if contextData is not None and len(contextData) > 0:
            context = contextData[-1]

            if NLP.isDismissPreviousRequest(message_text):
                Mongo.pop_context(users, g.user)
                return "Sure, no problem"

            # Find food functionality
            if context['context'] == 'find-food':
                return handle_find_food(user_id, context, sentence, nounPhrase, message, message_text, 'receive_location_text')
            
            elif context['context'] == 'yelp-rename':
                handle_yelp_rename(user_id, g.user, context, message_text)
                Mongo.pop_context(users, g.user) # pop yelp-rename
                return "Ta da! %s is now in my cloudy memory :D"%(message_text)

            elif context['context'] == 'create-memo':
                return handle_memo(user_id, message_text)
    
        else:
            if NLP.isGreetings(message_text):
                greeting = "%s %s :D"%(NLP.sayHiTimeZone(g.user), g.user['first_name'])
                FB.send_message(app.config['PAT'], user_id, greeting)
                return "How can I help you?"

            elif NLP.isGoodbye(message_text):
                return NLP.sayByeTimeZone(g.user)

            elif NLP.isYelp(sentence): 
                print nounPhrase               
                return handle_find_food(user_id, None, sentence, nounPhrase, message, message_text, 'receive_request')

            elif NLP.isMemoCommandOnly(message_text):
                data = { 'context': 'create-memo' }
                Mongo.add_context(users, g.user, data)
                return "I'm listening, go ahead :D"

            elif NLP.isMemo(message_text):
                content = NLP.get_memo_content(message_text)
                return handle_memo(user_id, content)

            elif NLP.isGetNews(sentence):
                keyword = NLP.getNewsQuery(sentence)
                FB.send_message(app.config['PAT'], user_id, "Scanning %s documents on the Internet B-)"%(random.randint(9999,999999)*random.randint(9999,999999)+random.randint(1,9)) )
                FB.show_typing(app.config['PAT'], user_id)
                posts = News.get_trending_news(keyword)
                FB.show_typing(app.config['PAT'], user_id, 'typing_off')

                # Log if there's no result to analyze
                if len(posts) == 0:
                    FB.send_message(app.config['PAT'], user_id, "Sorry, I can't find any news for that :(")
                    Mongo.log_message(log, user_id, 'no_news', keyword)

                else:
                    FB.send_trending_news(app.config['PAT'], user_id, posts)
                return 'pseudo'

            else:
                # Log this message for categorization later
                Mongo.log_message(uncategorized_messages, user_id, "text", message_text)
                try:
                    response = simSimi.getConversation(message_text)['response']
                    bad_times = 0
                    while NLP.badWords(response):
                        bad_times += 1
                        print response
                        response = simSimi.getConversation(message_text)['response']
                        if bad_times == 5:
                            return "Hmm... I can't think of anything witty enough to respond to that :P"
                    if 'simsimi' in response.lower():
                        response = response.lower().replace("simsimi", "Optimist Prime")
                    return response

                except simsimi.SimSimiException as e:
                    print e
                    return # return None will trigger a bot confusion response
    # ==/ END Text message type =====================================================

    # Location message type =========================================================
    elif message['type'] == 'location':
        FB.send_message(app.config['PAT'], user_id, "I've received location (%s,%s) (y)"%(message['data'][0],message['data'][1]))

        if contextData is not None and len(contextData) > 0:
            context = contextData[-1]
            if 'context' in context and context['context'] == 'find-food':
                return handle_find_food(user_id, context, None, None, message, None, 'receive_location_gps')
        else:
            return 'pseudo'
    # ==/ END Location message type ==================================================

    # Audio message type =========================================================
    elif message['type'] == 'audio':
        audio_url = message['data']

        # Get text from audio
        try:
            message_text = STT.transcribe(audio_url)
            if message_text == "" or message_text == None:
                return
            # if 'DISPLAY_STT_RESULT' in os.environ and os.environ['DISPLAY_STT_RESULT'] != 0:
            print message_text
        except Exception, e:
            message_text = "Sorry I can't process that now :("
            FB.send_message(app.config['PAT'], user_id, message_text)
            print e
            return

        # Begin processing audio command
        message_text = message_text.decode('utf-8')
        return processIncoming(user_id, message_text, True)
def handle_quick_reply(user_id, context, cmd):
    # Yelp YES response to "Do you want more result?"
    if cmd == 'yelp-more-yes':
        offset = g.user['yelp_offset'] + 5
        Mongo.increment_yelp_offset(users, g.user, 5)  # actually update
        result = yelp_search(context['terms'], context['location'],
                             context['coordinates'], 5, offset)

        if result['status'] == 1:  # Successful search
            FB.send_message(
                app.config['PAT'], user_id,
                "Okay, I've found %s places:" % (len(result['businesses'])))
            FB.send_yelp_results(app.config['PAT'], user_id,
                                 result['businesses'])
            FB.send_quick_replies_yelp_search(app.config['PAT'], user_id)
            return 'pseudo'
        else:
            Mongo.pop_context(users, g.user)
            Mongo.reset_yelp_offset(users, g.user)
            return "That's all I found for now :)"

    # Yelp NO response to "Do you want more result?"
    elif cmd == 'yelp-more-no':
        context = g.user['contexts'][-1]
        Mongo.reset_yelp_offset(users, g.user)

        if context['location_from_memory'] == 1:
            Mongo.pop_context(users, g.user)
            return "Glad I can help :)"

        if context['context'] == 'find-food' and context[
                'location'] is not None and context['coordinates'] is not None:
            latest_location = context['location']
            FB.send_quick_replies_yelp_save_location(app.config['PAT'],
                                                     user_id, latest_location)
            return 'pseudo'

        elif context['context'] == 'find-food' and context[
                'coordinates'] is not None and context['location'] is None:
            # Suggest saving this location
            FB.send_quick_replies_yelp_save_location(app.config['PAT'],
                                                     user_id)
            return 'pseudo'

        else:
            Mongo.pop_context(users, g.user)
            return "Glad I can help :)"

    # Yelp YES response to "Do you want to save this location"
    elif cmd == 'yelp-save-location-yes':
        context = g.user['contexts'][-1]
        latest_coords = context['coordinates']
        latest_location = context['location']

        if context['location'] == None:  # A search with only coordinates
            contextNow = {
                'context': 'yelp-rename',
                'name': 'untitled',
                'coordinates': latest_coords,
            }
            Mongo.pop_context(users, g.user)  # pop find-food context
            Mongo.add_context(users, g.user, contextNow)
            return "What do you want to call it? :D"

        else:
            Mongo.add_yelp_location_history(users, g.user, latest_coords,
                                            latest_location)
            Mongo.pop_context(users, g.user)
            Mongo.reset_yelp_offset(users, g.user)
            return "Ta da! I wrote it to my cloudy memory :D"

    # Yelp NO response to "Do you want to save this location"
    elif cmd == 'yelp-save-location-no':
        Mongo.pop_context(users, g.user)
        Mongo.reset_yelp_offset(users, g.user)
        return "OK (y) Hope you like those places I found :D"

    # Yelp RENAME response to "Do you want to save this location"
    elif cmd == 'yelp-save-location-rename':
        context = g.user['contexts'][-1]
        latest_location = context['location']
        latest_coords = context['coordinates']
        contextNow = {
            'context': 'yelp-rename',
            'name': latest_location,
            'coordinates': latest_coords,
        }
        Mongo.pop_context(users, g.user)  # pop find-food context
        Mongo.add_context(users, g.user, contextNow)
        return "What do you want to call it? :D"

    # Yelp choose one of the saved location
    elif 'yelp-cached-location-' in cmd:
        idx = int(cmd[-1])  # last character of payload string code
        location = get_recent_locations_yelp(idx)
        FB.send_message(app.config['PAT'], user_id,
                        "Looking around %s :D" % (location['name']))
        message = {}
        message['data'] = location['coordinates']
        return handle_find_food(user_id, context, None, None, message, None,
                                'receive_location_gps', 1)
def handle_find_food(user_id,
                     context,
                     sentence,
                     nounPhrase,
                     message,
                     incomingMessage,
                     stage,
                     location_from_memory=0):

    if stage == 'receive_request':
        # "Stage 1"
        contextNow = {
            'context': 'find-food',
            'location': None,
            'coordinates': None,
            'terms': nounPhrase,
            'location_from_memory': location_from_memory
        }
        Mongo.add_context(users, g.user, contextNow)
        FB.send_message(app.config['PAT'], user_id,
                        "Can you send me your location? :D")
        if len(g.user['yelp_location_history']) > 0:
            FB.send_quick_replies_yelp_suggest_location(
                app.config['PAT'], user_id, get_recent_locations_yelp())
        return 'pseudo'

    elif stage == 'receive_location_gps':
        # "Stage 2-GPS"
        if location_from_memory == 1:
            Mongo.update_context(users, g.user, 'find-food',
                                 'location_from_memory', 1)

        location = message['data']
        Mongo.update_context(users, g.user, 'find-food', 'coordinates',
                             location)
        FB.send_message(app.config['PAT'], user_id,
                        NLP.oneOf(NLP.looking_replies))
        FB.show_typing(app.config['PAT'], user_id)

        result = yelp_search(context['terms'], None, location)
        FB.show_typing(app.config['PAT'], user_id, 'typing_off')

        if result['status'] == 1:
            FB.send_message(
                app.config['PAT'], user_id,
                "Okay, I've found %s places:" % (len(result['businesses'])))
            FB.send_yelp_results(app.config['PAT'], user_id,
                                 result['businesses'])
            FB.send_quick_replies_yelp_search(app.config['PAT'], user_id)
            return 'pseudo'
        else:
            return "Sorry I couldn't find anything :("

    elif stage == 'receive_location_text':
        # "Stage 2 - Text"

        if context['location'] == None and context['coordinates'] == None:
            context['location'] = nounPhrase
            try:
                geolocator = Nominatim()
                location_lookup = geolocator.geocode(nounPhrase)
                coords = [location_lookup.latitude, location_lookup.longitude]
                Mongo.update_context(users, g.user, 'find-food', 'coordinates',
                                     coords)
                Mongo.update_context(users, g.user, 'find-food', 'location',
                                     nounPhrase)
                FB.show_typing(app.config['PAT'], user_id)
                FB.send_message(app.config['PAT'], user_id,
                                NLP.oneOf(NLP.looking_replies))
                result = yelp_search(context['terms'], None, coords)

            except Exception, e:
                print e
                Mongo.update_context(users, g.user, 'find-food', 'location',
                                     nounPhrase)
                FB.send_message(app.config['PAT'], user_id,
                                NLP.oneOf(NLP.looking_replies))
                result = yelp_search(context['terms'], nounPhrase)

            FB.show_typing(app.config['PAT'], user_id, 'typing_off')
            if result['status'] == 1:  # Successful search
                FB.send_message(
                    app.config['PAT'], user_id, "Okay, I've found %s places:" %
                    (len(result['businesses'])))
                FB.send_yelp_results(app.config['PAT'], user_id,
                                     result['businesses'])
                FB.send_quick_replies_yelp_search(app.config['PAT'], user_id)
                return 'pseudo'
            else:
                Mongo.pop_context(users, g.user)
                return "Sorry I can't find any results for that :("
                # Follow up?
        else:
            Mongo.pop_context(users, g.user)
            return
def processIncoming(user_id, message, just_text=False):
    # First time user
    if not Mongo.user_exists(users, user_id):
        g.user = Mongo.get_user_mongo(users, user_id)
        return handle_first_time_user(users, g.user)
    else:
        g.user = Mongo.get_user_mongo(users, user_id)

    last_seen = datetime.strptime(g.user['last_seen'], "%Y-%m-%d %H:%M:%S")
    recent5min = datetime.now() - timedelta(minutes=5)

    if last_seen < recent5min:
        Mongo.update_last_seen(users, g.user)

    contextData = g.user['contexts']

    # Text message type =========================================================
    if just_text or message['type'] == 'text':
        # just_text is transcribe audio
        message_text = message if just_text else message['data']

        if dev_area(message_text):  # go through development codes
            return 'pseudo'

        if message_text.lower() == "help":
            handle_help(user_id)
            return 'pseudo'

        if message_text[-1] != ".":  # help separate sentence for parsetree
            dotted_message = message_text + "."
        s = parsetree(dotted_message, relations=True, lemmata=True)
        sentence = s[0]
        nounPhrase = NLP.findNounPhrase(sentence)

        if NLP.isAskingBotInformation(sentence):
            return NLP.handleBotInfo(sentence)

        if contextData is not None and len(contextData) > 0:
            context = contextData[-1]

            if NLP.isDismissPreviousRequest(message_text):
                Mongo.pop_context(users, g.user)
                return "Sure, no problem"

            # Find food functionality
            if context['context'] == 'find-food':
                return handle_find_food(user_id, context, sentence, nounPhrase,
                                        message, message_text,
                                        'receive_location_text')

            elif context['context'] == 'yelp-rename':
                handle_yelp_rename(user_id, g.user, context, message_text)
                Mongo.pop_context(users, g.user)  # pop yelp-rename
                return "Ta da! %s is now in my cloudy memory :D" % (
                    message_text)

            elif context['context'] == 'create-memo':
                return handle_memo(user_id, message_text)

        else:
            if NLP.isGreetings(message_text):
                greeting = "%s %s :D" % (NLP.sayHiTimeZone(
                    g.user), g.user['first_name'])
                FB.send_message(app.config['PAT'], user_id, greeting)
                return "How can I help you?"

            elif NLP.isGoodbye(message_text):
                return NLP.sayByeTimeZone(g.user)

            elif NLP.isYelp(sentence):
                print nounPhrase
                return handle_find_food(user_id, None, sentence, nounPhrase,
                                        message, message_text,
                                        'receive_request')

            elif NLP.isMemoCommandOnly(message_text):
                data = {'context': 'create-memo'}
                Mongo.add_context(users, g.user, data)
                return "I'm listening, go ahead :D"

            elif NLP.isMemo(message_text):
                content = NLP.get_memo_content(message_text)
                return handle_memo(user_id, content)

            elif NLP.isGetNews(sentence):
                keyword = NLP.getNewsQuery(sentence)
                FB.send_message(
                    app.config['PAT'], user_id,
                    "Scanning %s documents on the Internet B-)" %
                    (random.randint(9999, 999999) *
                     random.randint(9999, 999999) + random.randint(1, 9)))
                FB.show_typing(app.config['PAT'], user_id)
                posts = News.get_trending_news(keyword)
                FB.show_typing(app.config['PAT'], user_id, 'typing_off')

                # Log if there's no result to analyze
                if len(posts) == 0:
                    FB.send_message(
                        app.config['PAT'], user_id,
                        "Sorry, I can't find any news for that :(")
                    Mongo.log_message(log, user_id, 'no_news', keyword)

                else:
                    FB.send_trending_news(app.config['PAT'], user_id, posts)
                return 'pseudo'

            else:
                # Log this message for categorization later
                Mongo.log_message(uncategorized_messages, user_id, "text",
                                  message_text)
                try:
                    response = simSimi.getConversation(
                        message_text)['response']
                    bad_times = 0
                    while NLP.badWords(response):
                        bad_times += 1
                        print response
                        response = simSimi.getConversation(
                            message_text)['response']
                        if bad_times == 5:
                            return "Hmm... I can't think of anything witty enough to respond to that :P"
                    if 'simsimi' in response.lower():
                        response = response.lower().replace(
                            "simsimi", "Optimist Prime")
                    return response

                except simsimi.SimSimiException as e:
                    print e
                    return  # return None will trigger a bot confusion response
    # ==/ END Text message type =====================================================

    # Location message type =========================================================
    elif message['type'] == 'location':
        FB.send_message(
            app.config['PAT'], user_id, "I've received location (%s,%s) (y)" %
            (message['data'][0], message['data'][1]))

        if contextData is not None and len(contextData) > 0:
            context = contextData[-1]
            if 'context' in context and context['context'] == 'find-food':
                return handle_find_food(user_id, context, None, None, message,
                                        None, 'receive_location_gps')
        else:
            return 'pseudo'
    # ==/ END Location message type ==================================================

    # Audio message type =========================================================
    elif message['type'] == 'audio':
        audio_url = message['data']

        # Get text from audio
        try:
            message_text = STT.transcribe(audio_url)
            if message_text == "" or message_text == None:
                return
            # if 'DISPLAY_STT_RESULT' in os.environ and os.environ['DISPLAY_STT_RESULT'] != 0:
            print message_text
        except Exception, e:
            message_text = "Sorry I can't process that now :("
            FB.send_message(app.config['PAT'], user_id, message_text)
            print e
            return

        # Begin processing audio command
        message_text = message_text.decode('utf-8')
        return processIncoming(user_id, message_text, True)