Build a Book Recommendation SMS Bot

June 22, 2020
Written by
Liz Moy
Twilion
Reviewed by
Diane Phan
Twilion

Build a book recommendation bot with Programmable SMS

On June 14, publisher Amistad Books launched an initiative to encourage people to purchase any two books by Black writers between June 13th – June 20th.

In addition, artists such as Noname have launched book clubs and dialogue to support Black voices in written works from anti-racist texts, to poetry, to science fiction and fantasy.

To help folks decide on something to read, I built a simple book recommendation bot using Programmable SMS with Python and Airtable to store the book data. The result is a guided conversation that allows the texter to choose a genre they want to read, and responds with a title of a book and a link to a Black-owned bookstore in the U.S. that has the book for sale, either in print,e-book, or audio book.

Try it by sending a text to (409) 404-0403. You can also see the Python code below and an example of the Airtable base that I used.

import os
from airtable import Airtable
from flask import Flask, request, session
from twilio.twiml.messaging_response import MessagingResponse

app = Flask(__name__)
app.config['SECRET_KEY'] = os.environ.get('FLASK_SECRET_KEY')

# This is required to read/write from AirTable base (GET/POST)
AIRTABLE_BASE_ID = os.environ.get("AIRTABLE_BASE_ID")

@app.route('/send-rec', methods=['POST'])
def send_rec():
   """
   a function that sends the SMS message
   """
   incoming_msg = request.values.get('Body', 'message error').lower()
      
   if not 'sms_count' in session:
       session['sms_count'] = 0
       session["1"] = get_authors("1")
      
   sms_count = session['sms_count']
    if sms_count == 0:
        sms_message = "Want a recommendation for a Black-authored book? Respond with the 
                                    number that corresponds with the genre you want:\n1 for Anti-racism 📕"
   else:
       try:
           book_dict = session[str(incoming_msg)]
           book_id_choice = next(iter(book_dict))

            # send back nicely formatted title, author, and book
sms_message = "{title} by {author}\nBuy it here: {link}\n\nGet another               
recommendation!\n1. Anti-racism 📕").format(
                                                       title = book_dict[book_id_choice]['book_title'],
                                                       author = book_dict[book_id_choice]['book_author'],
                                                       link = book_dict[book_id_choice]['book_link'])

           # delete that item from the dictionary
           del session[str(incoming_msg)][book_id_choice]
       except:
           # if there are no options left for this genre, let them know
           sms_message = "That's every book we have in that genre.\nTry another one.\n1.
Anti-racism 📕"

   session['sms_count'] += 1
   resp = MessagingResponse()
   msg = resp.message()
   msg.body(sms_message)

   return str(resp)

def get_authors(genre):
   """
   a function that gets the book data from airtable
   """
   airtable = Airtable(AIRTABLE_BASE_ID, genre)
   authors = {}

   for page in airtable.get_iter(view='books'):
       for record in page:
           fields = record['fields']
           authors[fields['ID']] = {'book_title' : fields['Title'],
                                    'book_author': fields['Author'],
                                    'book_link': fields['Link']}

   return authors

It always amazes me how versatile a Programmable SMS or WhatsApp chatbot can be. If you’ve spun up anything cool with these tools lately, tell us about it in the comments or send me an email at lmoy [at] twilio [dot] com.