Puka is an SMS chatbot that helps users locate businesses to resolve common household problems



I have a lot of relatives back home in Hawai’i, many of which are slightly out of touch with modern day technology, and still struggle to figure out the magical black box that is the internet. When they need help with a problem, they either message their children for help, or turn to the yellow pages. So I figured, why not allow people to access information that can be found in the yellow pages through text message? 



The average person has about 80 different apps installed in their phone. That’s a lot of apps, all of them providing some unique value that a user can leverage when needed. The problem with this, is that for each of these apps, the user must familiarize themselves with a new interface, work through different task flows, and acclimate themselves to varying feedback and interactions for each app. For many of these apps, the usage is only triggered by occurrence of an event. 

Enter, the chatbot

From this arises the opportunity to leverage chatbots as a means to access app services through conversational interactions. Puka, an SMS chatbot that helps users resolve common household problems, explores this opportunity. By utilizing the Yelp API, users can tell Puka about a household problem and receive the name, rating, and phone number of nearby businesses that can help. 



I began this project by first doing some secondary research on chatbots in order to understand how users are able to accomplish tasks and resolve problems through conversations. I looked at chatbots within the travel industry in particular, since the domain has a flourishing chatbot presence. Below, I created a domain analysis with axis assessing range of conversationality, and assisting vs. managing.

Domain Analysis of Chatbots

With an understanding the chatbot landscape, I began to consider possible scenarios in which a chatbot would be useful. Since texting is an interaction that is familiar to people of a large range of age groups, I decided to interview older relatives in order to determine some common problems that they experience. One of the more common responses from these interviews was the uncertainty of what to do and who to call during a leak or electrical problem with the house. I figured that many homeowners/renters likely encounter similar scenarios and decided to make a chatbot to address this problem.

I began crafting the bot by considering its personality, and giving it a name. 

Meet Puka

Puka is the Hawaiian word for ‘hole’. I chose this name when recalling one of my interviews with my aunty, in which she described wanting to fix a ‘puka’ in her wall. Keeping Puka’s personality in mind, I started to build the dialog flow to systematically diagram the conversation a user would have with Puka. In this dialog flow, I also experimented with Puka’s tone in the responses. 

Mapping Out the Dialog



Puka is a SMS chatbot that helps users locate nearby businesses to resolve common household problems using the Yelp API. 

1. Determining the Problem

These common household problems are based off of six predefined categories: Electricity, plumbing, leaks, heating, pests, and cleaning services. The code implemented is able to recognize not only keywords associated with the problem, but also the relevant emojis as well. 

def match (body, keywords)
    keywords.each do |keyword|
    keyword = keyword.downcase.strip
    if body.include?(keyword)
        return true
return false

def what_problem?

    problem_list = "Electricity 💡 \n" + "Plumbing 🚰 \n" + "Leak 💧 \n" + "Heating 🔥 \n" + "Pests 🐜 \n" + "Cleaning Service 🧹" 
    sympathy_responses = ["Oh no!", "Sorry to hear that."]
    sympathy_responses.sample + " What sort of problem is it? \n" + problem_list

ELECTRICITY = ["💡", "Electricity 💡", "electricity", "electric", "power", "cable", "wire", "Electricity", "electricity 💡", "⚡️"]
PLUMBING = ["🚰", "Plumbing 🚰", "plumbing", "clog", "clogged", "drain", "plumber", "plumbing 🚰"]
LEAK = ["💧", "Leak 💧", "leaking", "leak 💧", "leakage", "leak"]
HEATING = ["🔥", "heating", "Heating 🔥", "heating 🔥", "heater", "furnace"]
PESTS = ["🐜", "Pests 🐜", "pests", "Pests", "exterminate"]
MESSY = ["Just messy 🧹", "🧹", "messy", "just messy", "messy house", "dirty", "cleaner", "clutter"]

def pick_problem incoming_text
   restate_problem = "Ahh, let me see if I can find someone who can help with your #{incoming_text} problem. \n" + 
   "Message me your zipcode so I can find you some options nearby!"
    if match(incoming_text, ELECTRICITY)
        puts "problem is electricity - #{incoming_text}" 
        return restate_problem
    elsif match(incoming_text, PLUMBING)
        puts "problem is plumbing - #{incoming_text}" 
        return restate_problem
    elsif match(incoming_text, LEAK)
        puts "problem is leak - #{incoming_text}" 
        return restate_problem
    elsif match(incoming_text, HEATING)
        puts "problem is heating- #{incoming_text}" 
        return restate_problem
    elsif match(incoming_text, PESTS)
        puts "problem is pests - #{incoming_text}" 
        return restate_problem
    elsif match(incoming_text, MESSY)
        puts "problem is messy - #{incoming_text}" 
        return restate_problem
        return error_response
