Especialidad technical

Calcula el número exacto de segmentos de SMS antes de enviar: fórmula y código (PHP/JS/Python)

Calcule el número de segmentos de SMS antes de enviarlos: guía técnica con ejemplos de código para desarrolladores en Marruecos.

Calcula el número exacto de segmentos de SMS antes de enviar: fórmula y código (PHP/JS/Python)
En este artículo
  1. Uno de los errores más comunes al integrar una [API de SMS en Marruecos](/fr/api-sms-maroc/) es la sobrecarga inesperada relacionada con la codificación. Envías una campaña de 10.000 mensajes en darija y tu proveedor te cobra 30.000 créditos. Para qué ? Porque los SMS no se facturan “por mensaje”, sino “por segmento”.
  2. La fórmula para calcular segmentos.
  3. Detecta automáticamente GSM-7 vs UCS-2 en el código
  4. Fragmento PHP (Listo para usar)
  5. Fragmento Node.js / JavaScript

Uno de los errores más comunes al integrar una [API de SMS en Marruecos](/fr/api-sms-maroc/) es la sobrecarga inesperada relacionada con la codificación. Envías una campaña de 10.000 mensajes en darija y tu proveedor te cobra 30.000 créditos. Para qué ? Porque los SMS no se facturan “por mensaje”, sino “por segmento”.

Si está creando un CRM interno o una aplicación empresarial, debe definitivamente mostrar a sus usuarios la cantidad de segmentos que están a punto de consumir antes de hacer clic en "Enviar".

Aquí está la especificación técnica (GSM 03.38) y el código para implementar un contador de segmentos robusto en sus aplicaciones.

La fórmula para calcular segmentos.

La red de telecomunicaciones limita un SMS a un peso de 140 octetos (bytes). La capacidad de caracteres depende de cómo se utilizan estos bytes (la codificación):

1. Codificación GSM-7 (Alfabeto estándar)

Se utiliza para caracteres latinos clásicos (a-z, A-Z, 0-9) y algunos signos de puntuación básicos.

  • Cada carácter ocupa 7 bits.
  • Tamaño máximo para 1 segmento: 160 caracteres.
  • Tamaño si está concatenado (> 1 segmento): 153 caracteres por segmento (7 caracteres están reservados para el Encabezado de Datos de Usuario - UDH, que permite al teléfono juntar las piezas).

2. Codificación UCS-2 (Unicode)

Obligatorio si su mensaje contiene un solo carácter árabe, un emoji (🚀) o un acento complejo (œ).

  • Cada carácter ocupa 16 bits.
  • Tamaño máximo para 1 segmento: 70 caracteres.
  • Tamaño si está concatenado (> 1 segmento): 67 caracteres por segmento (3 caracteres reservados para UDH).

Detecta automáticamente GSM-7 vs UCS-2 en el código

El algoritmo de cálculo se realiza en 3 pasos:

  1. Analiza cada carácter del texto.
  2. Si todos los caracteres pertenecen al alfabeto GSM-7, utilice el límite de 160/153.
  3. Si un carácter único no pertenece allí, fuerce el alfabeto UCS-2 y use el límite de 70/67.

Nota: Algunos caracteres GSM-7 "extendidos" (como €, [, ], ~) cuentan el doble. Una buena función debe tenerlos en cuenta.

Fragmento PHP (Listo para usar)

Aquí hay una implementación PHP liviana, perfecta para backends de Laravel:

php
function calculateSmsSegments($text) {
    // Alphabet GSM-7 standard + Extension
    $gsm7Chars = "@£\$¥èéùìòÇ\nØø\rÅåΔ_ΦΓΛΩΠΨΣΘΞÆæßÉ !\"#¤%&'()*+,-./0123456789:;<=>?¡ABCDEFGHIJKLMNOPQRSTUVWXYZÄÖÑܧ¿abcdefghijklmnopqrstuvwxyzäöñüà";
    $gsm7Extended = "^{}\\[~]|€";
    
    $isGSM = true;
    $length = 0;
    
    // Détection de l'encodage et calcul de la longueur
    $chars = preg_split('//u', $text, -1, PREG_SPLIT_NO_EMPTY);
    foreach ($chars as $char) {
        if (mb_strpos($gsm7Extended, $char) !== false) {
            $length += 2; // Compte double
        } elseif (mb_strpos($gsm7Chars, $char) !== false) {
            $length += 1;
        } else {
            // Caractère hors GSM-7 trouvé (ex: Arabe, Emoji)
            $isGSM = false;
            $length = mb_strlen($text, 'UTF-8');
            break;
        }
    }
    
    if ($isGSM) {
        if ($length <= 160) return 1;
        return ceil($length / 153);
    } else {
        if ($length <= 70) return 1;
        return ceil($length / 67);
    }
}

