Que son los SMS y MMS: Guia Completa para Desarrolladores
Los SMS y MMS son las tecnologias de mensajeria movil mas antiguas y universales del mundo. A pesar del auge de WhatsApp, Telegram y otras apps, siguen siendo fundamentales para verificacion de usuarios, notificaciones criticas y marketing. En esta guia te explicamos todo lo que necesitas saber como desarrollador.
Que es un SMS?
SMS significa
Short Message Service (Servicio de Mensajes Cortos). Es un protocolo de comunicacion que permite enviar mensajes de texto entre telefonos moviles a traves de la red celular.
Caracteristicas Principales del SMS
| Longitud maxima | 160 caracteres (GSM-7) o 70 caracteres (Unicode) |
|---|
| Tipo de contenido | Solo texto |
|---|
| Requiere internet | No |
|---|
| Cobertura | 99% de telefonos moviles |
|---|
| Tasa de apertura | ~98% |
|---|
Historia del SMS
- 1984: Primera propuesta del concepto SMS
- 1992: Primer SMS enviado ("Merry Christmas")
- 2000s: Explosion de uso entre consumidores
- 2010s: Transicion hacia uso empresarial (A2P)
- 2020s: Fundamental para 2FA y notificaciones
Como Funciona Tecnicamente el SMS
Tu aplicacion envia el mensaje a un proveedor de SMS (como Zavu)El proveedor se conecta a un SMSC (Short Message Service Center)El SMSC localiza la red del destinatarioLa torre celular entrega el mensaje al telefonoEl telefono recibe el mensaje sin necesidad de internettext
[Tu App] --> [API Zavu] --> [SMSC] --> [Red Celular] --> [Telefono]
Que es un MMS?
MMS significa
Multimedia Messaging Service (Servicio de Mensajeria Multimedia). Es una extension del SMS que permite enviar contenido multimedia.
Caracteristicas del MMS
| Tamano maximo | 300KB - 600KB (varia por operador) |
|---|
| Tipos de contenido | Imagenes, videos, audio, vCards |
|---|
| Requiere internet | Datos moviles |
|---|
| Cobertura | ~95% de smartphones |
|---|
| Costo | 3-5x mas caro que SMS |
|---|
Tipos de Contenido MMS
- Imagenes: JPG, PNG, GIF (hasta ~500KB)
- Video: MP4, 3GP (muy limitado, ~15 segundos)
- Audio: MP3, AAC (clips cortos)
- vCard: Tarjetas de contacto
- Texto largo: Mensajes sin limite de 160 caracteres
SMS vs MMS: Diferencias Clave
| Contenido | Solo texto | Multimedia + texto |
|---|
| Limite | 160 caracteres | ~600KB |
|---|
| Costo por mensaje | $0.01 - $0.03 | $0.03 - $0.10 |
|---|
| Requiere datos | No | Si |
|---|
| Velocidad entrega | Segundos | Segundos a minutos |
|---|
| Compatibilidad | Universal | Casi universal |
|---|
| Uso principal | 2FA, notificaciones | Marketing visual |
|---|
Cuando Usar SMS
- Verificacion de usuarios (OTP/2FA)
- Notificaciones criticas (alertas de seguridad, confirmaciones)
- Recordatorios (citas, pagos, renovaciones)
- Alertas transaccionales (pedidos, envios)
- Mercados con internet limitado
Cuando Usar MMS
- Campanas de marketing visual
- Promociones con imagenes de productos
- Cupones con codigo QR
- Confirmaciones con recibos visuales
- Contenido que requiere impacto visual
Limitaciones Tecnicas del SMS
1. Limite de Caracteres
El SMS usa codificacion GSM-7, que permite 160 caracteres. Pero si usas caracteres especiales (emojis, acentos como a, n, u), cambia a UCS-2/Unicode y el limite baja a 70 caracteres.
typescript
const mensaje1 = "Your verification code is 123456";
const mensaje2 = "Tu codigo es 123456. Valido 5 min";
Tabla de Segmentos SMS
| Codificacion | Caracteres por SMS | Concatenados (por segmento) |
|---|
Nota: Los mensajes largos se dividen en "segmentos" y cada uno cuenta como un SMS individual para facturacion.
2. Caracteres GSM-7 Permitidos
text
A-Z, a-z, 0-9
@ ! " # $ % & ' ( ) + , - . / : ; < = > ?
Espacio, salto de linea
Algunos caracteres especiales: [ ] \ ^ _ { | } ~
Caracteres que activan Unicode:- Emojis
- Caracteres acentuados (a, e, i, o, u, n)
- Simbolos especiales
- Caracteres de otros alfabetos
3. Problemas de Entrega
Los SMS pueden fallar por varias razones:
| Codigo Error | Significado | Solucion |
|---|
| 30001 | Numero invalido | Validar formato E.164 |
|---|
| 30002 | Numero no alcanzable | Telefono apagado/sin cobertura |
|---|
| 30003 | Numero no existe | Verificar el numero |
|---|
| 30004 | Spam detectado | Revisar contenido del mensaje |
|---|
| 30005 | Carrier bloqueo | Registrar 10DLC (USA) |
|---|
| 30007 | Mensaje filtrado | Evitar palabras spam |
|---|
Regulaciones Importantes
En Estados Unidos: 10DLC
Desde 2021, todos los mensajes A2P (Application-to-Person) en USA requieren registro 10DLC:
Registro de marca - Tu empresa en The Campaign RegistryRegistro de campana - Descripcion del usoAsignacion de numeros - Vincular numeros a campanasSin registro: Los mensajes seran bloqueados o tendran muy baja entrega.
En Union Europea: GDPR
- Consentimiento explicito requerido
- Derecho a desuscribirse (STOP)
- Registro de consentimientos
- Proteccion de datos personales
En Mexico: LFPDPPP
- Aviso de privacidad requerido
- Consentimiento para mensajes promocionales
- Mecanismo de baja (STOP, CANCELAR)
En Chile: Ley 19.628
- Autorizacion del titular de datos
- Finalidad especifica del tratamiento
- Derecho a cancelacion
Enviando SMS con Zavu
Instalacion
bash
npm install @zavudev/sdk
Configuracion
typescript
import Zavudev from "@zavudev/sdk";
const client = new Zavu({
apiKey: process.env.ZAVU_API_KEY,
});
Enviar SMS Simple
typescript
const result = await client.messages.send({
to: "+56912345678",
channel: "sms",
text: "Tu codigo de verificacion es 847293. Valido por 5 minutos.",
});
console.log(Mensaje enviado: ${result.message.id});
console.log(Estado: ${result.message.status});
typescript
const result = await client.messages.send({
to: "+56912345678",
channel: "sms",
text: "Tu pedido #12345 ha sido enviado. Llegara manana.",
metadata: {
orderId: "12345",
userId: "user_abc",
type: "shipping_notification",
},
});
Enviar a Multiples Destinatarios
typescript
const recipients = ["+56912345678", "+56987654321", "+56911223344"];
const results = await Promise.all(
recipients.map((to) =>
client.messages.send({
to,
channel: "sms",
text: "Recordatorio: Tu cita es manana a las 10:00 AM.",
})
)
);
console.log(Enviados: ${results.length} mensajes);
Casos de Uso Comunes
1. Verificacion de Usuario (OTP)
El caso de uso mas comun. Tasa de conversion superior al 95%.
typescript
import Zavudev from "@zavudev/sdk";
const client = new Zavu();
async function sendOTP(phoneNumber: string): Promise<string> {
const code = Math.floor(100000 + Math.random() 900000).toString();
await client.messages.send({
to: phoneNumber,
channel: "sms",
text: Tu codigo de verificacion es ${code}. Expira en 5 minutos. No lo compartas con nadie.,
});
return code;
}
const code = await sendOTP("+56912345678");
2. Confirmacion de Pedido
typescript
interface Order {
id: string;
customerPhone: string;
total: number;
items: number;
}
async function sendOrderConfirmation(order: Order) {
await client.messages.send({
to: order.customerPhone,
channel: "sms",
text: Pedido #${order.id} confirmado. Total: ${order.total}. ${order.items} articulos. Te avisaremos cuando se envie.,
metadata: {
orderId: order.id,
type: "order_confirmation",
},
});
}
3. Recordatorio de Cita
typescript
interface Appointment {
id: string;
patientPhone: string;
doctorName: string;
date: Date;
location: string;
}
async function sendAppointmentReminder(apt: Appointment) {
const formattedDate = apt.date.toLocaleDateString("es-CL", {
weekday: "long",
day: "numeric",
month: "long",
hour: "2-digit",
minute: "2-digit",
});
await client.messages.send({
to: apt.patientPhone,
channel: "sms",
text: Recordatorio: Cita con Dr. ${apt.doctorName} el ${formattedDate} en ${apt.location}. Responde SI para confirmar o NO para cancelar.,
});
}
4. Alerta de Seguridad
typescript
async function sendSecurityAlert(
phoneNumber: string,
eventType: "new_login" | "password_change" | "suspicious_activity",
details: { ip?: string; location?: string; device?: string }
) {
const messages = {
new_login: Nuevo inicio de sesion detectado desde ${details.location |
|---|
"ubicacion desconocida"}. Si no fuiste tu, cambia tu contrasena inmediatamente.,
password_change: Tu contrasena fue cambiada exitosamente. Si no realizaste este cambio, contacta soporte inmediatamente.,
suspicious_activity: Detectamos actividad sospechosa en tu cuenta. Por seguridad, verifica tus ultimas transacciones.,
};
await client.messages.send({
to: phoneNumber,
channel: "sms",
text: messages[eventType],
metadata: {
type: "security_alert",
eventType,
...details,
},
});
}
5. Notificacion de Envio
typescript
interface Shipment {
orderId: string;
customerPhone: string;
carrier: string;
trackingNumber: string;
estimatedDelivery: Date;
}
async function sendShippingNotification(shipment: Shipment) {
const deliveryDate = shipment.estimatedDelivery.toLocaleDateString("es-CL", {
weekday: "long",
day: "numeric",
month: "long",
});
await client.messages.send({
to: shipment.customerPhone,
channel: "sms",
text: Tu pedido #${shipment.orderId} esta en camino! Seguimiento: ${shipment.trackingNumber} (${shipment.carrier}). Llegada estimada: ${deliveryDate}.,
});
}
Mejores Practicas
Siempre usa formato E.164 (codigo de pais + numero):
typescript
const phoneE164 = "+56912345678";
const phoneLocal = "912345678";
const phoneWithSpaces = "+56 9 1234 5678";
2. Contenido del Mensaje
typescript
const good = "Tu codigo: 847293. Valido 5 min. No lo compartas.";
const bad = "FELICIDADES!!! Has GANADO un PREMIO INCREIBLE! Haz clic AHORA en este link para RECLAMAR tu REGALO GRATIS!!!";
3. Incluir Opt-out
Para mensajes de marketing, siempre incluye opcion de baja:
typescript
const marketingMessage =
Oferta especial: 20% de descuento en tu proxima compra.
Usa codigo VERANO20. Valido hasta el 31/12.
Responde STOP para no recibir mas ofertas.
.trim();
4. Manejar Errores
typescript
async function sendSMSWithRetry(
to: string,
text: string,
maxRetries = 3
): Promise<boolean> {
for(let attempt = 1; attempt <= maxRetries; attempt++) {
try {
const result = await client.messages.send({
to,
channel: "sms",
text,
});
if (result.message.status === "queued") {
return true;
}
} catch (error) {
console.error(Intento ${attempt} fallido:, error);
if (attempt === maxRetries) {
throw new Error(SMS fallido despues de ${maxRetries} intentos);
}
await new Promise(r => setTimeout(r, 1000 * attempt));
}
}
return false;
}
5. Validar Antes de Enviar
typescript
function validateSMS(to: string, text: string): { valid: boolean; errors: string[] } {
const errors: string[] = [];
if (!/^\+[1-9]\d{6,14}$/.test(to)) {
errors.push("Numero debe estar en formato E.164 (+56912345678)");
}
if (text.length === 0) {
errors.push("El mensaje no puede estar vacio");
}
if (text.length > 1600) {
errors.push("El mensaje excede 10 segmentos SMS");
}
const hasUnicode = /[^\x00-\x7F]/.test(text);
if (hasUnicode && text.length > 70) {
errors.push("Mensaje con caracteres especiales: se enviaran multiples SMS");
}
return {
valid: errors.length === 0,
errors,
};
}
Costos y Optimizacion
Estructura de Costos Tipica
| Componente | Costo Aproximado |
|---|
| SMS saliente (USA) | $0.0079 - $0.02 |
|---|
| SMS saliente (LATAM) | $0.02 - $0.08 |
|---|
| SMS saliente (Europa) | $0.03 - $0.10 |
|---|
| Numero telefonico | $1 - $5/mes |
|---|
| MMS saliente | $0.02 - $0.10 |
|---|
Consejos para Reducir Costos
Usa GSM-7 cuando sea posible - Evita emojis y acentos en mensajes criticos - Un mensaje de 161 caracteres = 2 SMS
Concatena mensajes inteligentemente - Si necesitas >160 chars, asegurate que valga la pena
Valida numeros antes de enviar - Evita costos por numeros invalidos - Usa Zavu para introspection de numeros
Considera alternativas para contenido largo - WhatsApp para mensajes largos (sin costo por caracter) - Email para contenido extenso
Usa MAU-based pricing - Con Zavu, pagas por usuario activo, no por mensaje - Envios ilimitados a cada usuario
SMS vs WhatsApp: Cuando Usar Cada Uno
| Cobertura | 99% telefonos | ~75% smartphones |
|---|
| Requiere app | No | Si |
|---|
| Requiere internet | No | Si |
|---|
| Costo | Por mensaje | Por conversacion |
|---|
| Contenido rico | No (solo MMS) | Si |
|---|
| Verificacion | Ideal | Bueno |
|---|
| Marketing | Limitado | Excelente |
|---|
| Soporte al cliente | Basico | Completo |
|---|
Recomendaciones
- Usa SMS para: OTP, alertas criticas, usuarios sin WhatsApp
- Usa WhatsApp para: Soporte, marketing, conversaciones largas
- Usa ambos: Fallback automatico si uno falla
typescript
const result = await client.messages.send({
to: "+56912345678",
channel: "auto",
text: "Tu codigo es 123456",
fallbackEnabled: true,
});
Integracion con Webhooks
Recibe actualizaciones de estado en tiempo real:
typescript
app.post("/webhooks/zavu", (req, res) => {
const { event, data } = req.body;
switch (event) {
case "message.delivered":
console.log(SMS entregado: ${data.messageId});
break;
case "message.failed":
console.error(SMS fallido: ${data.errorMessage});
break;
case "message.inbound":
console.log(SMS recibido de ${data.from}: ${data.text});
break;
}
res.sendStatus(200);
});
Conclusion
SMS y MMS siguen siendo herramientas fundamentales en 2025:
- SMS: Ideal para verificacion, alertas y notificaciones criticas
- MMS: Util para marketing visual cuando el impacto justifica el costo
Claves para el exito:Cumple con regulaciones locales (10DLC, GDPR, etc.)Optimiza el contenido para minimizar segmentosIncluye siempre opcion de opt-outValida numeros antes de enviarImplementa manejo de errores robustoConsidera WhatsApp como complemento, no reemplazoRecursos Adicionales
Necesitas ayuda con SMS? Nuestro equipo esta disponible para asistirte.
Contactanos o unete a nuestra
comunidad en Discord.