Saltar al contenido
nvíame
Capítulo 4 de 410 min6 oct 2026

Canales de fallback SMS→chat

Cuando el SMS no llega: reenvío por canal IP, llamada de voz y diseño del botón de reenvío.

Entre un 2% y un 5% de los OTP por SMS no llegan a tiempo en mercados exigentes. Cada uno es un usuario que no pudo entrar. Ofrecer un canal alternativo convierte esa pérdida en una espera breve.

Una cascada razonable

  • SMS inmediato.
  • A los 30 s, botón «Reenviar» habilitado.
  • En el segundo intento, ofrecer canal de chat si el usuario lo tiene.
  • Como último recurso, llamada de voz que dicta el código.
const channels = ["sms", "chat", "voice"];
async function resend(session) {
  const next = channels[Math.min(session.sends, channels.length - 1)];
  session.sends++;
  return next === "sms"
    ? mx.sms.send({ to: session.phone, text: otpText(session.code) })
    : mx.chat.send(next, otpText(session.code));
}

Cuando el SMS tarda, el usuario pide otro código, y luego otro. Cada reenvío cuesta y además invalida el anterior, de modo que el mensaje que llega primero ya no sirve. Ofrecer un canal alternativo después de un tiempo prudente resuelve ambos problemas.

El orden habitual es SMS primero, por alcance, y canal de chat como alternativa ofrecida al usuario tras 30 a 60 segundos. La alternativa debe enviar el mismo código, no uno nuevo, para que cualquiera de los dos mensajes funcione.

Pruébalo

// Same OTP over SMS and then chat, so either message works
const phone = "+56912345678";
const code = mx.otp.issue(phone);

await mx.sms.send({ to: phone, text: "Tu código nvíame es " + code + ". Vence en 5 min." });
console.log("Esperando... el usuario pide otro canal");

await mx.chat.send("chat", "🔐 Tu código nvíame es " + code + ". No lo compartas.");
console.log("¿Verifica con el código recibido por chat?", mx.otp.verify(phone, code));
Se completa automáticamente al leer el 80%.

Comentarios (3)

Matías Herrera6 oct 2026

¿El código debe ser el mismo al cambiar de canal?

Equipo nvíameAutor6 oct 2026

Puedes reutilizarlo si no expiró, lo que evita confusión si llegan ambos. Si emites uno nuevo, invalida el anterior y dilo en la interfaz.

Camila Rojas6 oct 2026

Lo apliqué en el proyecto del trabajo. La sección «Canales de fallback SMS→chat» me ahorró una discusión larga con el equipo: ahora tenemos un criterio compartido.

Sofía Castillo6 oct 2026

¿Hay alguna diferencia importante si lo implemento en un servicio con varias instancias detrás de un balanceador?

Equipo nvíameAutor6 oct 2026

Sí: todo estado que hoy vive en memoria (contadores, sesiones, claves vistas) debe moverse a un almacén compartido con TTL, como Redis. Si no, cada instancia ve solo una parte de la historia.

Los comentarios se guardan solo en este navegador.