La Facebook Messenger API permite a los desarrolladores crear experiencias conversacionales que llegan a más de 1.3 mil millones de usuarios activos mensuales. Ya sea que estés creando un bot de atención al cliente, un asistente de comercio electrónico o una campaña de marketing interactiva, la messenger platform api proporciona las herramientas que necesitas para interactuar con los usuarios en conversaciones significativas.
Esta guía te lleva a través de todo, desde la configuración inicial hasta funciones avanzadas como plantillas de mensajes, respuestas rápidas y el protocolo de transferencia a humanos. Encontrarás ejemplos funcionales en TypeScript a lo largo del documento, listos para adaptar a tus propios proyectos.
Introducción a Messenger Platform
Messenger Platform es el framework de Meta para crear bots e integraciones que se comunican con los usuarios a través de Facebook Messenger. A diferencia de las interfaces web tradicionales, la facebook chat api crea una experiencia conversacional donde los usuarios interactúan mediante mensajes, botones y contenido multimedia enriquecido.

Las capacidades clave de la messenger bot api incluyen:
| Característica | Descripción | Caso de Uso |
|---|---|---|
| Mensajes de Texto | Envío y recepción básica de mensajes | Consultas de clientes, notificaciones |
| Plantillas de Mensajes | Diseños estructurados con imágenes y botones | Catálogos de productos, recibos |
| Respuestas Rápidas | Botones de respuesta sugerida | Conversaciones guiadas, encuestas |
| Menú Persistente | Opciones de navegación siempre disponibles | Navegación del bot, acciones comunes |
| Mensajes Multimedia | Imágenes, videos, audio y archivos | Imágenes de productos, tutoriales |
| Protocolo de Transferencia | Transferencia entre bots y agentes humanos | Escalamiento de soporte complejo |
La plataforma opera con una arquitectura basada en webhooks. Tu servidor recibe mensajes entrantes a través de webhooks, los procesa y responde usando la Send API. Este modelo asíncrono te permite crear experiencias responsivas sin mantener conexiones abiertas.
Configurando Tu Meta App
Antes de poder usar la facebook messenger api, necesitas crear y configurar una Meta App. Este proceso establece la identidad de tu aplicación y otorga acceso a Messenger Platform.
Paso 1: Crear una Meta App
Navega al portal de Meta for Developers y crea una nueva aplicación. Selecciona "Business" como tipo de aplicación, lo cual proporciona acceso a las funciones de Messenger.
// Environment variables you'll need after setup
interface MessengerConfig {
FACEBOOK_APP_ID: string;
FACEBOOK_APP_SECRET: string;
FACEBOOK_PAGE_ID: string;
FACEBOOK_PAGE_ACCESS_TOKEN: string;
MESSENGER_VERIFY_TOKEN: string;
}
// Validate your configuration at startup
function validateConfig(): MessengerConfig {
const required = [
'FACEBOOK_APP_ID',
'FACEBOOK_APP_SECRET',
'FACEBOOK_PAGE_ID',
'FACEBOOK_PAGE_ACCESS_TOKEN',
'MESSENGER_VERIFY_TOKEN'
];
const missing = required.filter(key => !process.env[key]);
if (missing.length > 0) {
throw new Error(`Missing required environment variables: ${missing.join(', ')}`);
}
return {
FACEBOOK_APP_ID: process.env.FACEBOOK_APP_ID!,
FACEBOOK_APP_SECRET: process.env.FACEBOOK_APP_SECRET!,
FACEBOOK_PAGE_ID: process.env.FACEBOOK_PAGE_ID!,
FACEBOOK_PAGE_ACCESS_TOKEN: process.env.FACEBOOK_PAGE_ACCESS_TOKEN!,
MESSENGER_VERIFY_TOKEN: process.env.MESSENGER_VERIFY_TOKEN!
};
}
Paso 2: Agregar el Producto Messenger
En el panel de tu aplicación, haz clic en "Add Product" y selecciona Messenger. Esto habilita las funciones de Messenger Platform para tu aplicación.
Paso 3: Conectar una Página de Facebook
Tu bot necesita una Página de Facebook para enviar y recibir mensajes. En la configuración de Messenger, haz clic en "Add or Remove Pages" y selecciona la página que deseas conectar. Genera un Page Access Token, que usarás para autenticar las solicitudes a la API.
Nota: Los Page Access Tokens pueden ser de corta o larga duración. Para aplicaciones en producción, intercambia tu token por una versión de larga duración que dura aproximadamente 60 días.
interface TokenExchangeResponse {
access_token: string;
token_type: string;
expires_in?: number;
}
async function exchangeForLongLivedToken(
shortLivedToken: string,
appId: string,
appSecret: string
): Promise {
const baseUrl = 'https://graph.facebook.com/v18.0';
const params = new URLSearchParams({
grant_type: 'fb_exchange_token',
client_id: appId,
client_secret: appSecret,
fb_exchange_token: shortLivedToken,
});
const response = await fetch(`${baseUrl}/oauth/access_token?${params.toString()}`);
if (!response.ok) {
const error = await response.text();
throw new Error(`Token exchange failed: ${error}`);
}
const data = await response.json();
if (!data.access_token) {
throw new Error('No access token returned from token exchange');
}
const expiresInDays = data.expires_in
? Math.floor(data.expires_in / 86400)
: 'unknown';
console.log(`Token exchanged successfully (expires in ${expiresInDays} days)`);
return {
access_token: data.access_token,
token_type: data.token_type || 'bearer',
expires_in: data.expires_in,
};
}
Paso 4: Configurar Permisos de la Aplicación
Solicita los permisos necesarios para tu bot. Como mínimo, necesitarás:
pages_messaging: Enviar y recibir mensajespages_manage_metadata: Suscribirse a webhookspages_read_engagement: Acceder a datos de conversación
Configuración y Verificación de Webhooks
Los webhooks son la columna vertebral de la messenger platform api. Permiten que Facebook notifique a tu servidor cuando ocurren eventos, como mensajes entrantes o confirmaciones de entrega.
Configurando Tu Endpoint de Webhook
Crea un endpoint que maneje tanto solicitudes GET (para verificación) como solicitudes POST (para recibir eventos).
import express, { Request, Response } from 'express';
import crypto from 'crypto';
const app = express();
// Parse raw body for signature verification
app.use(express.json({
verify: (req: any, res, buf) => {
req.rawBody = buf;
}
}));
// Webhook verification endpoint
app.get('/webhook', (req: Request, res: Response) => {
const mode = req.query['hub.mode'];
const token = req.query['hub.verify_token'];
const challenge = req.query['hub.challenge'];
const verifyToken = process.env.MESSENGER_VERIFY_TOKEN;
if (mode === 'subscribe' && token === verifyToken) {
console.log('Webhook verified successfully');
res.status(200).send(challenge);
} else {
console.error('Webhook verification failed');
res.sendStatus(403);
}
});
// Webhook event receiver
app.post('/webhook', (req: Request, res: Response) => {
// Verify request signature
const signature = req.headers['x-hub-signature-256'] as string;
if (!verifySignature(req, signature)) {
console.error('Invalid signature');
return res.sendStatus(401);
}
const body = req.body;
if (body.object !== 'page') {
return res.sendStatus(404);
}
// Process each entry
body.entry?.forEach((entry: any) => {
entry.messaging?.forEach((event: any) => {
handleMessagingEvent(event);
});
});
// Always respond with 200 OK quickly
res.sendStatus(200);
});
function verifySignature(req: any, signature: string): boolean {
if (!signature) return false;
const appSecret = process.env.FACEBOOK_APP_SECRET!;
const expectedSignature = 'sha256=' + crypto
.createHmac('sha256', appSecret)
.update(req.rawBody)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expectedSignature)
);
}
async function handleMessagingEvent(event: any): Promise {
const senderId = event.sender.id;
if (event.message) {
await handleMessage(senderId, event.message);
} else if (event.postback) {
await handlePostback(senderId, event.postback);
} else if (event.read) {
console.log(`Message read by ${senderId}`);
} else if (event.delivery) {
console.log(`Message delivered to ${senderId}`);
}
}
Suscribiéndose a Eventos de Webhook
Después de configurar tu endpoint, suscríbete a los eventos que deseas recibir. En el Panel de Meta App, configura la URL de tu webhook y selecciona los campos de suscripción relevantes:
messages: Mensajes entrantesmessaging_postbacks: Clics en botones y selecciones de menúmessaging_optins: Opt-ins de usuariosmessage_deliveries: Confirmaciones de entregamessage_reads: Confirmaciones de lectura
Recibiendo Mensajes
Cuando los usuarios envían mensajes a tu bot, la facebook chat api los entrega a tu webhook. Los mensajes pueden contener texto, archivos adjuntos o ambos.
interface MessengerMessage {
mid: string;
text?: string;
attachments?: Array<{
type: 'image' | 'video' | 'audio' | 'file' | 'location' | 'fallback';
payload: {
url?: string;
coordinates?: {
lat: number;
long: number;
};
};
}>;
quick_reply?: {
payload: string;
};
reply_to?: {
mid: string;
};
}
async function handleMessage(
senderId: string,
message: MessengerMessage
): Promise {
console.log(`Received message from ${senderId}:`, message);
// Handle quick reply responses
if (message.quick_reply) {
await handleQuickReply(senderId, message.quick_reply.payload);
return;
}
// Handle attachments
if (message.attachments && message.attachments.length > 0) {
for (const attachment of message.attachments) {
await handleAttachment(senderId, attachment);
}
return;
}
// Handle text messages
if (message.text) {
await processTextMessage(senderId, message.text);
}
}
async function handleAttachment(
senderId: string,
attachment: MessengerMessage['attachments'][0]
): Promise {
switch (attachment.type) {
case 'image':
await sendTextMessage(senderId, `Thanks for the image! I received: ${attachment.payload.url}`);
break;
case 'location':
const { lat, long } = attachment.payload.coordinates!;
await sendTextMessage(senderId, `Got your location: ${lat}, ${long}`);
break;
default:
await sendTextMessage(senderId, `Received your ${attachment.type}`);
}
}
async function processTextMessage(
senderId: string,
text: string
): Promise {
const lowerText = text.toLowerCase();
if (lowerText.includes('help')) {
await sendHelpMessage(senderId);
} else if (lowerText.includes('products')) {
await sendProductCatalog(senderId);
} else {
await sendTextMessage(senderId, `You said: "${text}". How can I help you today?`);
}
}
Enviando Mensajes de Texto
La Send API es tu herramienta principal para responder a los usuarios a través de la messenger bot api. Los mensajes de texto son la forma más simple de respuesta.
const GRAPH_API_URL = 'https://graph.facebook.com/v18.0';
interface SendMessageResponse {
recipient_id: string;
message_id: string;
}
interface SendMessageError {
message: string;
type: string;
code: number;
error_subcode?: number;
fbtrace_id: string;
}
async function sendTextMessage(
recipientId: string,
text: string
): Promise {
const pageAccessToken = process.env.FACEBOOK_PAGE_ACCESS_TOKEN!;
const response = await fetch(
`${GRAPH_API_URL}/me/messages?access_token=${pageAccessToken}`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
recipient: { id: recipientId },
message: { text },
messaging_type: 'RESPONSE'
}),
}
);
const data = await response.json();
if (!response.ok) {
const error = data.error as SendMessageError;
throw new Error(`Send failed: ${error.message} (code: ${error.code})`);
}
return data as SendMessageResponse;
}
// Send typing indicator for better UX
async function sendTypingIndicator(
recipientId: string,
isTyping: boolean
): Promise {
const pageAccessToken = process.env.FACEBOOK_PAGE_ACCESS_TOKEN!;
await fetch(
`${GRAPH_API_URL}/me/messages?access_token=${pageAccessToken}`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
recipient: { id: recipientId },
sender_action: isTyping ? 'typing_on' : 'typing_off'
}),
}
);
}
// Helper function to send messages with typing indicator
async function sendMessageWithTyping(
recipientId: string,
text: string,
typingDuration: number = 1000
): Promise {
await sendTypingIndicator(recipientId, true);
await new Promise(resolve => setTimeout(resolve, typingDuration));
return sendTextMessage(recipientId, text);
}
Plantillas de Mensajes (Generic, Button, Receipt)
Las plantillas de mensajes crean experiencias ricas e interactivas que van más allá del texto simple. La facebook messenger api soporta varios tipos de plantillas, cada una diseñada para casos de uso específicos.
Plantilla Generic
La Plantilla Generic muestra un carrusel de elementos, perfecta para listados de productos o feeds de contenido.
interface GenericTemplateElement {
title: string;
subtitle?: string;
image_url?: string;
default_action?: {
type: 'web_url';
url: string;
webview_height_ratio?: 'compact' | 'tall' | 'full';
};
buttons?: Array;
}
type TemplateButton =
| { type: 'web_url'; url: string; title: string }
| { type: 'postback'; title: string; payload: string }
| { type: 'phone_number'; title: string; payload: string }
| { type: 'account_link'; url: string }
| { type: 'ac