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.

sms marocapi smsotp 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](/fr/tarifs/) hors de contrôle.

💡 Pourquoi choisir EnvoiSMS pour votre entreprise ?

Délivrabilité Critique

Moins de 4 secondes pour vos OTP via des canaux directs opérateurs IAM, Inwi et Orange Maroc.

💰

Optimisation du Budget

WhatsApp Business API à 0,13 MAD seulement par session. Le meilleur ROI conversationnel.

🛡️

Données Souveraines (CNDP)

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