Cerebro de nuestro bot
Y ahora llegamos a un punto interesante.
¿Cómo sabe el bot qué decir? El cerebro de nuestro bot se corresponde con el archivo bot.py
.
class Bot(object):
def __init__(self, send_callback, users_dao, tree):
self.send_callback = send_callback
self.users_dao = users_dao
self.tree = tree
def handle(self, user_id, user_message, is_admin=False):
# lógica del bot
La clase es inicializada con 3 parámetros:
- una función callback (que ya se ha definido antes) para devolver mensajes a los usuarios,
- un objeto que proporciona el acceso a datos (para guardar el historial de las conversaciones), y
- el árbol que contiene los posibles flujos de conversación (se obtiene a partir del YAML mostrado anteriormente).
Como es de notarse, la clase handle
es la que contiene la lógica principal del bot.
El código anterior sólo muestra un fragmento del método. Pero en resumen aquí:
- Primero registramos el mensaje recibido del usuario, y obtenemos el historial de mensajes intercambiados con dicho usuario, usando nuestra instancia
DAO
(data access object
). - Esto nos permitirá reproducir las acciones del usuario, para descubrir dónde es que nos encontramos según el árbol.
- Se definen un mensaje y unos botones por defecto, que serán devueltos en caso que el usuario diga algo que el bot no entiende.
- Y así mismo se define una variable para determinar si el usuario desea reiniciar la conversación con el bot.
El historial de mensajes es muy importante. Estos mensajes guardan los textos enviados tanto por el usuario como por el bot.
Finalmente, tras recorrer todo el historial, escribimos nuestra respuesta (en un log y en una base de datos propia), y enviamos el mensaje de respuesta al usuario.
La última pieza del rompecabezas
Lo último pero no menos importante es la definición de un data access object
y un modelo que represente a los eventos notificados por Messenger.
Estas clases en conjunto nos permiten gestionar toda la información relacionada con los mensajes intercambiados (considerando 3 actores: usuarios, bot y administrador).
class UserEvent(ndb.Model):
user_id = ndb.StringProperty()
author = ndb.StringProperty()
message = ndb.StringProperty()
date = ndb.DateTimeProperty(auto_now_add=True)
class UserEventsDao(object):
def add_user_event(self, user_id, author, message):
event = UserEvent()
event.user_id = user_id
event.author = author
event.message = message
event.put()
logging.info("Evento registrado: %r", event)
def get_user_events(self, user_id):
events = UserEvent.query(UserEvent.user_id == user_id).order(UserEvent.date)
return [(event.message, event.author) for event in events]
def remove_user_events(self, user_id):
events = UserEvent.query(UserEvent.user_id == user_id)
quantity = events.count()
for event in events:
event.key.delete()
logging.info("Se eliminaron %r eventos", quantity)
def admin_messages_exist(self, user_id):
events = UserEvent.query(UserEvent.user_id == user_id, UserEvent.author == 'admin')
return events.count() > 0
Nuestro DAO hace uso de Google Datastore. Y la API de Python hace que el uso de Datastore sea muy fácil.
En el fragmento anterior:
- Primero creamos una clase modelo
UserEvent
, que especifica los campos y sus tipos. En nuestro caso, el user ID, el autor del mensaje, y el mensaje mismo sonString
, y finalmente la fecha del evento es de tipoDateTime
. - Para crear y almacenar un nuevo evento de usuario, simplemente instanciamos esta clase, fijamos las propiedades, y llamamos al método
put()
desde el objeto. - Para obtener los eventos de un usuario, llamamos a la función
query()
y usamos como filtro eluser ID
. Aquí ordenamos los eventos por fecha, y devolvemos una lista de tuplas.
Despliegue (deployment del bot)
Hemos dado un vistazo al código que compone nuestro bot! Ahora corresponde realizar el proceso de despliegue, para finalmente conectarlo con Messenger.
Para desplegar nuestra aplicación sobre App Engine, usamos el comando gcloud
que viene con el App Engine SDK:
gcloud app deploy
Una vez realizado el proceso de deployment, la URL de nuestro webhook será:
http://[PROJECT_ID].appspot.com/
Entonces actualizamos nuestra app Facebook con esta URL de webhook y estaremos listos!
Te esperamos en los siguientes artículos en donde hablaremos mas acerca de estos temas que hoy en día son de importancia e interés en el mundo de la tecnología.