Click to Expand

2. Recording Name and Location

Puka is also able to remember the name and the zipcode of the user by storing this information in sessions for later recall. Having the user input the zipcode also allows this information to be set as the location used for the Yelp API business search. 

session["last_intent"] ||= nil
    session["users_name"] ||= nil
    puts "Previous Intent #{session["last_intent"]}"
    puts "Current Username #{session["users_name"]}"
    puts "Current Problem #{session["current_problem"]}"
    puts "User Zipcode #{session["zipcode"]}"
    # this bit is important!!!
    body = body.downcase.strip
    if match(body, user_greetings)
      if session["users_name"].nil?
            session["last_intent"] = "find_name"
            message = puka_greetings.sample + " What's your name?"
            session["last_intent"] = "welcome"
            message = "Hi, #{session["users_name"]}. Welcome back!" + " Is there something needin' a fixin'?"
    elsif match(body, help_greetings)
        session["last_intent"] = "emergency"
        message = description + " What seems to be the problem? \n" + problem_list
    elsif session["last_intent"] == "find_name"
        session["last_intent"] = "saved_name"
        session["users_name"] = body 
        message = "Nice to meet ya #{ body } 👋🏼! \n" + description + "Is there something needin' a fixin'?"
    elsif session["last_intent"] == "saved_name" || session["last_intent"] == "welcome"
        if is_affirmation? (body)
            session["last_intent"] = "problem"
            message = what_problem?
        elsif is_negation? (body)
            session["last_intent"] = "no_problem"
            message = "Glad to hear, partner!"
            message = error_response
    elsif session["last_intent"] == "problem" || session["last_intent"] == "emergency"
        session["last_intent"] = "pick_problem"
        # stores problem
        session["current_problem"] = body
        message = pick_problem body
    elsif session["last_intent"] == "pick_problem"
        session["last_intent"] = "get_zipcode"
        # stores location based on zipcode
        session["zipcode"] = body
        message = get_zipcode body
Click to Expand

3. Retrieve Relevant Businesses

When the user responds with a particular problem, this response is also saved in a session to be used as the search term in the API. Using the formatted JSON file from Yelp, I return the names, phone numbers, and ratings for up to three relevant businesses nearby. 

def search_yelp body
   client = Yelp::Fusion::Client.new(API_KEY)
        location = "#{session["zipcode"]}"
        params = {
            term: "#{session["current_problem"]}",
            limit: 3
        response = client.search(location, params)

        # puts message.businesses.to_s
        # [<Business 1>, <Business 2>, ...]

        num_responses = response.businesses.count
        if num_responses < 1
            puts "Didn't find any matching businesses"
            return "Didn't find any matching businesses"
        elsif num_responses == 1
            name = response.businesses.first.name
            rating = response.businesses.first.phone	
            phone = response.businesses.first.rating	
            str = "I found one business: #{ name } with a rating of #{rating}. You can call them at #{phone}" 
            puts str
            return str
            str = "I found a few business 👍🏼: \n"
            for i in 0..2	
                name = response.businesses[i].name
                rating = response.businesses[i].rating	
                phone = response.businesses[i].phone
                str +="#{ name } with a rating of #{rating}. You can call them at #{phone}. \n"
            puts str
            return str

Click to Expand

Demo Video



Next Steps

Currently, the conversation ends with Puka providing the user with three Yelp businesses, but I think a more useful call to action would be to either allow the user to access the Yelp page on the app, or prompt to call the business of their choosing. I would also like to build out an 'other' category, in the case that the user's problem does not fall under one of the six predefined categories. This flow could help the user diagnose the problem to arrive at a term that can be searched within Yelp. 

If I Had More Time...

I would like to be able to make Puka more than just a bot that can be of use when called upon for a variety of use cases using Yelp's API. Puka could be messaged if a user would like to find nearby businesses for other services such as personal aesthetics, food establishments, auto repairs, and others. 

I would have also liked to spend more time on the conversation between Puka and the user. Right now, I utilize emojis to make the interaction more delightful, but I think use of other media such as giphys could also serve a more dynamic purpose, and might make the overall experience more engaging. 

Share this Project


49714 Programming for Online Prototypes

· 9 members

A hands on introduction to building online products and services through code


Puka is an SMS chatbot that helps users locate businesses to resolve common household problems


May 8th, 2020