Une page de destination avec un champ de numéro de téléphone et une case à cocher donne l’impression d’un consentement. Pour un agrégateur SMS, ce n’en est pas un. Un seul appel à l’API MobileConnect peut régler ce problème, sans rien changer à l’envoi lui-même.
Le problème venait d’une page de destination promotionnelle qui recueillait un nom, une adresse courriel et un numéro de cellulaire, avec une case de consentement en dessous. À la soumission, la page inscrivait le numéro dans une Data Extension avec un champ de statut réglé à « opted in ». Une importation planifiée lisait ensuite cette Data Extension et abonnait le numéro à un mot-clé MobileConnect, ce qui rendait le numéro réellement joignable.
Rien dans ce flux ne prouve que la personne qui a saisi le numéro est celle qui tient le téléphone. L’agrégateur qui gère le code court a fini par le remarquer : toute collecte de numéros sur le Web ou dans une application doit passer par un double opt-in, ce qui signifie que c’est le téléphone, et non le formulaire, qui doit confirmer. Le mot-clé a été suspendu, les envois ont cessé, et le correctif devait être en place avant même que l’agrégateur accepte de retester la page.
Pourquoi « il suffit d’activer le double opt-in » ne règle rien
Le modèle Double Opt-In de MobileConnect est conçu autour d’un vrai texto entrant : une personne envoie un mot-clé à un code court, MobileConnect lui répond pour demander une confirmation, et une réponse YES la fait passer au statut Subscribed. C’est simple quand le point d’entrée est un texto. Ça fonctionne beaucoup moins bien quand le point d’entrée est un formulaire Web, puisqu’un formulaire ne génère jamais le message entrant auquel MobileConnect attend de réagir.
Les solutions simplistes ne tiennent pas la route : Journey SMS ne peut pas le faire (un parcours envoie à des contacts déjà abonnés; il ne peut pas effectuer l’opt-in). Un mot-clé réservé au Web évite le problème immédiat, mais exige une tâche de synchronisation en arrière-plan pour transférer les contacts confirmés vers le vrai mot-clé d’envoi, ce qui ne fait que déplacer la question « était-ce vraiment cette personne ? ». Et laisser l’importation existante continuer d’abonner les gens, c’est la faille d’origine sous une autre étiquette.
QueueMO : faire croire à l’API qu’un texto vient d’être envoyé
Le mécanisme qui comble cette lacune est un point de terminaison REST de MobileConnect, POST /sms/v1/queueMO. MO signifie « mobile-originated » (provenant du mobile). Ce point de terminaison permet à un système dorsal de mettre en file d’attente un message entrant synthétique au nom d’une personne, comme si ce numéro venait d’envoyer le mot-clé au code court.
C’est tout le secret. MobileConnect ne peut pas distinguer un message mis en file d’attente d’un vrai texto, alors il exécute le flux Double Opt-In du mot-clé exactement comme pour une personne qui texte le code court. Dès lors, le flux Double Opt-In approuvé par l’agrégateur prend le relais : un SMS de confirmation est envoyé, le contact reste au statut In Progress, et un YES tapé sur l’appareil devient la preuve de possession que le formulaire ne pouvait jamais fournir.
Un détail de séquence compte plus que tout le reste : le mot-clé doit déjà être en Double Opt-In avant que QueueMO soit activé sur la page. QueueMO utilisé avec un mot-clé Single Opt-In abonne simplement le numéro immédiatement, sans étape YES, ce qui reproduit exactement l’infraction avec un appel API de plus en amont.
À quoi ressemble concrètement la solution
Le rôle de la CloudPage elle-même est limité : valider la soumission, consigner le consentement (sans jamais le traiter comme un abonnement), puis lancer côté serveur les appels de jeton et QueueMO. Voici le chargeur de configuration et l’appel QueueMO lui-même, légèrement généralisés à partir de la vraie Code Resource :

Un appel en échec inscrit un statut distinct et affiche un message générique invitant à réessayer. Il ne doit jamais pouvoir passer pour un opt-in réussi :

Le piège sournois : aucun webhook pour le YES
MobileConnect n’émet aucun événement quand une personne répond YES à une demande Double Opt-In. Aucun rappel, aucune notification push. Pour que votre propre registre de consentement reflète la réalité, il vous faut une synchronisation planifiée. Voici un exemple de ce à quoi pourrait ressembler cette requête horaire :

_SMSSubscriptionLog n’identifie un mot-clé que par son GUID, jamais par son nom. La liste SubscriptionDefinitionID IN (…) doit donc être codée en dur, et elle échoue silencieusement si un mot-clé est reconstruit plutôt que modifié sur place.
La requête qui fait la correspondance nom → GUID :

Autres pièges qui ont coûté de vraies heures de débogage
Aucun de ces pièges n’est propre à QueueMO, mais ce sont des pièges courants de REST et de SSJS dans Marketing Cloud, et ils frappent fort la première fois qu’on construit quelque chose de semblable :
Une DE de configuration sans clé naturelle génère l’erreur peu utile « invalid data extension key field reference » si vous tentez de filtrer sur un champ qui n’existe pas vraiment. Récupérez la DE au complet et prenez la ligne 0, comme ci-dessus.
Une erreur invalid_client sur l’appel de jeton signifie généralement que la ligne de configuration pointe vers le mauvais Installed Package, et non que l’appel SMS pose problème. Faites d’abord fonctionner le jeton de façon isolée.
Vérifiez le corps JSON, pas seulement le statut HTTP. Les API REST de SFMC renvoient souvent un HTTP 200 avec un errorcode dans le corps, et c’est précisément ce que restErrorMessage() ci-dessus sert à intercepter.
Jint (le moteur SSJS de SFMC) a ses aspérités. String.prototype.trim n’est pas implémenté, et des valeurs peuvent rester étiquetées en interne comme JsNumber même après qu’on croit les avoir converties en chaîne, ce que le pont CLR derrière Insert/UpsertData rejette alors catégoriquement :

La capture de l’adresse IP du client depuis une CloudPage n’est pas fiable. Les en-têtes de transfert habituels sont souvent vides selon le chemin de la requête. Ne concevez pas un registre de conformité qui dépend de la capture de l’IP. Un horodatage, une déclaration de consentement consignée et la réponse YES de l’appareil lui-même constituent de toute façon une meilleure piste de preuves.
L’essentiel : seul le téléphone peut faire la preuve du téléphone
Un formulaire Web ne peut pas prouver qu’une personne possède un numéro de téléphone; seule une réponse envoyée depuis ce téléphone le peut. Toute la valeur de QueueMO tient au fait qu’il vous permet de continuer à recueillir des numéros sur une page Web tout en faisant passer chaque décision liée à la conformité par le canal SMS, le seul capable de vérifier réellement la possession, au moyen d’une infrastructure de mots-clés déjà approuvée par un agrégateur. Bien faire les choses coûte peu : un appel API côté serveur, un modèle Double Opt-In et une tâche planifiée pour refléter un statut qui arrive sans webhook. Se tromper coûte un code court suspendu et une campagne interrompue, alors faisons-le correctement du premier coup.


