Cómo crear un Bot para Facebook Messenger con Node JS
En esta página:
Github
Los Bots de Facebook Messenger son herramientas interesantes para hacer Feedbacks, Ventas, etc. más ágiles desde Facebook. Puedes hacer que realice infinidad de funciones, pensar que puede interactuar con otros servicios como Google Maps, Instagram, WordPress, Prestashop, etc. nos damos cuenta del potencial de esta utilidad si sabemos sacarle el máximo provecho. En esta ocasión voy a enseñarles a crear un Bot para Facebook Messenger con Node JS y el deployment lo haré en el servidor Heroku con una cuenta gratuita.
Los pasos que llevaré a cabo son los siguientes:
- Porque usar Heroku?
- Deployment en Heroku (Configuración de nuestro servidor para alojar el Bot)
- Programando las Funcionalidades del Bot.
- Porque usar un servidor con Certificado SSL?
- Configurando la app en Facebook Developer.
- Testeando mi Bot.
Mi Bot va tener 5 característcas que servirán para que el usuario pueda interactuar sin problemas con el Bot:
- mensaje automático : Este no es un comando, es un mensaje que se muestra cuando el usuario escribe cualquier texto en el chat.
- ‘busca blog’
- ‘sobre platzi’
- ‘testimonios’
- ‘ayuda’
Estas características mencionadas las detallaré más adelante en el paso Programando las Funcionalidades del Bot, primero vamos con el tutorial:
Porque usar Heroku ?
Esta plataforma nos ofrece una cuenta gratuita para hacer nuestras pruebas, si bien esta cuenta tiene limitaciones, podemos escalarla y agregarle mas especificaciones y mejoras para obtener un mejor rendimiento y persistencia. Ademas tiene mucha compatibilidad con Node JS que es la tecnología ideal para hacer funcionar nuestro Bot, por la respuesta en tiempo real que nos brinda. Algo muy importante tambien es que Heroku nos da un certificado SSL el cual es un requerimiento obligatorio de la plataforma Facebook Developers para poder alojar nuestro Bot.
Deployment en Heroku (Configuración de nuestro servidor para alojar el Bot)
Hacemos el despliegue y configuración de nuestro servidor. Para este tutorial yo voy a usar un servidor gratuito en Heroku. Primero nos creamos una cuenta en heroku.com e iniciamos sesión con nuestro usuario y contraseña.
Una vez dentro creamos una nueva app, dejamos en blanco el nombre ya que el sistema free le asigna uno por default, seleccionamos la región y le damos en Create App.
El sistema me creó mi app con el nombre pure-woodland-19018. Ahora instala Heroku Toolbet y configúralo para que puedas trabajar con Heroku en tu consola de Comandos.
Por default Heroku nos crea un repositorio al cual podemos hacer Pull y Push ejecutando comandos Git en nuestra consola de comandos:
1 2 3 4 5 6 7 8 9 10 11 12 |
// Clonamos el repositorio $ heroku git:clone -a pure-woodland-19018 // Accedemos al repositorio descargado $ cd pure-woodland-19018 // Publicamos los cambios en Heroku $ git add . $ git commit -m"Cambios" $ git push |
Dentro de la pestaña Deploy de tu app en Heroku también tienes los comandos y pasos mencionados anteriormente:
Nota: Si es la primera vez que despliegas en Heroku debes configurar tu SSH Key y demás datos privados para que puedas ejecutar sin problemas los comandos mencionados anteriormente – puedes consultar la documentación oficial para más detalles.
Ejecutado el comando anterior para clonar el repositorio de nuestra app nos descarga un directorio, el cual tiene el nombre de tu app. Mi directorio se llama pure-woodland-19018 y dentro de este directorio encontraremos la estructura o esqueleto que Heroku nos pide obligatoriamente para que nuestra aplicación en Node JS funcione sin problemas en sus servidores.
Programando las Funcionalidades del Bot
Ahora vamos a darle vida a nuestro bot, con las funcionalidades necesarias para que el usuario interactúe con el dentro de la ventana del chat. Voy hacer que mi bot tenga las siguiente funciones:
- Cuando el usuario escriba cualquier texto el bot le mostrará una ayuda.
- Buscar artículos en el blog de Platzi (El usuario podrá buscar artículos sobre Android, Javascript, PHP, UX, Python, Ruby, etc)
- Sobre Platzi (El usuario podrá obtener una información que define lo que es Platzi)
- Testimonios (El usuario podrá ver una lista horizontal de Wildcards con las Historias de los Estudiantes de Platzi)
- Ayuda. (El usuario podrá ver una lista de comandos para poder guiarse)
Para este bot vamos a usar Node JS por ser un lenguaje de respuesta en tiempo real y muy dinámico. Creamos un archivo llamado index.js y colocamos el código abajo, dentro del cual también explico para qué sirve cada función.
Voy a indicarles las acciones mas importantes que hace cada linea de nuestro código:
Nota: Si te queda complicado al final del artículo encontrarás un link al repositorio GitHub con el código completo.
Instancio mis variables y hago la configuración requerida así mismo configuro el puerto para correr nuestra APP:
1 2 3 4 5 6 7 8 9 10 |
var express = require('express'); var bodyParser = require('body-parser'); var request = require('request'); var app = express(); app.use(bodyParser.urlencoded({extended: false})); app.use(bodyParser.json()); app.listen((process.env.PORT || 8080)); // Indispensable colocar el puerto 8080 para correr la aplicación en heroku |
Imprimo un texto en el home de mi servidor Heroku para comprobar si mi deployment se hizo correctamente y también si es que el Token de seguridad es inválido:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
app.get('/', function (req, res) { res.send('Hola soy un Bot de Facebook Messenger :)'); }); // Conecto a mi Facebook Webhook app.get('/webhook', function (req, res) { if (req.query['hub.verify_token'] === 'testbot_verify_token') { res.send(req.query['hub.challenge']); } else { res.send('Token de seguridad inválido'); } }); |
Le muestro un mensaje de ayuda para usar el Bot, si el usuario hace enter en el chat sin saber que hacer le ofrecemos una guía de como usar el Bot:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
app.post('/webhook', function (req, res) { var events = req.body.entry[0].messaging; for (i = 0; i < events.length; i++) { var event = events[i]; if (event.message && event.message.text) { if(introResponse(event.sender.id, event.message.text)) { res.sendStatus(200); } else if(newResponselnk(event.sender.id, event.message.text)) { res.sendStatus(200); } else if(newResponse(event.sender.id, event.message.text)) { res.sendStatus(200); } else { //Si el usuario escribe un mensaje le muestro una guía de uso del bot sendMessage(event.sender.id, {text: "Por favor escribe el comando 'ayuda' (sin las comillas), para Ver los Comandos disponibles."}); } } } res.sendStatus(200); }); |
Defino las comandos que puede usar el usuario dentro del Messenger para el comando ‘busca blog’ , ejemplo: ‘buscar blog javascript’, ‘buscar blog ruby’ , etc:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
function newResponselnk(recipientId, text) { text = text || ""; var buscar = text.match(/buscar/gi); var ux = text.match(/ux/gi); var blog = text.match(/blog/gi); var php = text.match(/php/gi); var android = text.match(/android/gi); var javascript = text.match(/javascript/gi); var python = text.match(/python/gi); var ruby = text.match(/ruby/gi); if(buscar != null && blog != null) { var query = ""; //sendMessage(recipientId, message); if(android != null) { query = "Android"; } else if (javascript != null) { query = "Javascript"; } else if (php != null) { query = "PHP"; } else if (ux != null) { query = "UX"; } else if (python != null) { query = "Python"; } else if (ruby != null) { query = "Ruby"; } sendButtonMessagelnk(recipientId, query); return true } return false; }; |
Muestro un botón que es un link al blog de Platzi con los resultados obtenidos luego de haber ejecutado el comando ‘buscar blog javascript’, ‘buscar blog ruby’, etc.:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
function sendButtonMessagelnk(recipientId, query) { var messageData = { recipient: { id: recipientId }, message: { attachment: { type: "template", payload: { template_type: "button", text: "Resultados de "+query+":", buttons:[{ type: "web_url", url: "https://platzi.com/blog/?s="+query, title: "Platzi: " + query }] } } } }; callSendAPI(messageData); } |
Valido la conexión a la Graph API de Facebook para el envío y recepción de mensajes:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
function callSendAPI(messageData) { request({ uri: 'https://graph.facebook.com/v2.6/me/messages', qs: { access_token: process.env.PAGE_ACCESS_TOKEN }, method: 'POST', json: messageData }, function (error, response, body) { if (!error && response.statusCode == 200) { var recipientId = body.recipient_id; var messageId = body.message_id; console.log("Se ha enviado el mensaje generado con id %s a %s", messageId, recipientId); } else { console.error("No se puede enviar mensajes."); console.error(response); console.error(error); } }); } |
Defino las respuestas para el comando ‘sobre platzi’ y tambien para el comando ‘ayuda’:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
function introResponse(recipientId, text) { text = text || ""; var sobre = text.match(/sobre/gi); var platzi = text.match(/platzi/gi); var ayuda = text.match(/ayuda/gi); if(sobre != null && platzi != null) { message = { text: "Platzi es la mejor plataforma de habla hispana con cursos profesionales de desarrollo web y de apps, marketing online, diseño de interfaces, servidores. Con clases en vivo y profesores sabios de la industria. Bienvenido :)" } sendMessage(recipientId, message); return true; } if(ayuda != null) { message = { text: "Platzi Bot Ver. 1.0 "+ "\n" +" Comandos disponibles: "+ "\n" +" 1)Buscar blog Javascript, etc.(Puedes buscar Android, Javascript, PHP, UX, Python, Ruby) "+ "\n" +" 2)Sobre Platzi. "+ "\n" +" 3)Testimonios. "+ "\n" +" 4)Ayuda." } sendMessage(recipientId, message); return true; } return false; }; |
Defino y valido el comando ‘testimonios’:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
function newResponse(recipientId, text) { text = text || ""; var testimonios = text.match(/testimonios/gi); if(testimonios != null) { var query = ""; //sendMessage(recipientId, message); if(testimonios != null) { query = "Historias"; } sendButtonMessage(recipientId, query); return true } return false; }; |
Muestro los wildcards con los ‘testimonios’, son una tira de tarjetas informativas dentro del Chat Facebook Messenger:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
function sendButtonMessage(recipientId, query) { var messageData = { recipient: { id: recipientId }, message: { attachment: { type: "template", "payload": { "template_type": "generic", "elements": [{ "title": "La Receta para mantenerse actualizado.", "subtitle": "Es increíble cómo la formación profesional técnica puede motivarte a participar y aportar en el proceso de...", "image_url": "https://static.platzi.com/static/stories/images/gollum-card.3cbc54914d6f.png", "buttons": [{ "type": "web_url", "url": "https://platzi.com/historias/la-receta-para-mantenerse-actualizado/", "title": "Leer más (+)" }, { "type": "web_url", "url": "platzi.com/historias", "title": "Ver más Historias..." }], }, { "title": "Platzi me ayudó a crecer y a aprender más de lo que ya sabía.", "subtitle": "Soy Vicky O’Shee de Argentina, trabajo como emprendedora digital ahora radicada en Medellín, Colombia...", "image_url": "https://static.platzi.com/static/stories/images/victoria-card.98c35c8ac6af.jpg", "buttons": [{ "type": "web_url", "url": "https://platzi.com/historias/me-ayudo-a-crecer-y-a-aprender-mas-de-lo-que-ya-sabia/", "title": "Leer más (+)" }, { "type": "web_url", "url": "platzi.com/historias", "title": "Ver más Historias..." }], }] } } } }; callSendAPI(messageData); } |
Muestro un mensaje si hay un error enviado los mensajes:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
function sendMessage(recipientId, message) { request({ url: 'https://graph.facebook.com/v2.6/me/messages', qs: {access_token: process.env.PAGE_ACCESS_TOKEN}, method: 'POST', json: { recipient: {id: recipientId}, message: message, } }, function(error, response, body) { if (error) { console.log('Error enviando el Mensaje: ', error); } else if (response.body.error) { console.log('Error: ', response.body.error); } }); }; |
“Terminado nuestro código, procedemos a subirlo a Heroku”
Nota: Debemos crear el Archivo Procfile para que nuestra aplicación se inicie automáticamente:
1 2 3 4 5 6 7 8 |
// Creamos el archivo Procfile $ >Procfile // Abrimos el archivo Procfile que creamos y colocamos el siguiente contenido web: node index.js |
Ahora publicamos los cambios en Heroku:
1 2 3 4 5 6 |
// Publicamos los cambios en Heroku con comandos conocidos Git $ git add . $ git commit -m"Cambios" $ git push |
Para comprobar si nuestro servidor está trabajando sin problemas abrimos nuestra app en Heroku:
Nos debe mostrar el mensaje que declaramos al inicio de nuestro código:
1 2 3 4 5 6 |
// Imprimo un texto en la home de mi servidor Heroku para comprobar si mi deployment se hizo correctamente app.get('/', function (req, res) { res.send('Hola soy un Bot de Facebook Messenger :)'); }); |
Es decir nos debe mostrar el mensaje: Hola soy un Bot de Facebook Messenger 🙂
Es importante que la URL de nuestra aplicación en Heroku cargue sin problemas, ya que cuando configuremos nuestra aplicación en Facebook, hará pedidos de respuesta al servidor para validar el servidor HTTP Seguro.
Porque usar un servidor con Certificado SSL?
Un certificado SSL (Secure Socket Layer) o Capa de Conexión Seguridad de por si es la mejor opción para darle seguridad a tus datos y la de tus usuarios.
Un servidor con Certificado SSL es muy considerado por los diferentes servicios que existen en Internet entre ellos Facebook Developers que nos pide si o si tener un Certificado SSL para publicar nuestro Bot
Un proyecto creado con un simple servidor sin certificado SSL muchas veces es fácil de usar para crear Suplantación de identidad (Pishing), Descargar Malware y muchas categorías de Virus que vulneran la seguridad del usuario, etc. Por eso se decidió darle una capa de seguridad a nuestros proyectos y una manera de diferenciar a los malos de los buenos, a continuación les mostrare cuando una servidor tiene certificado SSL y cuando no, por ejemplo tenemos los siguientes dominios:
https://www.midominio.com (Sin Certificado SSL)
https://www.midominio.com (Con certificado SSL)
Si vemos bien podemos saber que un proyecto con certificado SSL es cuando al inicio de la url en su navegador tiene https, esto significa: Hypertext Transfer Protocol Secure (Protocolo seguro de transferencia de hipertexto)
Para este tutorial use Heroku que ya nos brinda el certificado SSL de Manera gratuita, pero si decides usar otro Proovedor, necesitas comprarle o ver si viene con Certificado SSL.
Configurando la app en Facebook Developer
Vamos a crear una aplicación para Web, para ello nos dirigimos a Facebook Developers y agregamos una nueva aplicación:
Una vez que terminamos de configurar nuestra aplicación regresamos a la página principal de Facebook Developers y de paso recargamos la página, desplegamos la lista de nuestras aplicaciones y hacemos click en la aplicación que hemos creado:
Cuando estemos en la página de configuración de nuestra aplicación, nos dirigimos a la opción Messenger en el menú de opciones del lado izquierdo:
Para algunos les debe cargar la nueva versión de la página para configurar nuestra aplicación.
Sea cual sea la versión que tengamos en pantalla, debemos seleccionar el Fanpage en donde nuestro bot va a trabajar e interactuar con los usuarios que nos escriban mensajes. Para mi caso seleccionaré el Fanpage “Bot Messenger Chat Platzi”. Podemos ver que nos genera un token de acceso a la página, y lo copiamos.
Luego nos dirigimos a Webhooks.
Los Webhooks nos sirven para enviar y recibir respuestas desde nuestro servidor a nuestra aplicación y consecuentemente la interacción con el usuario.
Como nuestra aplicación está alojada en Heroku, el servidor cuenta con Certificado SSL. Copiamos y pegamos la URL de nuestra aplicación alojada en Heroku ya que es allí en donde está nuestro código con las funciones que nuestro bot debe realizar. Pegamos el token generado anteriormente y marcamos las 4 casillas: message_deliveries, messages, messaging_optins y messaging_postbacks y le damos click en Verificar y guardar. Si todo está bien nos aparecerá un checkbox verde de aprobado.
Ahora abrimos nuestra ventana de comandos (Puede ser Git Bash u otra) y ejecutamos lo siguiente para suscribir nuestra app a la página de aplicaciones de Facebook.
1 2 3 |
curl -ik -X POST "https://graph.facebook.com/v2.6/me/subscribed_apps?access_token=MI_TOKEN" |
Donde dice MI_TOKEN escribimos nuestro token generado anteriormente. Presionamos enter en la consola de comandos y nos debe salir true, lo que indica que nuestra app está configurada correctamente.
También tenemos que colocar el TOKEN en Heroku, para eso nos dirigimos a Settings y luego a Configurar Variables:
En la imagen anterior escribimos la variable de seguridad PAGE_ACCESS_TOKEN y a su lado colocamos el token generado automáticamente en Facebook.
Testeando mi Bot
Ahora vamos a probar las funciones que programé para mi bot.
1.- Cuando el usuario escriba cualquier texto, el bot le mostrará una ayuda.
Debemos tener en cuenta que el usuario al ingresar no tiene ni la más mínima idea de qué comandos escribir para poder ver algún tipo de resultado en el chat. Si por ejemplo el usuario escribe hola o cualquier otra palabra que desee, el bot le muestra una guía.
2.- Buscar artículos en el blog de Platzi
Esta función le permite al usuario buscar un contenido determinado en el blog de Platzi; para ello ejecuto el comando buscar blog. Por ejemplo si el usuario escribe buscar blog javascript, el bot muestra un botón que al hacerle click nos envía al blog y nos muestra los resultados de nuestra búsqueda.
3.- Sobre Platzi
Este comando muestra una breve descripción de la empresa con solo escribir el comando sobre platzi.
4.- Testimonios
Para hacerlo más vistoso y vendedor si escribimos el comando testimonios el bot muestra una lista horizontal de Wildcards con las Historias de los Estudiantes de Platzi.
5.- Ayuda
Cuando el usuario escribe el comando ayuda nuestro querido bot le muestra una lista con los comandos disponibles.
Está genial, ¿cierto?
Puedes crear las funciones que desees, también conectar todo a una base de datos como MySQL, Mongo DB, Rethink DB, etc. y tener tu Bot con datos más actualizados y dinámicos.
Para poner el Bot al acceso público se debe tomar en cuenta que tienes que tener un servidor privado potente. De hecho yo no comparto el link de mi Bot porque el servidor Heroku gratuito no soporta muchas conexiones y se puede caer. Lo que sí puedo hacer es dar acceso para que lo prueben, me pueden enviar un mensaje por Twitter para solicitarlo.
También te dejo el código alojado en GitHub para que lo revises con calma o lo incorpores en tu proyecto.
Gracias por tu atención.
- Node JS Tutoriales
- 17-11-2016
- 26-09-2022
- Crear un Post - Eventos Devs - Foro