After chatting with Jon and the team from Best Friends Animal Society, we were inspired to create a hack to support some of Best Friends' most pressing needs. We wanted to try our hand at building a chatbot, and though they can be overly flashy but not particularly useful, we think AdoptBot could be a great addition to Best Friends' online outreach strategy.
A chatbot allows users to quickly get personalized information in one place and ask questions naturally, 24/7 and using any device. Users are also often reluctant to scour a website or social media for information; with a chatbot, one can just send a message and have the bot do the work. Due to the platform's interactive nature, there's also less user drop-off, especially when the bot's responses include some call to action or prompt.
What it does
AdoptBot processes users' natural language queries and responds to them in plain English as well. Users can ask about pet adoption, donation, and volunteer opportunities. AdoptBot also integrates with the RescueGroups API to query the database of pets up for adoption and presents the user with up-to-date, localized information.
How we built it
We used a number of technologies to create AdoptBot. The service was primarily implemented with Python 3. We used libraries such as NLTK (natural language toolkit) to form the basis of our natural language processing capabilities. In addition, we deployed the chatbot on Heroku and integrated it with Facebook's Messenger Platform. However, the code is quite modularized and can be used with any platform, whether it's a chat box on BestFriends.org or SMS.
Challenges we ran into
We ran into quite a few challenges.
Firstly, we wanted to keep Best Friend's primary objectives in mind. From our chats with the Best Friends team, we realized that a significant issue was maximizing engagement. We spent several hours the first day discussing ways to design the user flow with this goal in mind. For instance, in the case when a user prefers a specific breed but none are up for adoption, we wouldn't want to lose them as a potential adopter, volunteer, or donor. Therefore, we implemented a mechanism to intelligently suggest calls to action - perhaps suggesting a user to subscribe to Best Friend's mailing list or adopt another pet if their choice of breed isn't available.
Also important were the challenges involved in dealing with natural language. This is a cutting-edge field and we wanted our bot to go beyond coding some simple simple rules and constraining users to sending only simple messages in some required format. Though we didn't have the time to integrate anything fancy like a full-fledged machine learning model for natural language processing (which is the state of the art), we've implemented some interesting capabilities such as fuzzy matching and stemming to allow for AdoptBot to understand a robust range of user messages.
Finally, another big challenge that we continually ran into was maintaining our sanity. By that we mean sanity of the code. As we found out, it is ridiculously easy for chatbot code to devolve into a mess of if/else statements. Furthermore, we wanted conversations to be natural rather than one-shot; by this we mean that conversations could develop over the course of multiple messages, rather than each message being considered and responded to individually without consideration to chat history. And, with the added complexity of having to maintain individual states for each user and handle multiple conversations at the same time, we really needed to figure out a way to maintain the state of all the chats. Our solution to this was a sort of finite state machine, which allowed us to elegantly maintain complex conversations and modularize the code.
Accomplishments that we're proud of
This was Cindy and Noah's first time building a chatbot, and one of Cindy's first projects using Python. We're proud that everyone got to pitch into all phases of the process - ideation, design, implementation, and branding - to make a working prototype.
Our demo conversations were scripted, but we're proud that the chatbot is very robust and can truly handle a complex conversation, presenting the user with useful information and hopefully supporting Best Friends' goal to save them all!
What's next for AdoptBot
There's a lot to improve upon but we think that our prototype has stubbed out a good framework to start with. The codebase is structured so that new capabilities can be easily added. Here's just a few ideas we have:
- A lot more integrations could be added with Best Friends' existing infrastructure. For instance, in our prototype we couldn't actually link up with the mailing list. However, we envision the bot being able to do even more things like schedule volunteers at their local partnering shelters or walk users through all steps of the adoption process.
- Facebook's platform allows more complex message types. For instance, Facebook Pay could be easily integrated to solicit donations in-app.
- We could incorporate novel natural language processing capabilities using machine learning. These are becoming more and more practical as time goes on and will reduce the need for "rules" and "paths" to be explicitly defined.
(Note: AdoptBot is waiting for Facebook approval to go live, so only developers can speak to it right now.)