Cómo elegir e integrar un proveedor SMS para tu WhatsApp Bot en 2026
Si tienes un bot de WhatsApp en producción sabes que la entrega no es perfecta. Los usuarios cambian de número, tienen WhatsApp desactivado, o simplemente no abren el app. SMS sigue siendo el canal de respaldo más confiable que existe: tasa de apertura arriba del 90%, sin necesidad de app instalada, y funciona en cualquier teléfono del planeta. El problema es que elegir mal el proveedor te cuesta caro — tanto en pesos como en mensajes que nunca llegan.

Este tutorial te lleva de la mano desde la evaluación de proveedores hasta la integración funcional con tu bot, con código real y advertencias de lo que se rompe en producción.
Requisitos previos
- Bot de WhatsApp funcional (Cloud API o BSP como Gupshup, 360dialog, etc.)
- Node.js 20+ o Python 3.11+
- Cuenta activa en al menos un proveedor SMS (Sinch, Twilio, Vonage, Telnyx)
- Variables de entorno configuradas (nunca hardcodees credenciales)
- Webhook funcional para recibir delivery receipts
Paso 1: Define tus criterios de evaluación antes de firmar nada
Antes de abrir cuenta en cualquier proveedor, tienes que saber qué vas a medir. Los criterios que importan en 2026 para México y Latinoamérica son:
Cobertura real en destino. No te fíes del mapa de cobertura en el sitio web. Pide una prueba técnica con envíos reales a Telcel, AT&T México y Movistar. Los carriers locales tienen reglas de filtrado distintas cada año.
Latencia de entrega. Para OTPs y alertas de fraude, si el SMS tarda más de 10 segundos en llegar, el usuario ya se desesperó. Mide el tiempo entre el API call y el delivery receipt.
Tasa de entrega confirmada (DLR rate). Un proveedor que te promete 99% de entrega pero no te da DLRs detallados no te está prometiendo nada. Exige reportes con breakdown por carrier.
Precio por segmento, no por mensaje. Un SMS de más de 160 caracteres se factura como múltiples segmentos. Con texto en español (acentos, ñ) en encoding UTF-16, el límite baja a 70 caracteres por segmento. Esto duplica o triplica tu factura si no lo calculas.
Soporte de Sender ID alfanumérico en México. Desde 2025, IFETEL tiene reglas más estrictas. Confirma con el proveedor que tu Sender ID esté registrado correctamente.
Paso 2: Arquitectura de fallback WhatsApp → SMS
La lógica es simple: si el mensaje de WhatsApp no se entrega en X minutos, dispara el SMS. Aquí el diagrama de flujo:
Usuario → Bot intenta WhatsApp Cloud API
↓ (webhook: message_delivered?)
No entregado en 3 min
↓
Fallback SMS via proveedor
↓
Log del evento + métrica
Implementa esto con un job asíncrono. No bloquees el flujo principal del bot esperando el DLR de WhatsApp.
Paso 3: Integración con Sinch (ejemplo funcional)
Sinch tiene SDK oficial para Node.js y Python. Aquí el ejemplo en Node.js con manejo de errores real:
// sms-fallback.js
import { SinchClient } from '@sinch/sdk-core';
const sinch = new SinchClient({
projectId: process.env.SINCH_PROJECT_ID,
keyId: process.env.SINCH_KEY_ID,
keySecret: process.env.SINCH_KEY_SECRET,
});
export async function sendFallbackSMS(toNumber, messageText) {
// Normaliza el número a E.164
const normalized = toNumber.startsWith('+') ? toNumber : `+52${toNumber}`;
try {
const response = await sinch.sms.batches.send({
to: [normalized],
from: process.env.SINCH_SENDER_ID,
body: messageText,
delivery_report: 'per_recipient',
callback_url: `${process.env.BASE_URL}/webhooks/sinch-dlr`,
});
console.log(`SMS enviado. Batch ID: ${response.id}`);
return { success: true, batchId: response.id };
} catch (error) {
// Sinch regresa errores estructurados — loggea el code, no solo el message
console.error(`Error SMS [${error.statusCode}]: ${error.message}`);
return { success: false, error: error.message };
}
}
Webhook para recibir DLRs de Sinch:
// En tu router Express
app.post('/webhooks/sinch-dlr', (req, res) => {
const { batch_id, statuses } = req.body;
for (const status of statuses) {
console.log(`[DLR] ${status.recipient}: ${status.code} - ${status.status}`);
// Guarda en DB: número, estado, timestamp
saveDLRToDatabase({
batchId: batch_id,
number: status.recipient,
status: status.status, // 'Delivered', 'Failed', 'Unknown'
code: status.code,
timestamp: new Date(),
});
}
res.status(200).send('OK');
});
Paso 4: Lógica de fallback en el bot
// whatsapp-with-fallback.js
import { sendWhatsAppMessage } from './whatsapp.js';
import { sendFallbackSMS } from './sms-fallback.js';
const FALLBACK_TIMEOUT_MS = 3 * 60 * 1000; // 3 minutos
export async function sendWithFallback(userId, phoneNumber, message) {
const waResult = await sendWhatsAppMessage(userId, message);
if (!waResult.success) {
// WhatsApp falló inmediatamente — fallback directo
return sendFallbackSMS(phoneNumber, message);
}
// Programa verificación de entrega
setTimeout(async () => {
const delivered = await checkWhatsAppDelivery(waResult.messageId);
if (!delivered) {
console.log(`WA no entregado para ${userId}, activando SMS fallback`);
await sendFallbackSMS(phoneNumber, message);
}
}, FALLBACK_TIMEOUT_MS);
return waResult;
}
Paso 5: Métricas que debes monitorear en producción
No instales esto y te olvides. Estas son las métricas que debes tener en tu dashboard (Grafana, Datadog, lo que uses):
- Fallback rate: porcentaje de mensajes que terminaron en SMS. Si sube de 15%, algo está mal con tu configuración de WhatsApp.
- SMS DLR success rate por carrier: desglosa Telcel vs AT&T vs Movistar. Las diferencias pueden ser brutales.
- Costo por conversación: suma WhatsApp + SMS cuando aplica. Te ayuda a decidir si vale la pena el doble envío.
- Latencia de fallback: tiempo entre el fallo de WA y la entrega del SMS.
Advertencias reales de producción
No envíes el mismo contenido por WhatsApp y SMS simultáneamente. El usuario recibe duplicados y se molesta. Respeta el timeout antes de activar el fallback.
Los números de México en E.164 llevan +52, no +521. El dígito 1 después del código de país era para celulares antes de 2020. Hoy todos los carriers mexicanos aceptan +52 directo. Algunos proveedores internacionales aún agregan el 1 automáticamente — verifica y desactiva esa opción.
Codificación de caracteres. Si tu mensaje tiene ñ, acentos o emojis, usa encoding explícito. Con Sinch, el SDK maneja esto, pero si usas la API REST directamente, especifica "encoding": "unicode" o tus mensajes llegarán como basura.
Rate limits. Sinch en el plan básico tiene límites por segundo. En campañas masivas, implementa una cola con Bull o BullMQ para no recibir errores 429.
Prueba con números reales antes de producción. Los sandbox de los proveedores no replican los filtros de los carriers reales. Gasta los 20 pesos que cuesta una prueba real. Vale la pena.
Comparativa rápida de proveedores para México (2026)
| Proveedor | Cobertura MX | DLR detallado | Sender ID alfanum. | Precio aprox/SMS |
|---|---|---|---|---|
| Sinch | Excelente | Sí | Sí (con registro) | $0.008 USD |
| Twilio | Muy buena | Sí | Sí | $0.0079 USD |
| Vonage | Buena | Sí | Limitado | $0.009 USD |
| Telnyx | Buena | Sí | Sí | $0.006 USD |
Los precios varían según volumen. Negocia siempre si mandas más de 50k mensajes al mes.
SMS no está muerto. En 2026 sigue siendo el canal de último recurso más confiable que existe, y combinado con WhatsApp tienes una estrategia de entrega que cubre prácticamente cualquier escenario. Implementa esto bien desde el inicio y te ahorras dolores de cabeza cuando tu bot escale.