Expertise technical

Calculer le nombre exact de segments SMS avant l'envoi : formule et code (PHP/JS/Python)

Calculer nombre sms segments avant envoi : guide technique avec exemples de code pour les développeurs au Maroc.

Calculer le nombre exact de segments SMS avant l'envoi : formule et code (PHP/JS/Python)

L'un des pièges les plus courants lors de l'intégration d'une [API SMS au Maroc](/fr/api/) est la surfacturation imprévue liée à l'encodage. Vous envoyez une campagne de 10 000 messages en darija, et votre fournisseur vous facture 30 000 crédits. Pourquoi ? Parce que le SMS n'est pas facturé "au message", mais "au segment".

Si vous construisez un CRM maison ou une application métier, vous devez impérativement afficher à vos utilisateurs le nombre de segments qu'ils s'apprêtent à consommer avant qu'ils ne cliquent sur "Envoyer".

Voici la spécification technique (GSM 03.38) et le code pour implémenter un compteur de segments robuste dans vos applications.

La formule de calcul des segments

Un SMS est limité par le réseau télécom à un poids de 140 octets (bytes). La capacité en caractères dépend de la manière dont ces octets sont utilisés (l'encodage) :

1. Encodage GSM-7 (Alphabet standard)

Utilisé pour les caractères latins classiques (a-z, A-Z, 0-9) et quelques signes de ponctuation basiques.

  • Chaque caractère prend 7 bits.
  • Taille maximale pour 1 segment : 160 caractères.
  • Taille si concaténé (> 1 segment) : 153 caractères par segment (7 caractères sont réservés pour le User Data Header - UDH, qui permet au téléphone de recoller les morceaux).

2. Encodage UCS-2 (Unicode)

Obligatoire si votre message contient un seul caractère arabe, un emoji (🚀), ou un accent complexe (œ).

  • Chaque caractère prend 16 bits.
  • Taille maximale pour 1 segment : 70 caractères.
  • Taille si concaténé (> 1 segment) : 67 caractères par segment (3 caractères réservés pour l'UDH).

Détecter automatiquement GSM-7 vs UCS-2 dans le code

L'algorithme de calcul se déroule en 3 étapes :

  1. Analyser chaque caractère du texte.
  2. Si tous les caractères appartiennent à l'alphabet GSM-7, utiliser la limite de 160/153.
  3. Si un seul caractère n'y appartient pas, forcer l'alphabet UCS-2 et utiliser la limite de 70/67.

Note : Certains caractères GSM-7 "étendus" (comme , [, ], ~) comptent double. Une bonne fonction doit les prendre en compte.

Snippet PHP (Prêt à l'emploi)

Voici une implémentation PHP légère, parfaite pour les backends 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

Snippet Node.js / JavaScript

Pour votre frontend React/Vue (pour afficher le compteur en direct lors de la saisie) :

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)

N'envoyez jamais vos campagnes à l'aveugle. Implémenter cette logique dans votre application vous sauvera, vous et vos clients marocains, de factures API SMS hors de contrôle.

💡 Pourquoi choisir EnvoiSMS pour votre entreprise ?

Délivrabilité Opérateurs

Routes locales vers IAM, Orange et Inwi, avec bascule automatique entre routes et statut de livraison transmis par webhook.

💰

Optimisation Budgétaire

WhatsApp Business API dès 0,65 MAD par message. Le meilleur retour sur investissement.

🛡️

Données Souveraines (CNDP)

Hébergement conforme aux réglementations de protection des données personnelles locales.

Q.Quelle est la latence d'acheminement sur les réseaux IAM, Inwi et Orange ?
Sur nos routes locales vers Maroc Telecom (IAM), Orange et inwi, la latence moyenne de remise est comprise entre 2 et 4 secondes pour les flux transactionnels.
Q.Comment la plateforme gère-t-elle le format des numéros marocains ?
EnvoiSMS normalise automatiquement les numéros saisis (06..., 07..., 00212...) vers le standard E.164 (+212) pour éviter tout échec de distribution.

Articles suggérés

Formatage SMS au Maroc : Sauts de ligne, Encodage GSM-7 vs UCS-2 et Optimisation des Coûts
technical

Formatage SMS au Maroc : Sauts de ligne, Encodage GSM-7 vs UCS-2 et Optimisation des Coûts

Formatage WhatsApp Business au Maroc : Texte Enrichi, Emojis et Boutons Interactifs
technical

Formatage WhatsApp Business au Maroc : Texte Enrichi, Emojis et Boutons Interactifs

Chatbot WhatsApp en Darija Marocain : Comment l'IA Traite l'Arabizi et le Mix Français-Arabe
technical

Chatbot WhatsApp en Darija Marocain : Comment l'IA Traite l'Arabizi et le Mix Français-Arabe