En este tutorial, encontrarás información sobre todo lo que necesitas saber para crear tu primera experiencia de Messenger. Antes de empezar, elige una de las opciones que aparecen en Proyecto inicial para obtener el código que necesitarás para empezar y, a continuación, sigue los pasos que se describen en Primeros pasos para definir la configuración.
¿Solo quieres ver el código terminado? Sin problema. Puedes realizar una bifurcación a partir de él en GitHub.Antes de empezar este inicio rápido, asegúrate de haber completado una de las siguientes opciones para garantizar que dispones del código inicial que vas a necesitar. El código inicial proporciona un webhook básico que usaremos como base de la experiencia de Messenger.
En nuestra guía de configuración de webhooks, encontrarás información sobre cómo crear tu primer webhook, que puedes usar con este inicio rápido de principio a fin.
Crear el webhookDescarga nuestro código inicial de webhook de GitHub e impleméntalo en el servidor que prefieras.
Descargar el códigoSi no dispones de un servidor en el que implementar tu webhook, puedes retocar nuestro proyecto inicial de webhook en Glitch, en el que se proporcionará una URL pública para el webhook que se muestra a través de HTTPS.
Para crear tu propio webhook en Glitch, sigue estos pasos:
/webhook
anexado:
https://
Antes de crear tu primera experiencia de Messenger, configura las credenciales de la aplicación.
Si todavía no lo has hecho, sigue nuestra guía de configuración de aplicaciones a fin de configurar tu aplicación de Facebook para poder usarla con la plataforma de Messenger.
Hasta que la aplicación se haya enviado y aprobado para uso público en Messenger, los identificadores de la página solo le permiten interactuar con cuentas de Facebook que hayan obtenido el rol de administrador, desarrollador o evaluador para tu aplicación.
Para conceder estos roles a otras cuentas de Facebook, accede a la pestaña “Roles” de la configuración de la aplicación.
Todas las solicitudes a las API de la plataforma de Messenger se autentican mediante la incorporación de un identificador de acceso de nivel de página en el parámetro access_token
de la cadena de consulta.
Si no lo has hecho al configurar la aplicación de Facebook, genera un identificador de acceso a la página de la siguiente forma:
Para mantener protegida la información confidencial (como el identificador de acceso a la página), te recomendamos que no la codifiques en el webhook.
Para ello, añade el siguiente código a las variables de entorno, donde <PAGE_ACCESS_TOKEN>
es el identificador de acceso que acabas de generar y <VERIFY_TOKEN>
, una cadena aleatoria que defines para verificar el webhook:
PAGE_ACCESS_TOKEN="
Si usas Glitch, define las variables de entorno en el archivo .env
proporcionado para asegurarte de que no estén visibles para otros usuarios de Glitch.
Lo que tienes que hacer en este momento es añadir los identificadores de acceso a la página y de verificación en la parte superior del archivo app.js
para usarlo en la lógica del webhook:
const PAGE_ACCESS_TOKEN = process.env.PAGE_ACCESS_TOKEN;
const VERIFY_TOKEN = process.env.VERIFY_TOKEN;
En este tutorial, crearemos una experiencia sencilla de Messenger que hace lo siguiente:
Analiza el identificador específico de la página del emisor y el mensaje de un evento entrante del webhook.
Gestiona los eventos del webhook messages
y messaging_postbacks
.
Envía mensajes mediante la API de envío.
Responde a mensajes de texto con un mensaje del mismo tipo.
Responde a un archivo de imagen adjunto con una plantilla genérica que usa la imagen recibida.
Responde de forma condicional a la carga útil de un postback.
Para empezar, escribiremos el código auxiliar de tres funciones que controlarán los tipos de eventos entrantes de webhook que queremos admitir y que responderán mediante la API de envío. Para ello, anexa el siguiente código al 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 los usuarios en Messenger, lo primero que necesitamos es saber quiénes son. En Messenger, esto se sabe mediante la obtención del identificador específico de la página (PSID) del emisor del mensaje a partir del evento entrante del webhook.
Un usuario tiene asignado un identificador único específico de la página (PSID) para cada página de Facebook con la que inicia una conversación. El PSID se utiliza para identificar a un usuario al enviar mensajes.
Si has completado una de las opciones de la sección Proyecto inicial anterior, deberías tener un extremo /webhook
básico que acepta solicitudes POST
y registra el cuerpo de los eventos de webhooks recibidos con un aspecto similar al siguiente:
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 emisor, actualiza el bloque body.entry.forEach
con el siguiente código para extraer el PSID de la propiedad sender.id
del evento:
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
Queremos que la experiencia pueda gestionar 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 se pueden comprobar propiedades concretas del objeto para determinarlo.
La plataforma de Messenger envía eventos de webhook para notificarte de acciones que tienen lugar 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 ello, actualiza el bloque body.entry.forEach
del webhook con un condicional que compruebe si el evento recibido contiene una propiedad message
o postback
. También añadiremos llamadas a las funciones handleMessage()
y handlePostback()
cuyo código auxiliar escribimos previamente:
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 dirigen a la función adecuada del controlador, actualizaremos handleMessage()
para gestionar mensajes de texto básicos y responder a ellos. Para ello, actualiza el código a fin de definir la carga útil del mensaje de la respuesta y, a continuación, pasa dicha carga útil a callSendAPI()
. Queremos responder con un mensaje de texto básico, por lo que definimos 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 el momento de enviar tu primer mensaje con la API de envío de la plataforma de Messenger.
En handleMessage()
, llamamos a callSendAPI()
, de modo que ahora es necesario actualizar esta función para construir el cuerpo completo de la solicitud y enviarla a la plataforma de Messenger. Una solicitud a la API de envío tiene dos propiedades:
recipient
: establece el destinatario previsto del mensaje. En este caso, identificamos al usuario mediante su PSID.message
: establece los detalles del mensaje que se va a enviar. Definiremos esta propiedad como el objeto de mensaje que hemos pasado de la función handleMessage()
.Para construir el cuerpo de la solicitud, actualiza el código auxiliar de callSendAPI()
con el siguiente fragmento:
function callSendAPI(sender_psid, response) {
// Construct the message body
let request_body = {
"recipient": {
"id": sender_psid
},
"message": response
}
}
Lo que tenemos que hacer en este momento es enviar el mensaje mediante el envío de una solicitud POST
a la API de envío en https://graph.facebook.com/v2.6/me/messages
.
Ten en cuenta que debes anexar el valor de PAGE_ACCESS_TOKEN
en el parámetro access_token
de la cadena de consulta de URL.
En este inicio rápido, usamos el módulo de solicitud de Node.js para devolver las solicitudes HTTP a la plataforma de Messenger, pero puedes usar el cliente HTTP que quieras.
Para descargar el módulo de solicitud, ejecuta npm install request --save
desde la línea de comandos y, a continuación, añade el siguiente código a la parte superior de app.js
para importarlo:
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);
}
});
}
Como la respuesta le pide al destinatario del mensaje enviar una imagen, el siguiente paso consiste en actualizar el código para que gestione un archivo adjunto. La plataforma de Messenger guarda automáticamente los archivos adjuntos enviados y los pone a disposición de los usuarios mediante una URL en la propiedad payload.url
de cada índice en la matriz attachments
, por lo que también extraeremos esta información del evento.
Para determinar si el mensaje es un archivo adjunto, actualiza el condicional de la función handleMessage()
para que compruebe si hay una propiedad attachments
en received_message
. A continuación, extrae la URL correspondiente. En un bot real, llevaríamos a cabo una iteración en la matriz para comprobar si hay varios archivos adjuntos, pero a efectos de este inicio rápido, simplemente obtendremos el primer archivo adjunto.
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 un mensaje de plantilla genérica. La plantilla genérica es el tipo de mensaje estructurado que se usa con mayor frecuencia y permite enviar una imagen, texto y botones en un mensaje.
Sí. La plataforma de Messenger proporciona un conjunto de plantillas de mensajes útiles, diseñadas para admitir las distintas estructuras de mensajes más habituales, como listas, recibos o botones, entre otras. Para obtener todos los detalles, consulta Plantillas.
Las plantillas de mensajes se definen en la propiedad attachment
del mensaje, que contiene las propiedades type
y payload
. En payload
se establecen los detalles de la plantilla genérica, concretamente en las siguientes propiedades:
template_type
: establece el tipo de plantilla usado para el mensaje. Estamos usando la plantilla genérica, por lo que el valor es “generic”.elements
: establece las propiedades personalizadas de la plantilla. En el caso de la plantilla genérica, especificaremos un título, un subtítulo, una imagen y dos botones de postback.En el caso del mensaje estructurado, usaremos el valor de attachment_url
enviado como image_url
para que se muestre en la plantilla. Además, incluiremos un par de botones de postback para que el destinatario del mensaje pueda responder. Para construir la carga útil del mensaje y enviar la plantilla genérica, actualiza handleMessage()
con el siguiente código:
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 gestionar el evento de webhook messaging_postbacks
que se enviará cuando el destinatario del mensaje toque uno de los botones de postback de la plantilla genérica.
El botón de postback envía un evento de webhook messaging_postbacks
a tu webhook que incluye una cadena personalizada con un máximo de 1000 caracteres en la propiedad payload
. Esto te permite implementar con facilidad diferentes cargas útiles de postback que puedes analizar y a las que puedes responder con comportamientos concretos.
Como la plantilla genérica permite al destinatario del mensaje elegir entre dos botones de postback, responderemos en función del valor de la propiedad payload
del evento de postback. Para ello, actualiza el código auxiliar de handlePostback()
con el siguiente fragmento:
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);
}