En este tutorial, aprenderás todo lo que necesitas saber para crear tu primera experiencia en Messenger. Primero, elige una de las opciones que aparecen en Proyecto iniciales para obtener el código que necesitarás para empezar. A continuación, sigue las indicaciones de Primeros pasos para realizar la configuración.
¿Solo quieres ver el código finalizado? No hay problema. Puedes bifurcarlo en GitHub.Para poder comenzar con este inicio rápido, debes haber completado una de las siguientes opciones para garantizar que tienes el código de inicio necesario. El código de inicio proporciona un webhook básico que servirá de base de la experiencia en Messenger.
En nuestra guía de configuración de webhooks, te mostramos cómo crear el primer webhook, que puedes usar con este inicio rápido de principio a fin.
Crear un webhookDescarga el código de inicio del webhook de GitHub e impleméntalo en el servidor que prefieras.
Descargar el códigoSi no cuentas con un servidor en el que puedas implementar el webhook, puedes remixar nuestro proyecto inicial de webhook en Glitch, que te proporcionará una URL pública que se ofrece a través de HTTPS del webhook.
Para crear tu propio webhook en Glitch, realiza los siguientes pasos:
/webhook
:
https://
Para crear tu primera experiencia en Messenger, debes configurar las credenciales de la app.
Si todavía no lo hiciste, sigue la guía de configuración de apps para configurar la app de Facebook y usarla con la plataforma de Messenger.
Hasta que la app se envíe y se apruebe para uso público en Messenger, los tokens de la página solo permiten que esta interactúe con las cuentas de Facebook que tengan el rol de administrador, desarrollador o evaluador de la app.
Para otorgar estos roles a otras cuentas de Facebook, ve a la pestaña "Roles" de la configuración de la app.
Para autenticar las solicitudes a las API de la plataforma de Messenger, se incluye un token de acceso en el nivel de la página en el parámetro access_token
de la cadena de consulta.
Si todavía no generaste un token de acceso a la página, hazlo cuando configures la app de Facebook de la siguiente manera:
Se recomienda proteger la información confidencial, como el token de acceso a la página, y no codificar los valores en el webhook.
Para eso, agrega lo siguiente a las variables del entorno, donde <PAGE_ACCESS_TOKEN>
es el token de acceso que acabas de generar y <VERIFY_TOKEN>
es una cadena aleatoria que configuraste para verificar el webhook:
PAGE_ACCESS_TOKEN="
Si usas Glitch, configura las variables del entorno en el archivo .env
correspondiente para asegurarte de que no puedan verlas otros usuarios de Glitch.
Ahora, solo te falta agregar el token de acceso a la página y verificarlo en la parte superior del archivo app.js
para usarlo en la lógica de tu webhook:
const PAGE_ACCESS_TOKEN = process.env.PAGE_ACCESS_TOKEN;
const VERIFY_TOKEN = process.env.VERIFY_TOKEN;
En este tutorial, se creará una experiencia en Messenger simple que realiza lo siguiente:
Analiza el mensaje y el identificador de usuario específico de la página del remitente a partir de un evento de webhook entrante.
Identifica los eventos de webhook messages
y messaging_postbacks
.
Envía mensajes mediante la API de envío.
Responde los mensajes de texto con un mensaje de texto.
Responde un archivo adjunto de imagen con una plantilla genérica que usa la imagen recibida.
Responde de manera condicional una caga del postback.
Para empezar, se crearán códigos auxiliares de tres funciones que identificarán los tipos de eventos de webhook entrantes que se quieren admitir, además de responder mediante la API de envío. Para eso, agrega lo siguiente a tu archivo app.js
:
// Handles messages events
function handleMessage(sender_psid, received_message) {
}
// Handles messaging_postbacks events
function handlePostback(sender_psid, received_postback) {
}
// Sends response messages via the Send API
function callSendAPI(sender_psid, response) {
}
Para responder a las personas en Messenger, primero hay que saber quiénes son. En Messenger, para saberlo se obtiene el identificador de usuario específico de la página (PSID) del remitente del mensaje a partir del evento de webhook entrante.
A una persona se le asigna un identificador de usuario específico de la página (PSID) único, correspondiente a cada página de Facebook con la que inicia una conversación. El PSID se usa para identificar a una persona cuando se envían mensajes.
Si completaste una de las opciones de la sección Proyecto inicial mencionada antes, debes tener un punto de conexión básico /webhook
que acepte solicitudes POST
y registre el cuerpo de los eventos de webhook recibidos, que se ve de la siguiente manera:
app.post('/webhook', (req, res) => {
// Parse the request body from the POST
let body = req.body;
// Check the webhook event is from a Page subscription
if (body.object === 'page') {
// Iterate over each entry - there may be multiple if batched
body.entry.forEach(function(entry) {
// Get the webhook event. entry.messaging is an array, but
// will only ever contain one event, so we get index 0
let webhook_event = entry.messaging[0];
console.log(webhook_event);
});
// Return a '200 OK' response to all events
res.status(200).send('EVENT_RECEIVED');
} else {
// Return a '404 Not Found' if event is not from a page subscription
res.sendStatus(404);
}
});
Para obtener el PSID del remitente, actualiza el bloque body.entry.forEach
con el siguiente código para extraer el PSID de la propiedad del evento sender.id
:
body.entry.forEach(function(entry) {
// Gets the body of the webhook event
let webhook_event = entry.messaging[0];
console.log(webhook_event);
// Get the sender PSID
let sender_psid = webhook_event.sender.id;
console.log('Sender PSID: ' + sender_psid);
});
Sender PSID: 1254938275682919
Se busca que la experiencia identifique dos tipos de eventos de webhook: messages
y messaging_postback
. El nombre del tipo de evento no se incluye en el cuerpo del evento, pero para determinarlo se pueden verificar ciertas propiedades del objeto.
La plataforma de Messenger envía eventos de webhook para notificarte sobre las acciones que ocurren en Messenger. Los eventos se envían en formato JSON como solicitudes POST
a tu webhook. Para obtener más información, consulta Eventos de webhook.
Para eso, actualiza el bloque body.entry.forEach
de tu webhook con una condición que verifique si el evento recibido contiene una propiedad message
o postback
. También se agregarán llamadas a las funciones handleMessage()
y handlePostback()
de las cuales se crearon códigos auxiliares antes:
body.entry.forEach(function(entry) {
// Gets the body of the webhook event
let webhook_event = entry.messaging[0];
console.log(webhook_event);
// Get the sender PSID
let sender_psid = webhook_event.sender.id;
console.log('Sender PSID: ' + sender_psid);
// Check if the event is a message or postback and
// pass the event to the appropriate handler function
if (webhook_event.message) {
handleMessage(sender_psid, webhook_event.message);
} else if (webhook_event.postback) {
handlePostback(sender_psid, webhook_event.postback);
}
});
Ahora que los mensajes entrantes se envían a la función de identificador correspondiente, se actualizará handleMessage()
para identificar y responder los mensajes de texto. Para eso, actualiza el código a fin de definir la carga de mensaje de la respuesta y luego pasa esa carga a callSendAPI()
. Para responder con un mensaje de texto básico, se define un objeto JSON con una propiedad "text"
:
function handleMessage(sender_psid, received_message) {
let response;
// Check if the message contains text
if (received_message.text) {
// Create the payload for a basic text message
response = {
"text": `You sent the message: "${received_message.text}". Now send me an image!`
}
}
// Sends the response message
callSendAPI(sender_psid, response);
}
Es hora de enviar el primer mensaje con la API de envío de la plataforma de Messenger.
En handleMessage()
, llamamos a callSendAPI()
, por lo tanto, debemos actualizarla para construir el cuerpo de la solicitud completo y enviarla a la plataforma de Messenger. Una solicitud a la API de envío tiene dos propiedades:
recipient
: configura el destinatario esperado del mensaje. En este caso, se identifica a la persona por el PSID.message
: configura los detalles del mensaje que se debe enviar. En este caso, se lo configurará en el objeto del mensaje pasado a partir de la función handleMessage()
.Para construir el cuerpo de la solicitud, actualiza el código auxiliar de callSendAPI()
de la siguiente manera:
function callSendAPI(sender_psid, response) {
// Construct the message body
let request_body = {
"recipient": {
"id": sender_psid
},
"message": response
}
}
Ahora, para enviar el mensaje solo hay que enviar una solicitud POST
a la API de envío en https://graph.facebook.com/v2.6/me/messages
.
Ten en cuenta que debes agregar el PAGE_ACCESS_TOKEN
al parámetro access_token
de la URL de la cadena de la consulta.
En este inicio rápido, se utiliza el módulo de la solicitud Node.js para devolver las solicitudes HTTP a la plataforma de Messenger, pero puedes utilizar el cliente HTTP que quieras.
Para instalar el módulo de la solicitud, ejecuta npm install request --save
desde la línea de comandos y luego, para importarlo, agrega lo siguiente en la parte superior de app.js
:
const request = require('request');
function callSendAPI(sender_psid, response) {
// Construct the message body
let request_body = {
"recipient": {
"id": sender_psid
},
"message": response
}
// Send the HTTP request to the Messenger Platform
request({
"uri": "https://graph.facebook.com/v2.6/me/messages",
"qs": { "access_token": process.env.PAGE_ACCESS_TOKEN },
"method": "POST",
"json": request_body
}, (err, res, body) => {
if (!err) {
console.log('message sent!')
} else {
console.error("Unable to send message:" + err);
}
});
}
Dado que la respuesta sugiere al destinatario del mensaje que envíe una imagen, el siguiente paso es actualizar el código para procesar un archivo adjunto. La plataforma de Messenger guarda automáticamente los archivos adjuntos enviados, a los que se puede acceder mediante una URL en la propiedad payload.url
de cada índice de la matriz attachments
; por lo tanto, también se extraerán del evento.
Para determinar si el mensaje es un archivo adjunto, actualiza la condición de la función handleMessage()
a fin de verificar el received_message
de una propiedad attachments
y luego extrae la URL. En un bot real, se repetiría la matriz para verificar varios archivos adjuntos, pero a los fines de este inicio rápido, solo se hará con el primero.
function handleMessage(sender_psid, received_message) {
let response;
// Checks if the message contains text
if (received_message.text) {
// Creates the payload for a basic text message, which
// will be added to the body of our request to the Send API
response = {
"text": `You sent the message: "${received_message.text}". Now send me an attachment!`
}
} else if (received_message.attachments) {
// Gets the URL of the message attachment
let attachment_url = received_message.attachments[0].payload.url;
}
// Sends the response message
callSendAPI(sender_psid, response);
}
A continuación, responderemos a la imagen con una plantilla de mensajes genérica. La plantilla genérica es el tipo de mensaje estructurado más usado y permite enviar una imagen, un texto y botones en un mensaje.
Sí. La plataforma de Messenger proporciona un conjunto de plantillas de mensajes útiles, cada una diseñada para admitir una estructura de mensajes diferente y común, incluidos recibos, listas y botones. Para obtener información completa, consulta Plantillas.
Las plantillas de mensajes se definen en la propiedad attachment
del mensaje, que contiene las propiedades type
y payload
. En payload
, se configuran los detalles de la plantilla genérica de las siguientes propiedades:
template_type
: configura el tipo de plantilla que se usa en los mensajes. Como se está usando la plantilla genérica, el valor es "generic".elements
: configura las propiedades personalizadas de la plantilla. En el caso de la plantilla genérica, se especificará un título, un subtítulo, una imagen y dos botones de postback.En el caso de los mensajes estructurados, se utilizará el attachment_url
enviado como image_url
para mostrar en la plantilla y se incluirá un par de botones de postback para permitir que el destinatario del mensaje responda. Para construir la carga del mensaje y enviar la plantilla genérica, actualiza handleMessage()
de la siguiente manera:
function handleMessage(sender_psid, received_message) {
let response;
// Checks if the message contains text
if (received_message.text) {
// Create the payload for a basic text message, which
// will be added to the body of our request to the Send API
response = {
"text": `You sent the message: "${received_message.text}". Now send me an attachment!`
}
} else if (received_message.attachments) {
// Get the URL of the message attachment
let attachment_url = received_message.attachments[0].payload.url;
response = {
"attachment": {
"type": "template",
"payload": {
"template_type": "generic",
"elements": [{
"title": "Is this the right picture?",
"subtitle": "Tap a button to answer.",
"image_url": attachment_url,
"buttons": [
{
"type": "postback",
"title": "Yes!",
"payload": "yes",
},
{
"type": "postback",
"title": "No!",
"payload": "no",
}
],
}]
}
}
}
}
// Send the response message
callSendAPI(sender_psid, response);
}
El último paso consiste en identificar el evento de webhook messaging_postbacks
que se enviará cuando el destinatario del mensaje toque uno de los botones de postback que aparecen en la plantilla genérica.
El botón de postback envía un evento de webhook messaging_postbacks
a tu webhook, en el que se incluye una cadena personalizada de hasta 1.000 caracteres en la propiedad payload
. Te permite implementar fácilmente diferentes cargas de postback que puedes analizar y a las que puedes responder con comportamientos específicos.
Dado que la plantilla genérica permite que el destinatario del mensaje elija entre dos botones de postback, la respuesta dependerá del valor de la propiedad payload
del evento de postback. Para ello, actualiza el código auxiliar handlePostback()
de la siguiente manera:
function handlePostback(sender_psid, received_postback) {
let response;
// Get the payload for the postback
let payload = received_postback.payload;
// Set the response based on the postback payload
if (payload === 'yes') {
response = { "text": "Thanks!" }
} else if (payload === 'no') {
response = { "text": "Oops, try sending another image." }
}
// Send the message to acknowledge the postback
callSendAPI(sender_psid, response);
}