Cómo integrar RCS en tu bot de WhatsApp: guía práctica para 2026
Si llevas tiempo construyendo bots de WhatsApp, ya sabes el dolor: el usuario no tiene la app instalada, el número es de prepago sin datos suficientes, o simplemente el mercado al que apuntas tiene una penetración de WhatsApp por debajo del 60%. En 2026, RCS (Rich Communication Services) ya no es una promesa de Google — es el protocolo nativo en prácticamente todos los Android con Android 12 o superior, y Apple lo adoptó de lleno desde iOS 18. El canal existe. La pregunta es cómo aprovecharlo sin tirar a la basura el bot que ya construiste.

Este tutorial te muestra cómo tender un puente entre tu lógica de bot existente (asumimos Node.js con la WhatsApp Cloud API de Meta) y RCS usando la plataforma de Sinch como intermediario. Al final tendrás un sistema que detecta si el número de destino soporta RCS, manda el mensaje enriquecido por ese canal si puede, y cae en cascada a WhatsApp o SMS si no puede.
Requisitos previos
- Node.js 20+ instalado
- Una app activa en Meta Business con WhatsApp Cloud API configurada
- Cuenta en Sinch con acceso a su RCS API (el plan Conversation API incluye RCS, WhatsApp y SMS en un solo endpoint — esto es clave)
- Número de teléfono verificado en Sinch con RCS habilitado (puede tardar 2-5 días hábiles en producción)
- Variables de entorno configuradas:
SINCH_APP_ID,SINCH_PROJECT_ID,SINCH_KEY_ID,SINCH_KEY_SECRET
Paso 1: Entiende cómo funciona RCS en producción
RCS no viaja por la red celular de señalización como el SMS. Va sobre datos — Wi-Fi o datos móviles — y se conecta a un servidor RCS operado por Google o el carrier. Esto significa dos cosas importantes para tu bot:
- Capacidad de entrega incierta: si el usuario no tiene datos activos, el mensaje se queda en cola. No hay garantía de entrega inmediata como en SMS.
- Verificación del agente: tu bot en RCS debe estar aprobado como "RCS Business Messaging agent" antes de poder mandar mensajes verificados con logo y nombre de marca. Sin eso, los mensajes salen como RCS genérico o se bloquean.
Sinch abstrae parte de esta complejidad, pero necesitas saber qué esperar.
Paso 2: Instala el SDK de Sinch
npm install @sinch/sdk-core
Configura el cliente en tu archivo principal:
// sinchClient.js
import { SinchClient } from '@sinch/sdk-core';
export const sinch = new SinchClient({
projectId: process.env.SINCH_PROJECT_ID,
keyId: process.env.SINCH_KEY_ID,
keySecret: process.env.SINCH_KEY_SECRET,
});
Paso 3: Detecta si el número soporta RCS
Antes de mandar cualquier cosa, consulta la capability del número. Sinch tiene un endpoint para esto dentro de Conversation API:
// checkCapability.js
import { sinch } from './sinchClient.js';
export async function checkRCSCapability(phoneNumber) {
try {
const result = await sinch.conversation.capability.lookup({
lookupCapabilityRequestBody: {
recipient: {
identified_by: {
channel_identities: [
{
channel: 'RCS',
identity: phoneNumber, // formato E.164: +521234567890
},
],
},
},
app_id: process.env.SINCH_APP_ID,
},
});
const channels = result.capability ?? [];
return channels.includes('RCS');
} catch (err) {
console.error('Error checking RCS capability:', err.message);
return false;
}
}
Advertencia de producción: esta llamada tiene latencia. En promedio 300-800ms. No la hagas en tiempo real durante una conversación activa — cachea el resultado por número durante al menos 24 horas en Redis o en tu base de datos.
Paso 4: Construye la lógica de canal con fallback
Aquí está el núcleo del puente. La idea es simple: si el número soporta RCS, manda por RCS. Si no, intenta WhatsApp. Si tampoco, SMS.
// sendMessage.js
import { sinch } from './sinchClient.js';
import { checkRCSCapability } from './checkCapability.js';
export async function sendWithFallback(phoneNumber, messagePayload) {
const supportsRCS = await checkRCSCapability(phoneNumber);
const channelPriority = supportsRCS
? ['RCS', 'WHATSAPP', 'SMS']
: ['WHATSAPP', 'SMS'];
const response = await sinch.conversation.messages.send({
sendMessageRequestBody: {
app_id: process.env.SINCH_APP_ID,
recipient: {
identified_by: {
channel_identities: channelPriority.map((channel) => ({
channel,
identity: phoneNumber,
})),
},
},
message: messagePayload,
channel_priority_order: channelPriority,
},
});
return response;
}
Y un payload de ejemplo con tarjeta enriquecida (esto es lo que RCS puede mandar y WhatsApp no puede de la misma forma nativa):
const richCardPayload = {
card_message: {
title: 'Tu pedido está listo',
description: 'Pasa a recogerlo antes de las 9pm.',
media_message: {
url: 'https://tudominio.com/assets/pedido-listo.jpg',
thumbnail_url: 'https://tudominio.com/assets/pedido-listo-thumb.jpg',
},
choices: [
{
text_message: { text: 'Ver detalles' },
postback_data: 'ver_detalles',
},
{
text_message: { text: 'Cancelar pedido' },
postback_data: 'cancelar_pedido',
},
],
},
};
Paso 5: Maneja los webhooks de respuesta
RCS y WhatsApp usan el mismo webhook de Conversation API en Sinch. Configura un endpoint en tu servidor:
// webhook.js
import express from 'express';
const router = express.Router();
router.post('/sinch-webhook', express.json(), (req, res) => {
const event = req.body;
if (event.message) {
const { contact_id, channel_identity, body } = event.message;
const canal = channel_identity?.channel ?? 'DESCONOCIDO';
const texto = body?.text_message?.text ?? '';
console.log(`Mensaje de ${contact_id} vía ${canal}: ${texto}`);
// Aquí conectas con tu lógica de bot existente
procesarMensaje({ contactId: contact_id, canal, texto });
}
res.sendStatus(200);
});
export default router;
Advertencia: Sinch espera un 200 OK en menos de 5 segundos. Si tu procesarMensaje tarda más (llamadas a LLM, consultas a DB), responde el 200 primero y procesa de forma asíncrona.
Paso 6: Prueba en staging antes de tocar producción
Sinch tiene un sandbox para RCS. Actívalo desde el dashboard y usa números de prueba para simular la entrega. Los mensajes en sandbox NO salen al dispositivo real — son simulados en el portal. Valida:
- Que el fallback a WhatsApp funciona cuando el número no tiene RCS
- Que los postback_data de las tarjetas llegan al webhook
- Que el caché de capability no te da falsos positivos
Consideraciones finales para producción
- Aprobación del agente RCS: en México, Telcel y AT&T ya soportan RCS Business Messaging, pero la aprobación del agente puede tardar semanas. Empieza ese proceso antes de escribir una sola línea de código.
- Costos: RCS Business Messaging no es gratuito. En Sinch, el costo por mensaje RCS es similar al de WhatsApp pero varía por carrier y país.
- Privacidad: RCS sobre Google pasa por los servidores de Google. Si tu caso de uso maneja datos sensibles, evalúa las implicaciones de cumplimiento antes de activar el canal.
- Límites de tamaño: las imágenes en tarjetas RCS tienen un límite de 1MB. Las tarjetas en carrusel admiten hasta 10 elementos. Valida tu contenido antes de mandarlo o recibirás errores silenciosos.
Con esto tienes un puente funcional entre tu bot de WhatsApp y RCS. El canal ya está ahí — solo falta aprovecharlo.