// Tests
echo calculateSmsSegments("Test simple GSM7"); // Retourne 1
echo calculateSmsSegments("Test en arabe مرحبا"); // Retourne 1 (passe en UCS2, mais <70)
echo calculateSmsSegments(str_repeat("مرحبا بكم في خدمة الرسائل القصيرة", 3)); // Retourne 2 ou 3 selon la longueur exacte

Fragmento Node.js / JavaScript

Para su interfaz React/Vue (para mostrar el contador en vivo mientras escribe):

javascript
function getSmsSegments(text) {
    const gsm7Regex = /^[@£$¥èéùìòÇ\nØø\rÅåΔ_ΦΓΛΩΠΨΣΘΞÆæßÉ !"\#¤%&'()*+,\-.\/0-9:;<=>?¡A-ZÄÖÑܧ¿a-zäöñüà\^\{\}\\[~\]|€]*$/;
    
    // Détecter si le texte est entièrement en GSM-7
    const isGsm7 = gsm7Regex.test(text);
    
    // Calcul de la longueur (les caractères étendus comme € comptent pour 2)
    let length = text.length;
    if (isGsm7) {
        const extendedRegex = /[\^\{\}\\[~\]|€]/g;
        const matches = text.match(extendedRegex);
        if (matches) {
            length += matches.length;
        }
    }
    
    if (isGsm7) {
        if (length <= 160) return 1;
        return Math.ceil(length / 153);
    } else {
        // Mode UCS-2 (Unicode) - Attention avec JavaScript et les emojis (Surrogate pairs)
        // Array.from(text).length donne le compte exact d'emojis complexes
        const unicodeLength = Array.from(text).length;
        if (unicodeLength <= 70) return 1;
        return Math.ceil(unicodeLength / 67);
    }
}

console.log(`Segments: \${getSmsSegments("Vos soldes sont ouverts 🚀")}`); // Segments: 1 (UCS-2)

Nunca envíes tus campañas a ciegas. Implementar esta lógica en su aplicación le evitará a usted y a sus clientes marroquíes facturas fuera de control SMS API.

¿Por qué elegir EnvoiSMS para su negocio?

Entrega a Operadores

Rutas locales hacia IAM, Orange e Inwi, con conmutación automática entre rutas y estado de entrega enviado por webhook.

Optimización de Costes

WhatsApp Business API desde 0,65 MAD por mensaje. El mejor retorno de inversión.

Conformidad CNDP

Alojamiento que cumple con las regulaciones de protección de datos personales locales.

¿Cuál es la latencia de enrutamiento en las redes IAM, Inwi y Orange?
En nuestras rutas locales hacia Maroc Telecom (IAM), Orange e inwi, la latencia media de entrega es de entre 2 y 4 segundos para los flujos transaccionales.
¿Cómo gestiona la plataforma el formato de los números marroquíes?
EnvoiSMS normaliza automáticamente los números introducidos (06..., 07..., 00212...) al estándar E.164 (+212) para evitar cualquier fallo en la entrega.

Artículos sugeridos

Formateo de SMS en Marruecos: saltos de línea, codificación GSM-7 frente a UCS-2 y optimización de costes
technical

Formateo de SMS en Marruecos: saltos de línea, codificación GSM-7 frente a UCS-2 y optimización de costes

Formato empresarial de WhatsApp en Marruecos: texto enriquecido, emojis y botones interactivos
technical

Formato empresarial de WhatsApp en Marruecos: texto enriquecido, emojis y botones interactivos

Autenticación WhatsApp en 1-Clic y One-Tap Autofill OTP en Marruecos
technical

Autenticación WhatsApp en 1-Clic y One-Tap Autofill OTP en Marruecos