Documentation & Encyclopédie système
Guide technique complet, répertoire des éléments d'interface utilisateur et manuel d'optimisation pour hébergement mutualisé de MarbleSend.
Architecture système & fondation d'hébergement
Philosophie : auto-hébergé, mono-tenant, zero-build, adapté à l'hébergement mutualisé
MarbleSend est conçu dès le départ pour éliminer un point douloureux bien connu des logiciels d'email marketing : le besoin d'instances VPS dédiées et coûteuses, de serveurs Redis, de pipelines de build node ou d'orchestration Docker complexe. MarbleSend fonctionne sur un hébergement mutualisé standard (cPanel, Hostinger, DirectAdmin, Plesk, LiteSpeed) en utilisant PHP 8.2+ pur sans aucune compilation côté serveur.
Zéro injection SQL
Chaque requête de base de données utilise des requêtes préparées strictes sans surcharge d'ORM.
Chiffrement au repos
Identifiants SMTP, clés API d'IA et secrets webhook chiffrés dans Crypto.php.
Aucun double envoi
Le worker réserve les lots de file d'attente de manière atomique via des mises à jour d'état MySQL avec gestion stricte des délais d'expiration.
Déploiement instantané
Tailwind CSS précompilé et Alpine.js intégré. Téléversez le zip, lancez l'installateur, c'est prêt.
0.1 Philosophie d'hébergement et runtime Zero-Build
La plupart des applications web modernes exigent des pipelines de compilation Node.js, des démons Redis, une orchestration Docker ou un accès root VPS. MarbleSend rejette cette complexité. Conçu spécifiquement pour l'hébergement mutualisé accessible (cPanel, Hostinger, Plesk, LiteSpeed), il fonctionne sur du PHP 8.2+ pur sans aucune compilation sur le serveur.
Zéro compilation sur serveur
Aucun npm, Webpack, Vite ou Composer requis sur le serveur de production. Tailwind CSS est précompilé en ressources statiques, Alpine.js est intégré localement et PHPMailer 6.9.x est directement inclus dans vendor-lite.
Faible empreinte mémoire
L'utilisation maximale de la mémoire reste inférieure à 32 Mo même lors du traitement des lots de la file d'attente d'e-mails. Fonctionne parfaitement dans les limites strictes du mutualisé (allocations de 64 Mo à 128 Mo dans php.ini).
Aucune fonction interdite
Évite strictement les fonctions dangereuses fréquemment désactivées par les hébergeurs mutualisés (exec, shell_exec, system, passthru, eval, proc_close). Toutes les opérations externes utilisent cURL natif avec timeouts.
0.2 Périmètre de sécurité et isolation des répertoires
MarbleSend met en œuvre une structure stricte à deux niveaux qui sépare les ressources web publiques du code d'application sensible et du storage, éliminant les risques de directory traversal et d'exposition de files.
Document Root isolé (public/)
Seul le répertoire public/ est exposé au serveur web. Pointez le DocumentRoot de votre domaine ou sous-domaine vers /public. Même si le listing de répertoires est activé sur Apache/Nginx, les files sources principaux ne peuvent pas être consultés.
Cœur d'application protégé (app/)
Les contrôleurs, services, bibliothèques, vues et configurations résident hors du document root dans app/. Les identifiants de base de données dans app/config/config.php et les clés de chiffrement sont inaccessibles par requête HTTP directe.
Storage et migrations sécurisés
Le répertoire storage/ (contenant les logs du worker) et migrations/ (contenant les files de schema SQL bruts) résident complètement hors de public/, empêchant tout téléchargement non autorisé.
0.3 Base de données Zero-ORM et Prepared Statements PDO
Les ORM comme Eloquent ou Doctrine introduisent une surcharge mémoire massive, des couches d'hydratation complexes et des requêtes N+1 imprévisibles. MarbleSend utilise directement PDO natif avec 100% de prepared statements.
100% Prepared Statements
Chaque requête lie explicitement ses paramètres (PDO::PARAM_STR, PDO::PARAM_INT). Les structures SQL et les données utilisateur ne se mélangent jamais, offrant une immunité totale contre les injections SQL.
Requêtes prévisibles à haute performance
L'exécution SQL directe élimine la surcharge d'hydratation ORM, exécutant les opérations de liste et les mises à jour par lot de la file jusqu'à 5 fois plus vite avec une consommation CPU minime sur base partagée.
Migrations de schema idempotentes
Les versions de base de données sont tracées via des files SQL numérotés (0001_initial.sql à 0019_add_feedback_attachment.sql) exécutés par un exécuteur idempotent doté de clauses IF NOT EXISTS et enregistrés dans cm_migrations.
Isolation des données Single-Tenant
Conçu comme un logiciel autonome single-tenant sans colonne tenant_id. Les index restent compacts, les scans séquentiels sont évités et le risque de fuite de données inter-clients est nul.
0.4 Chiffrement au repos et normes cryptographiques
Les secrets sensibles ne sont jamais stockés en texte clair. MarbleSend chiffre les identifiants à l'aide d'une cryptographie symétrique authentifiée standard de l'industrie via App\Lib\Crypto.
Chiffrement AES-256-GCM
Utilise Advanced Encryption Standard en mode Galois/Counter (AES-256-GCM), offrant à la fois confidentialité et vérification d'intégrité cryptographique pour détecter toute altération.
IV aléatoire unique de 96 bits
Chaque valeur chiffrée génère un vecteur d'initialisation (IV) aléatoire sécurisé de 12 octets (96 bits) via random_bytes(), garantissant que des textes identiques produisent des ciphertexts entièrement différents.
Catalogue de secrets chiffrés
Protège automatiquement les mots de passe de relais SMTP, les clés API d'IA BYOK (OpenAI, Claude, Gemini, DeepSeek, Kimi, OpenRouter), les secrets de signature de webhook et le Purchase Code Envato.
Isolation de la clé principale
La clé ENCRYPTION_KEY de 32 octets est générée à l'installation et conservée exclusivement dans app/config/config.php (chmod 0600). La base de données ne contient jamais la clé de chiffrement.
0.5 Dual-Worker Engine et sécurité de concurrence
MarbleSend délègue toutes les tâches planifiées et exigeantes en temps à un worker d'arrière-plan unifié, garantissant que le dashboard d'administration reste rapide et réactif à tout instant.
Exécuteur d'arrière-plan maître unique
worker.php coordonne l'envoi des lots de la file, l'exécution des planifications récurrentes, la récupération des flux RSS, le déclenchement des autorépondeurs et le renvoi des campagnes non ouvertes.
Flexibilité CLI Cron et Web-Cron
Exécution via la crontab système native (* * * * * php /path/to/worker.php) ou via un ping HTTP externe sécurisé vers /cron.php?key=YOUR_KEY. Les deux voies appliquent une logique identique.
Revendication atomique de file (aucun double envoi)
Les instances de worker réservent les lots de file par des mises à jour d'état SQL atomiques (UPDATE cm_email_queue SET status = 'processing' WHERE status = 'pending' LIMIT N). Même des exécutions simultanées n'envoient jamais d'e-mails en double.
Heartbeat et récupération des tâches bloquées
Enregistre le heartbeat d'exécution dans cm_settings. Si un worker est interrompu en plein envoi (ex: timeout de l'hôte), les exécutions ultérieures détectent et restaurent automatiquement les éléments bloqués.
0.6 Prérequis serveur et matrice de compatibilité d'hébergement
MarbleSend est certifié compatible avec tous les environnements d'hébergement mutualisé standards, panneaux de configuration et configurations serveur respectant les spécifications de base PHP 8.2+.
| Composant | Configuration minimale | Recommandé | Remarques opérationnelles |
|---|---|---|---|
| Environnement PHP | PHP 8.2.0+ | PHP 8.2 ou 8.3 | strict_types=1 déclaré sur l'ensemble des files de l'application. |
| Moteur de base de données | MySQL 8.0+ / MariaDB 10.6+ | MariaDB 10.11+ ou MySQL 8.0+ | Moteur InnoDB obligatoire. Encodage UTF8MB4 full Unicode. |
| Extensions requises | pdo_mysql, openssl, mbstring, json, curl, simplexml, sodium | Toutes les extensions standard activées | Standard sur 99% des hébergements mutualisés. Optionnel: intl pour le formatage régional. |
| Serveur Web | Apache, Nginx, LiteSpeed, Caddy | Apache + mod_rewrite ou LiteSpeed | Files .htaccess préconfigurés inclus à la racine et dans public/. |
| Allocation mémoire | 32 Mo memory_limit | 64 Mo - 128 Mo | Les fragments de file sont traités par lots mesurés pour prévenir tout dépassement mémoire. |
| Planificateur Cron | CLI crontab OU ping HTTP Web-Cron | CLI cron chaque minute | Point d'accès de secours Web-Cron (/cron.php?key=...) pour les hôtes sans accès CLI. |
Panneaux de contrôle d'hébergement testés
Entièrement testé et vérifié sur cPanel, Hostinger hPanel, Plesk, DirectAdmin, CyberPanel, AApanel, CloudPanel et les piles classiques Ubuntu/Debian LAMP/LEMP.
Aperçu du tableau de bord (/dashboard)
Centre de commande agrégé pour la santé de l'audience, les KPI de distribution, le battement de cœur du worker et l'automatisation des Schedules.
Anatomie des composants du tableau de bord & inspecteur de support
Survolez ou cliquez sur un élément ci-dessous pour voir les détails d'arrière-planTotal envoyés
Agrégation des logs & compteur mensuelOuverts / Taux d'ouverture
Pixel de suivi 1x1 & note Apple MPPCliqués / CTR
Injecteur de redirection de clicsAudience désinscrite
Taux de désinscription & conformité RFCBattement de cœur du worker
Statut du cron & intervalle de 1 minGraphique de croissance du volume
Échelle 7j, 30j, 90j, YTDTableau des diffusions récentes
Cycle de vie des statuts & piste d'auditSanté de la délivrabilité
Disponibilité du profil SMTP1.1 Cartes KPI de performance des e-mails
| Élément | Calcul & source | Signification visuelle | Justification de prévention du support |
|---|---|---|---|
| Carte Total envoyé | COUNT(cm_email_logs) + SUM(cm_campaigns.sent_count) | Affiche le total historique des e-mails de broadcast et de schedule expédiés. Le sous-texte indique le volume envoyé ce mois civil. | Évite toute confusion lorsque les anciennes entrées de journal sont nettoyées ; les compteurs historiques de Campaigns garantissent que les totaux ne diminuent jamais. |
| Total ouverts / Taux d'ouverture | COUNT(DISTINCT contact_id WHERE opened_at IS NOT NULL) / Total Sent * 100 | Mesure l'engagement via un pixel de suivi transparent 1x1 injecté dans le pied de page HTML de l'e-mail. | Avertissement Apple MPP : iOS Mail Privacy Protection précharge les images via le proxy d'Apple, ce qui peut gonfler artificiellement les ouvertures. Le CTR reste la véritable métrique commerciale. |
| Total cliqués / CTR | COUNT(DISTINCT contact_id WHERE clicked_at IS NOT NULL) / Total Sent * 100 | Mesure les clics uniques des abonnés sur les liens. Réécrits via /track/click.php. | Les liens de désinscription et de confirmation sont exclus du CTR de la Campaign afin de préserver l'intégrité statistique. |
| Carte Désinscrits | COUNT(status = 'unsubscribed') / Total Contacts * 100 | Taux de destinataires de la liste qui se sont désinscrits via le mécanisme obligatoire de désinscription en un clic. | Le seuil sain est < 0,5 %. Un taux de désinscription > 1 % indique une fatigue de l'audience, des listes achetées ou un manque de pertinence. |
Total envoyé & Débit mensuel
Suit le total historique des e-mails expédiés avec succès via les diffusions, les plannings récurrents, les flux RSS et les répondeurs automatiques. Le sous-texte met en évidence le volume expédié au cours du mois civil actif. Parce que MarbleSend agrège les compteurs historiques de Campaigns aux logs d'envoi actifs, les totaux globaux restent permanents même lors du nettoyage de la base de données.
Ouvertures uniques & dynamique Apple MPP
Enregistré via un pixel de suivi transparent 1x1 injecté dans le pied de page HTML de l'e-mail. Les ouvertures sont suivies de manière unique par contact par Campaign (horodatage au premier contact). Remarque essentielle : Apple Mail Privacy Protection (MPP) met en cache les images via des serveurs proxy, gonflant artificiellement les ouvertures. Le CTR reste le véritable indicateur d'intention de conversion.
Clics uniques & moteur de réécriture d'URL
Chaque lien standard du corps de l'e-mail est réécrit pour passer par /track/click.php, consignant l'ID de contact, l'ID de Campaign, l'URL de destination et l'horodatage avant redirection. Pour garantir la confiance et la conformité, les liens de désinscription (/unsubscribe.php) et de confirmation (/confirm.php) sont strictement exempts de suivi.
Contacts désinscrits & Protection du domaine
Mesure les abonnés désinscrits via le lien du corps du message ou l'en-tête List-Unsubscribe RFC 8058. Une liste saine maintient un taux sous 0,5 %. Au-delà de 1,0 %, MarbleSend avertit les administrateurs de réviser la qualité de la liste afin d'éviter que les messageries (Gmail, Yahoo, Outlook) ne dégradent la réputation du domaine.
1.2 Opérations & battement de cœur du worker
MarbleSend repose sur un gestionnaire d'arrière-plan principal unique : worker.php. Le tableau de bord inspecte cm_settings['worker_last_run'] pour déterminer si le cron s'exécute bien toutes les 60 secondes.
État actif (Cron sain)
Lorsque worker.php s'est exécuté dans les 3 dernières minutes, le badge indique Actif. Les lots de la file d'attente sont traités en temps réel, les newsletters planifiées se déclenchent à l'heure et les répondeurs automatiques partent promptement.
État inactif (Cron non détecté)
Si aucun battement de cœur n'est enregistré depuis plus de 3 minutes, le badge devient rouge. Cliquer sur la carte mène immédiatement à Settings → Système avec la commande CLI crontab exacte et l'URL Web-Cron de secours.
Contacts actifs vs Audience totale
Affiche les contacts au statut actif par rapport à la base d'abonnés totale. MarbleSend applique une machine d'état stricte à 4 niveaux : active, pending (en attente du double opt-in), unsubscribed et suppressed (bounces/plaintes). Les workers de Campaign filtrent strictement selon WHERE status = 'active'.
Volume de Campaigns mensuel & global
Résume les diffusions envoyées durant le mois civil actif ainsi que le total historique de Campaigns. Offre une visibilité immédiate sur le rythme d'envoi et la cadence marketing.
Résolution du prochain calendrier prévu
Interroge les planifications récurrentes actives (triées par next_run_at ASC LIMIT 1) et affiche la prochaine newsletter en attente. Toutes les exécutions sont calculées exclusivement par SchedulerService::computeNextRun() avec prise en charge intégrale des fuseaux horaires et stockage UTC.
Battement de cœur du worker & Cron d'hébergement partagé
Le battement de cœur vérifie si worker.php a fonctionné au cours des 180 dernières secondes. Sur hébergement mutualisé (cPanel, Hostinger), configurez le crontab sur * * * * * php /chemin/vers/worker.php >/dev/null 2>&1. En l'absence de CLI cron, utilisez le point d'accès Web-Cron de secours (/cron.php?key=VOTRE_CLE).
1.3 Visualiseur de croissance des Campaigns
Le visualiseur de croissance restitue la distribution du volume sur quatre périodes sélectionnables : 7 jours, 30 jours, 90 jours et depuis le début de l'année (YTD). Chaque barre représente un segment temporel agrégé, affichant le nombre d'envois et d'ouvertures au survol.
Permet de basculer instantanément entre cadence hebdomadaire (7 jours), cycles mensuels (30 jours), performances trimestrielles (90 jours) et volume annuel (depuis le début de l'année).
Rendu à l'aide de hauteurs flexbox CSS pures calculées par rapport au volume maximal d'envoi. Évite les bibliothèques JavaScript lourdes et charge instantanément sur mobile.
Le survol d'une barre révèle l'intervalle exact, les messages envoyés et le volume d'ouvertures uniques pour une analyse comparative rapide.
Flux d'envois en direct & battement de cœur
Le flux de la colonne de droite présente les récentes expéditions de Campaign en direct avec des badges de statut animés (Completed, Sending pulsant, Failed, Draft), les ratios de livraison et l'état du système.
status = 'completed'
status = 'sending'
status = 'failed'
status = 'draft'
Historique des Campaigns & Tableau d'audit
Le tableau d'audit inférieur répertorie les récentes diffusions avec métadonnées : nom de Campaign, statut, origine (manual, schedule, rss, auto_resend), ratio destinataires/envoyés et taux d'ouverture vérifié.
Affiche l'objet de la Campaign, la date de création et le tag d'origine (manual, recurring, rss ou resend_unopened).
Compte instantané des messages délivrés par rapport aux échecs, ainsi que les pourcentages en direct du taux d'ouverture et de clics.
Raccourci direct vers la page de rapport de la Campaign pour consulter les logs d'événements par destinataire et la modale de renvoi aux non-ouverts.
1.6 Raccourcis d'actions rapides & Automatisation des flux
Accélérateurs reliant le tableau de bord aux flux stratégiques : newsletters récurrentes automatisées, intégration de flux RSS-vers-email, capture de listes d'abonnés, conformité double opt-in et suppression automatique.
Flux d'automatisation (Récurrent & RSS)
Déclenche des envois d'e-mails automatiques sur base de plannings cron ou dès qu'un flux RSS WordPress/Ghost/Substack connecté publie un nouveau contenu.
Gestion de l'audience & des abonnés
Permet l'import rapide d'abonnés par CSV, la segmentation de listes, l'application du double opt-in et l'exclusion automatique des adresses non valides.
Gestionnaire de Campaigns & rapports (/campaigns)
Éditeur d'envoi ultra-rapide, sélecteur de destinataires ciblé par tags, moteur de sécurité pré-vol et rapports de livraison détaillés.
Interactive Campaigns UI Inspector
Cliquez sur n'importe quel composant pour inspecter l'impact sur le schéma et les conseils opérationnelsMoniteur d'Envoi Live
Statistiques et événements en temps réelSélecteur de Destinataires
Filtrage par tag et sélection globaleÉditeur Triple Vue
Code, split et aperçuMoteur de Vérification Preflight
Inspection automatique en 6 pointsDiagnostic d'Envoi Test
Échantillon direct sans fileRéécriveur UTM et Liens
Paramètres UTM et suivi 302Historique des Diffusions
Filtres de status et d'origineRapport Détaillé Post-Envoi
CTR, MPP et réexpédition auto2.1 Bannière de surveillance en direct de la Campaign
Dès qu'un envoi de broadcast est en cours, une bannière de suivi persistante s'affiche en haut de /campaigns. Elle interroge /api/campaigns/:id/progress toutes les 1,5 seconde sans recharger la page.
Summer Launch Newsletter
Sending74% complete
7,420 / 10,000 emails
En Attente
2,528
Envoi en cours
40
Succès
7,420
Échoué
12
Recent Events Real-time status
Moteur de Polling à 1,5 Seconde
Interroge /api/campaigns/:id/progress de manière asynchrone toutes les 1,5 seconde, affichant le débit en direct sans recharger la page.
Flux d'Événements Récents de Livraison
Journal en direct affichant les 5 derniers changements de status des destinataires avec confirmations de remise et diagnostics d'erreur SMTP.
Si le worker.php en arrière-plan est ralenti ou le cron inactif, un badge d'alerte fournit des instructions de dépannage en un clic.
2.2 Sélecteur de destinataires & filtres de tags (Colonne de gauche)
La colonne de gauche permet un ciblage d'abonnés très précis. Les administrateurs peuvent filtrer par tags personnalisés de contact, rechercher par e-mail/nom partiel, et sélectionner des contacts individuels ou cliquer sur Tout sélectionner.
Garantie de filtrage de la machine à états :
Quelle que soit la sélection ou la recherche, le moteur de requêtes applique strictement status = 'active'. Les contacts désinscrits, en attente ou bloqués sont automatiquement exclus de la file d'attente.
Intersections Multi-Tags
Sélectionnez des segments précis d'abonnés via des tags. Le sélecteur calcule dynamiquement les effectifs croisés en temps réel.
Recherche Live avec Debounce (300ms)
Recherche instantanée filtrant les contacts par nom ou e-mail avec un délai de 300ms pour éviter de surcharger la base de données.
Commandes Centralisées de Sélection
Cochez des contacts individuels ou utilisez Tout Sélectionner pour cibler l'ensemble des contacts correspondant au filtre actif en un clic.
Groupes
Les contacts sont organisés en groupes (un contact peut appartenir à plusieurs groupes ; chaque contact est dans au moins un, General par défaut). Dans Select Recipients, choisissez « Par groupe » pour envoyer à chaque contact actif des groupes choisis — le groupe entier, pas seulement la page affichée — ou « Choisir manuellement » pour sélectionner des contacts individuels (filtrage facultatif par un groupe).
Les groupes peuvent aussi servir d’audience à une planification, de déclencheur à une règle d’autoresponder, de destination à une page d’inscription et pour restreindre un renvoi aux non-lecteurs. Supprimer un groupe ne supprime jamais ses contacts ; les règles d’autoresponder qui en dépendent sont désactivées.
2.3 Compositeur de Campaign & modes d'édition partagés
Mode partagé
Édition simultanée du code à gauche et aperçu en direct dans un iframe réactif à droite.
Mode code seul
Éditeur de code HTML pleine largeur sans distraction avec numéros de ligne dans la marge et onglets de syntax.
Mode aperçu en direct
Rendu isolé avec bascules d'affichage Desktop (100%), Tablette (600px) et Mobile (375px).
Variables de Remplacement et Moteur de Substitution
Personnalisez les e-mails dynamiquement à l'aide des tags {{name}}, {{email}}, {{unsubscribe_link}}, {{offer_url}} et {{track_pixel}}.
Viewports Responsives en Sandbox
Testez l'affichage sur mobile (375px), tablette (600px) et ordinateur (100%) au sein d'une iframe isolée avant tout envoi.
2.4 Contrôle de sécurité pré-vol automatisé en 6 points
Pour éviter des erreurs désastreuses (ex. envoyer des e-mails avec des variables cassées, des liens de désinscription manquants ou des termes spams), MarbleSend exige un contrôle pré-vol avant le lancement.
| Contrôle de sécurité | Sévérité | Règle & détection | Conséquence en cas d'échec |
|---|---|---|---|
| 1. Lien de désinscription | CRITIQUE | Vérifie la présence du token {{unsubscribe_link}}. | L'envoi est BLOQUÉ. Obligatoire selon CAN-SPAM, RGPD et les exigences expéditeurs Yahoo/Google 2024. |
| 2. Validité des variables | CRITIQUE | Détecte les balises de remplacement inconnues (ex. fautes comme {{first_nam}}). | Envoi bloqué jusqu'à ce que les balises inconnues soient corrigées ou supprimées. |
| 3. Audience de destinataires | CRITIQUE | Vérifie que plus de 0 destinataire actif est sélectionné. | Impossible d'envoyer à une sélection vide. |
| 4. Connectivité SMTP | CRITIQUE | Vérifie l'hôte et les identifiants du profil SMTP sélectionné. | Évite le blocage de la file d'attente causé par de mauvais identifiants de relais. |
| 5. Mots déclencheurs de spam | AVERTISSEMENT | Analyse l'objet et le corps pour détecter des expressions à risque (« 100% gratuit », « agissez maintenant », « offre limitée »). | Bannière d'avertissement affichée ; l'administrateur peut examiner et continuer. |
| 6. Longueur de l'objet | INFO | Recommande 30 à 60 caractères pour éviter la troncature sur les écrans mobiles. | Notice informative pour obtenir de meilleurs taux d'ouverture. |
Portail de Contrôle Preflight
Vérifie 6 règles de sécurité automatisées avant la mise en file d'attente. Tout échec critique désactive le bouton d'envoi.
2.5 Diagnostic d'envoi de test & modale de confirmation
Avant de confier des milliers d'e-mails à la file d'attente, le bouton Envoyer un e-mail de test expédie instantanément un e-mail de test unique à l'administrateur ou à la boîte QA sans toucher à la liste des destinataires en base. Toutes les balises ({{first_name}}, {{email}}, {{unsubscribe_link}}) sont remplies avec des valeurs d'aperçu fictives afin que vous puissiez contrôler le rendu sur Gmail, Apple Mail et Outlook.
Interpolation de Données de Test
Remplace les variables par des valeurs réalistes (ex: Jane Doe, lien de désinscription démo) pour une vérification visuelle authentique.
Modal de Validation Pré-Lancement
Confirmation en deux étapes affichant le volume de destinataires, le profil d'expéditeur et les tags UTM actifs avant validation.
2.6 Injection automatisée du suivi UTM
Toutes les balises d'ancrage sortantes (<a href="...">) sont traitées via App\Services\TrackingInjector. Les paramètres UTM (utm_source, utm_medium, utm_campaign, utm_content) sont ajoutés automatiquement avant l'encapsulation de redirection de clics. Les liens mailto, tel et de désinscription restent intacts.
Étape 1: Injection de Paramètres UTM
Ajoute utm_source, utm_medium, utm_campaign et utm_content à chaque lien sans modifier les paramètres existants.
Étape 2: Insertion du Pixel de Suivi
Insère une image GIF transparente 1x1 avant la balise fermante </body> pour enregistrer l'ouverture lors de l'affichage.
Étape 3: Moteur de Redirection 302
Réécrit les URLs vers /track/click.php?h=... pour des redirections instantanées à faible latence avec télémétrie du premier clic.
Exemptions Strictes de Conformité
Les liens de désabonnement, protocoles mailto/tel et liens double opt-in sont strictement exclus des UTM et du suivi des clics.
2.7 Historique & portfolio des Campaigns (/campaigns/history)
Le portfolio d'historique complet offre un filtrage multi-critères par origine (manual, recurring, rss, resend_unopened), statut (completed, sending, failed, draft) et plage de dates. Les administrateurs peuvent sélectionner plusieurs Campaigns pour télécharger les logs de livraison groupés au format CSV.
Pipeline de Suivi d'Origine
Classe les envois par source: Composer manuel, Plannings récurrents, Déclencheurs de blog RSS ou Réexpéditions aux non-ouvreurs.
Filtrage Multi-Status et Export CSV
Filtrez l'historique par états terminé, en cours, échoué et brouillon. Téléchargez les journaux détaillés en un clic.
Duplication d'Envoi en un Clic
Dupliquez toute diffusion passée dans le composer en conservant le code HTML complet, la ligne de subject et les réglages de l'expéditeur.
2.8 Rapports d'analyse & fonctionnalité « Renvoyer aux non-ouverts »
Facultatif : choisissez des groupes pour ne renvoyer qu'aux non-lecteurs qui en font partie. Un renvoi ne dépasse jamais les destinataires de la campagne d'origine.
Sous /campaigns/:id/report, MarbleSend présente un rapport d'après-campagne complet :
4 Indicateurs de Performance Bento
Mesure le volume Envoyé (100%), les Échecs, les Ouvertures uniques avec taux d'ouverture et les Clics uniques avec CTR.
Courbe d'Engagement Horaire
Affiche les pics d'ouvertures heure par heure sur les premières 72 heures afin d'identifier les meilleurs créneaux d'envoi.
Réexpédition Ciblée aux Non-Ouvreurs
Clone la Campaign en ciblant les abonnés avec opened_at IS NULL, permettant de tester un nouveau subject pour générer 15 à 25% d'ouvertures supplémentaires sans lasser les lecteurs actifs.
Hub de contacts & outils de croissance (/contacts)
Gestion du cycle de vie des abonnés, import CSV, conformité RGPD, pages d'inscription personnalisées et autorépondeurs.
Inspecteur d'Interface Interactif des Contacts
Cliquez sur un composant pour inspecter l'impact sur le schéma et les conseils opérationnelsMachine à 4 États
active/pending/unsub/suppMoteur de Recherche et Filtres
Tags, statut et debounceVolet d'Audit et Consentement
IP, horodatages et rebondsImportateur CSV RFC 4180
50k lignes et déduplicationPages de Capture Hébergées
Double opt-in et entonnoirsAutoresponders par Tag
Règles de goutte-à-goutte par événementHub de Gestion en Masse
Segmentation multi-pagesConfidentialité RGPD et Purge
Export JSON et suppression totale3.1 Machine à états des abonnés à 4 états
MarbleSend maintient une machine à états stricte et unifiée pour tous les contacts. Il n'y a aucun indicateur booléen secondaire. Chaque pipeline d'envoi applique WHERE status = 'active'.
Abonné actif
Opt-in confirmé, e-mail valide. Éligible pour recevoir des Campaigns, des Schedules et des autorépondeurs.
Double Opt-In en attente
Inscrit via un formulaire double opt-in, en attente du clic sur l'e-mail de confirmation. Exclu des diffusions jusqu'à confirmation.
Désinscrit
A cliqué sur le lien de désinscription. Ne recevra plus jamais d'envoi. Ne peut pas être réactivé manuellement sans réengagement explicite.
Rebond dur / Plainte
Bloqué de manière permanente en raison d'une boîte invalide (erreur SMTP 5xx), d'une plainte pour spam ou d'un blocage manuel par l'administrateur.
| Statut | Déclencheur de Transition | Statut Cible | Impact sur l'Envoi des Campaigns |
|---|---|---|---|
| active | L'abonné clique sur le lien de désinscription ou l'en-tête RFC 8058 | unsubscribed | Immédiatement exclu de toutes les futures files d'attente de broadcast et planifications. |
| active | Rebond permanent SMTP 5xx ou 3e rebond temporaire consécutif | suppressed | Placé en quarantaine permanente afin de protéger la réputation du domaine expéditeur. |
| pending | L'abonné clique sur le lien de confirmation contenant le token de double opt-in | active | Promu au statut active ; éligible à la réception des Campaigns et autoresponders. |
| suppressed | Levée manuelle de la quarantaine par l'administrateur avec confirmation | active | Compteur de rebonds temporaires réinitialisé ; réintégré dans les files d'envoi actives. |
Garde d'Architecture : Zéro Indicateur Booléen Secondaire
MarbleSend impose une colonne ENUM unique (cm_contacts.status). D'autres plateformes subissent souvent des corruptions de données lorsque des indicateurs booléens tels que is_active, is_unsubscribed et is_bounced entrent en conflit. Dans MarbleSend, chaque requête d'envoi contient WHERE status = 'active' sans ambiguïté.
3.2 Filtres en temps réel, recherche & actions de ligne
La table des Contacts propose un filtrage réactif instantané avec Alpine.js par pastilles de tags, statut d'abonné (active, pending, unsubscribed, suppressed) et recherche textuelle sans à-coups sur l'e-mail et le prénom/nom.
Chaque contact appartient à au moins un groupe (General par défaut). Utilisez le filtre Groupes pour restreindre le tableau et Gérer les groupes pour créer, renommer ou supprimer des groupes — supprimer un groupe ne supprime jamais ses contacts.
Stockage et Normalisation des Tags JSON
Les tags sont stockés sous forme de tableaux JSON normalisés dans cm_contacts.tags. Ils sont insensibles à la casse, nettoyés et indexés pour un filtrage instantané.
Recherche Instantanée avec Debounce de 300ms
Les requêtes recherchent simultanément sur l'e-mail, le prénom et le nom avec une temporisation de 300ms pour préserver les ressources de la base de données.
Pagination Côté Serveur et Volumétrie
Parcourez aisément des listes de plus de 50 000 abonnés grâce à des requêtes SQL LIMIT et OFFSET optimisées avec un faible impact mémoire.
Mettre à jour le nom, les métadonnées personnalisées et les badges de tags en ligne sans rechargement.
Bloquer instantanément un contact pour le disqualifier immédiatement de toutes les files d'attente.
Supprime définitivement le profil du contact, les logs et les éléments de file d'attente conformément à l'article 17 du RGPD.
3.3 Volet de détails, piste d'audit RGPD & export JSON
Cliquer sur une ligne de contact fait glisser le volet d'audit. Il présente les métriques historiques (total des e-mails reçus, taux d'ouverture, nombre de clics), l'adresse IP d'opt-in, l'horodatage d'opt-in, le slug du formulaire d'inscription et un bouton en un clic Exporter en JSON RGPD pour se conformer aux articles 15 (Droit d'accès) et 20 (Portabilité des données).
Horodatage d'Opt-in et Source de Consentement
Enregistre la date, l'heure exacte et le canal d'acquisition (Manuel, Import CSV, slug de Page d'Inscription ou API) pour contrôle légal.
Capture de l'Adresse IP Vérifiée
Capture l'adresse IP de l'abonné au moment de la soumission du formulaire, constituant une preuve irréfutable sous le RGPD et CAN-SPAM.
Télémétrie d'Engagement Historique
Suit le volume cumulé d'envois ainsi que les horodatages d'ouverture vérifiés pour identifier les abonnés actifs des inactifs.
Escalade Automatique des Rebonds Temporaires
Compte les échecs temporaires de livraison consécutifs (X / 3). Dès le 3e rebond temporaire consécutif, le statut bascule automatiquement vers suppressed.
3.4 Importateur CSV & mappage de colonnes
L'importateur traite les files CSV jusqu'à 50 000 lignes. Il détecte automatiquement les délimiteurs (virgule, point-virgule, tabulation) et fournit des menus déroulants visuels pour mapper les colonnes vers : E-mail, Prénom, Nom et Tags.
Choisissez les groupes que rejoignent les contacts importés (General si aucun). Les contacts existants sont ajoutés à ces groupes ; ils ne sont jamais retirés des groupes auxquels ils appartiennent déjà.
Téléversement par Lots Préservant la Mémoire
Traite des fichiers jusqu'à 50 000 lignes par segments transactionnels, maintenant la mémoire en dessous de 32MB même sur un hébergement partagé contraint.
Détection Automatique du Séparateur et Mappage
Détecte les virgules, points-virgules et tabulations automatiquement, avec affectation visuelle pour E-mail, Prénom, Nom et Tags.
Tagging de Groupe et Audit Post-Importation
Attribue un tag global à tous les contacts importés et affiche un compte rendu détaillé des enregistrements insérés, mis à jour ou ignorés.
Ignorer les doublons
Conserve les coordonnées et les tags existants du contact. Seules les nouvelles lignes sont insérées.
Mettre à jour les champs vides
Remplit les noms manquants et ajoute les nouveaux tags sans écraser les données existantes.
Tout remplacer
Met à jour complètement les noms et les tags pour correspondre au file CSV entrant.
3.5 Pages d'inscription publiques (/s/:slug)
Situé sous l'onglet 2 de Contacts. Créez des pages d'inscription autonomes à votre image avec titre, description, libellés de champs et boutons d'envoi personnalisés. Les fonctionnalités incluent :
Choisissez les groupes que rejoignent les abonnés de cette page (General si aucun). Les groupes supprimés plus tard sont ignorés automatiquement.
Surveille le cumul des impressions sur l'ensemble des entonnoirs d'inscription actifs.
Calcule le ratio soumissions/vues sur l'ensemble des formulaires de capture hébergés.
Indique le nombre de pages d'atterrissage actives par rapport à la capacité maximale de 20 pages.
Suit les nouvelles adresses collectées au cours de la période glissante des 30 derniers jours.
Intégration d'Intégration Multi-Canaux
Intégrez les formulaires partout via l'URL hébergée (/subscribe?slug=...), code HTML brut, iframe adaptatif ou popup modale.
Génère des tokens de confirmation signés par HMAC avec envoi automatique d'un e-mail de confirmation.
Attribue des tags désignés dès l'inscription pour déclencher des séquences automatisées ciblées.
Redirige les nouveaux abonnés vers votre page de remerciement ou l'URL de votre offre après l'inscription.
3.6 Autorépondeurs & séquences automatisées
Se trouve dans l'onglet 3 de Contacts. Configurez des e-mails de bienvenue automatiques mis en file dès qu'un nouvel abonné devient actif — juste après l'inscription ou après la confirmation du double opt-in. Une règle correspond à une étiquette ou à un groupe ; il n'y a pas de réglage de délai. Les e-mails sont envoyés par le worker en arrière-plan et respectent automatiquement les règles de suppression.
Une règle peut se déclencher sur un groupe plutôt que sur une étiquette. Les règles de groupe s'exécutent lorsqu'un nouveau contact actif est créé dans ce groupe ou confirme par e-mail — pas lorsqu'un contact existant est ajouté au groupe plus tard (comme les règles d'étiquette). Supprimer le groupe désactive la règle.
Écouteur d'Événements par Tag
Se déclenche lorsqu'un nouvel abonné actif porte l'étiquette de la règle ou appartient à son groupe — juste après une page d'inscription, un appel API ou un ajout manuel (single opt-in), ou une fois le double opt-in confirmé. Ne se déclenche pas pour les imports CSV, ni lorsqu'une étiquette ou un groupe est ajouté plus tard à un contact existant.
Routage SMTP Dédié
Achemine les e-mails transactionnels de bienvenue via des profils SMTP dédiés à haute réputation, dissociés des diffusions de masse.
Traitement Asynchrone par le Worker
Confie le rendu et l'envoi à worker.php, prévenant les blocages web et garantissant une réponse instantanée aux formulaires.
Protection Anti-Boucle et Déduplication
Empêche les activations redondantes, garantissant qu'un abonné ne reçoit jamais d'e-mail de bienvenue en double s'il est étiqueté à nouveau.
3.7 Gestion par lots & segmentation de liste (/contacts/list)
Sous /contacts/list, gérez les listes volumineuses grâce aux opérations par lots : sélection sur plusieurs pages, ajout ou suppression de tags en masse, blocage de milliers de prospects froids simultanément ou export de segments ciblés dans des files CSV UTF-8.
Ajouter au groupe et Retirer du groupe s'appliquent à chaque contact sélectionné. Retirer un contact de son dernier groupe le remet dans General.
Ajout de Tags en Masse
Ajoute des tags à tous les contacts sélectionnés en une seule requête sans effacer leurs tags existants.
Suppression de Tags en Masse
Retire des tags ciblés avec exactitude parmi les contacts choisis au sein de multiples listes.
Export CSV Filtré
Télécharge directement un sous-ensemble filtré d'abonnés au format CSV RFC 4180 avec toutes les métadonnées.
Mise en Quarantaine en Masse
Isole immédiatement les contacts inactifs ou à risque pour préserver le score de réputation expéditeur.
Désinscription en Masse
Traite les demandes de désabonnement groupées provenant de sources externes ou de campagnes hors ligne.
Purge Définitive RGPD
Supprime définitivement les données des abonnés et les journaux de suivi associés conformément à l'Article 17 du RGPD.
3.8 Confidentialité RGPD, Export d'Audit et Normes d'Effacement
Outils de confidentialité intégrés strictement conformes au Règlement Général sur la Protection des Données (RGPD) de l'UE, au CCPA et au CAN-SPAM.
L'export GDPR (JSON) liste aussi les groupes auxquels appartient le contact.
Articles 15 & 20 : Export JSON Structuré
Génère un dossier JSON complet et structuré comprenant le profil de l'abonné, l'IP de consentement, les horodatages et les logs d'envoi.
Article 17 : Droit à l'Effacement (Suppression Définitive)
La suppression définitive s'applique en cascade sur cm_contacts, cm_email_logs et cm_email_queue, détruisant toute donnée identifiable.
Sécurité lors de la Réactivation d'Adresses Supprimées
Exige une validation administrative explicite pour réactiver une adresse mise en quarantaine, évitant tout envoi vers des boîtes erronées.
Studio de modèles & rédacteur IA (/templates)
8 mises en page d'e-mail à base de tableaux, aperçu en iframe isolé avec réinitialisation CSS miniature, rédacteur IA orienté vente et articles d'actualité en Markdown pour les newsletters.
Inspecteur d'Interface Templates Studio
Cliquez sur n'importe quel composant ci-dessous pour afficher les requêtes de base de données, l'impact sur le schéma et les conseils opérationnelsBibliothèque de Templates
Recherche instantanée & clés de slugDispositions Starter
8 mises en page d'emails basées sur tableauxÉditeur de Code Brut
Indentation Tab & formateurViewport Isolé
Cadre bureau & mobilePalette de Tokens Dynamiques
Injection de placeholders en 1 clicExpéditeur d'Email de Test
Modal de vérification SMTP en directVolet AI Copywriter
Générer & affiner les templatesRéviseur d'Objets
Score 1–100 & audit anti-spamArticles d'actualité
Articles Markdown pour newsletters4.1 Bibliothèque de Templates, Slugs Personnalisés & Gestion des Métadonnées
Dépôt centralisé pour tous les templates d'emails marketing, transactionnels et autoresponders. Propose un filtrage instantané côté client, des slugs d'URL immuables et des indicateurs d'état de brouillon en direct.
Slugs de Templates Immuables
Les identifiants slug (#monthly-newsletter) sont définis à la création et verrouillés lors de l'enregistrement. Cela garantit que les Campaigns RSS automatisées et les autoresponders ne se rompent jamais.
Recherche Instantanée avec Debounce
Filtre Alpine rapide côté client qui recherche parmi les titres, objets et slugs sans solliciter inutilement la base de données.
Synchronisation d'État de Brouillon en Direct
Une carte d'indication en pointillés distingue clairement les brouillons actifs en mémoire des templates de production enregistrés.
Instantanés de Campaigns Indépendants
La modification ou suppression d'un template n'affecte jamais les envois passés. Les Campaigns expédiées conservent des instantanés HTML et d'objet statiques dans cm_campaigns.
4.2 8 Mises en Page Starter Réactives Basées sur Tableaux Éprouvées
Les moteurs d'affichage de bureau modernes (notamment Microsoft Outlook utilisant Word HTML) ne prennent pas en charge CSS Grid ou Flexbox. MarbleSend intègre 8 mises en page basées sur tableaux testées sur Gmail, Outlook, Apple Mail et Yahoo :
Canevas épuré avec pied de page de désinscription obligatoire.
Bannière principale, proposition de valeur, appel à l'action percutant.
Éditorial soigné, mise en avant d'articles sur 2 colonnes.
Bandeau d'en-tête et bloc {{news_posts}} pour les planifications d'articles d'actualité.
Intégration personnalisée, guide de démarrage en 3 étapes.
Badge date/heure, biographie de l'intervenant, bouton RSVP.
Articles numérotés, temps de lecture, tags d'auteurs.
Coupon de réduction urgent, texte basé sur l'aversion à la perte.
Architecture de Tableaux Imbriqués & CSS Inline
Chaque mise en page starter s'appuie sur des éléments <table> imbriqués avec largeurs explicites en pixels, cellpadding/cellspacing à zéro et CSS intégré en ligne pour une stabilité parfaite.
4.3 Éditeur de Code HTML Brut & Formateur Propre
Un éditeur dédié aux développeurs d'emails, avec gestion de l'indentation Tab, suivi en temps réel du nombre de caractères et normalisateur automatique des espaces.
Indentation avec la Touche Tab
L'appui sur Tab insère 2 espaces sans changer le focus du navigateur, facilitant la structuration du code directement dans l'interface.
Formateur de Code en 1 Clic ("Clean")
Harmonise les indentations irrégulières, élimine les sauts de ligne superflus et nettoie la syntaxe des tableaux imbriqués sans altérer les styles inline.
Contrôle du Poids & Protection contre la Troncature
Suivi en temps réel du volume de code. Conserver un poids HTML sous 102 Ko empêche Gmail de couper votre message avec l'avertissement "[Message clipped]".
Zéro Code Parasite Issu d'Éditeurs Visuels
Le contrôle direct du HTML évite l'ajout de classes CSS superflues, de polices non supportées ou de balises span cachées qui nuisent à la délivrabilité.
4.4 Viewports Réactifs Multi-Appareils Isolés
Simule les clients de messagerie de bureau et mobiles dans un cadre iframe isolé, protégeant l'interface d'administration de tout conflit de style.
Sécurité d'Iframe & Isolation CSS
L'attribut sandbox="allow-same-origin" isole totalement les règles CSS de l'email, empêchant toute interférence avec le panneau d'administration MarbleSend.
Bascule Bureau vs Mobile 320px
Basculez instantanément entre la largeur complète bureau et un affichage mobile réaliste de 320px avec bordures d'appareil pour vérifier la lisibilité sur une colonne.
Simulation de Ligne d'Objet en Temps Réel
La barre supérieure affiche l'objet généré en temps réel, prévisualisant le rendu exact des placeholders de personnalisation pour le destinataire.
Bannière d'Alerte de Syntax Dynamique
Analyse automatiquement le balisage du brouillon et affiche un avertissement si des balises de placeholders non fermées ou inconnues sont détectées.
4.5 Tokens de Personnalisation Dynamiques & Conformité RFC
Au moment de l'envoi, le moteur de modèles remplace dynamiquement les tokens par les attributs du destinataire, des liens de suivi sécurisés, des résumés d'articles RSS et des articles d'actualité.
Nom complet du destinataire (utilise "there" si non renseigné)
Adresse email du destinataire
Lien de désinscription obligatoire en 1 clic conforme au RFC 8058
URL de confirmation double opt-in pour les pages d'inscription
Boucle d'articles de blog syndiqués pour les newsletters RSS automatisées
Titre du flux de contenu RSS/Atom connecté
Titre de l'article de blog le plus récemment publié
Nombre de nouveaux articles du flux inclus dans l'envoi
Bloc d'articles d'actualité pour une planification de Newsletter (couverture, titre, sous-titre, corps)
Nombre d'articles d'actualité inclus dans cet envoi
Titre de l'article d'actualité le plus récent de cet envoi
Exigence Légale & Sauvegarde de la Délivrabilité
Tout envoi marketing doit comporter {{unsubscribe_link}}. Un broadcast dépourvu de mécanisme de désinscription valide enfreint CAN-SPAM, GDPR et CASL, entraînant le blocage rapide de votre domaine.
4.6 Diagnostic d'Envoi de Test Unique & Contrôle Préalable
Outil modal permettant d'expédier des emails de test vers n'importe quelle adresse via le profil SMTP sélectionné avant de programmer ou d'envoyer la Campaign.
Sélection Multi-Profils SMTP
Acheminez les tests via n'importe quel profil SMTP configuré pour tester les enregistrements SPF, DKIM et la délivrabilité sur vos serveurs d'envoi.
Rendu des Placeholders avec Valeurs Factices
Remplace automatiquement les tokens par des données de simulation réalistes (ex. "John Doe") pour vérifier la mise en page et les alignements.
Expédition Synchrone Hors File d'Attente
Contourne la file d'attente d'arrière-plan (cm_email_queue) pour délivrer immédiatement le message via MailerFactory avec confirmation instantanée.
Contrôle Qualité Boîte de Réception & Mode Sombre
Envoyez des tests vers des comptes Gmail, Outlook et Apple Mail pour auditer l'inversion des couleurs en mode sombre et la lisibilité globale.
4.7 Moteur de Copywriting AI Accrocheur BYOK
Rédacteur AI intégré fonctionnant directement via BYOK (Bring Your Own Key) pour créer et optimiser des templates emails ultra-performants sans intermédiaire.
Principe Fondamental : La Qualité Dépend du Prompt et du Modèle
MarbleSend ne vous enferme pas dans un modèle d'IA propriétaire unique. Comme la génération s'exécute via votre fournisseur BYOK configuré, la qualité de la mise en page, la puissance persuasive, la précision des tableaux HTML et la critique des objets sont fondamentalement régies par deux variables : la spécificité de vos instructions de prompt et la capacité de raisonnement du modèle LLM sélectionné.
1. Spécificité et Richesse de Contexte du Prompt Utilisateur
Le modèle d'IA est le reflet de la clarté et du contexte fournis. Un prompt générique tel que « rédige un e-mail promo » produira un texte basique. Pour des résultats remarquables, offrez un contexte structuré : public cible, problématique centrale, offre principale, ton souhaité (urgent, conversationnel, exécutif) et un Call-to-Action (CTA) précis. Dans l'onglet Modifier le modèle, donnez des consignes ciblées (ex. : « raccourcis le deuxième paragraphe », « accentue la remise de 20 % sur le CTA », « ajoute un encadré de 3 avantages ») pour affiner votre modèle pas à pas.
2. Gamme et Puissance de Raisonnement du Modèle LLM
Sous Settings → AI Providers, vous pouvez relier des modèles de pointe (comme DeepSeek-V4.1-flash, Claude 5 Sonnet ou GPT-6) ou des modèles locaux légers (comme 7B–8B paramètres via Ollama ou Groq). Les modèles de premier plan excellent dans l'imbrication de tableaux HTML fiables pour e-mail, le placement naturel des token de personnalisation ({{name}}, {{email}}, {{unsubscribe_link}}) et le copywriting persuasif. Dans l'onglet Options d'objet, le score 1–100, l'audit anti-spam et les suggestions de variantes sont générés en direct par le modèle actif ; les modèles plus performants fournissent une analyse nettement plus pointue et des variantes bien plus percutantes.
Garde-fous Natifs du System Prompt de MarbleSend
Quels que soient la longueur du prompt ou le modèle retenu, AiService.php injecte des garde-fous architecturaux stricts : structure responsive à tableau unique (largeur max 600px, fond épuré, cartes contrastées), boutons CTA basés sur des tableaux parés contre les bugs d'Outlook et de Gmail, zéro image externe pour préserver la délivrabilité, et insertion obligatoire du token {{unsubscribe_link}} dans le pied de page pour respecter la conformité légale internationale.
Génération Complète de Template
Produit des structures d'emails HTML complètes et réactives basées sur tableaux, adaptées à votre cible, votre offre, le ton et la longueur choisis.
Affinement Contextuel
Examine le template en cours dans l'éditeur et effectue des modifications ciblées (ex. "ajoute une section 3 avantages" ou "renforce l'urgence du bouton d'action").
Comparaison Visuelle Interactive
Des iframes côte à côte affichent simultanément les versions "Avant" et "Après" pour vérifier les ajustements avant de les appliquer.
Comment Obtenir les Clés API des Principaux Fournisseurs
Une fois votre clé API et votre ID de modèle obtenus, configurez MarbleSend selon ces étapes simples :
4.8 Score d'Objet AI & Inspecteur de Délivrabilité Interactif
Analyse les lignes d'objet de tous vos templates, évaluant le taux d'ouverture estimé, les alertes de filtres anti-spam et la longueur avec variantes en 1 clic.
Chargement des Objets de la Bibliothèque
Parcourt tous les objets stockés dans cm_templates et les présente sous forme de liste, en mettant en avant celui du template en cours d'édition.
Évaluation Multi-Critères 1–100
Le modèle LLM actif jauge la curiosité, la clarté, la valeur perçue et l'urgence afin de calculer une note d'efficacité globale sur 100.
Audit de Troncature Mobile & Filtres Anti-Spam
Signale les longueurs dépassant les écrans mobiles (recommandé <= 50 caractères) et repère les mots sensibles comme "GRATUIT", "URGENT $$$" ou la ponctuation abusive.
Suggestions de Variantes Optimisées
Génère des variantes axées sur la curiosité, le bénéfice concret ou l'aversion à la perte, applicables directement d'un simple clic.
Articles d'actualité — des articles façon Substack pour vos newsletters
Rédigez des articles dans l'onglet Articles de Modèles (Markdown avec aperçu en direct). Une planification de Newsletter réglée sur « Articles d'actualité » envoie chaque article Prêt une seule fois, du plus ancien au plus récent, en remplissant le marqueur {{news_posts}} de son modèle. Les articles n'existent que dans votre e-mail — il n'y a pas de page publique.
Rédiger et marquer Prêt
Utilisez la barre d'outils ou du Markdown simple. Un article n'est envoyé qu'après son passage de Brouillon à Prêt.
Marqueur de modèle
Placez {{news_posts}} là où les articles doivent apparaître (le modèle de départ « Newsletter d'articles d'actualité » le contient déjà). {{news_posts_count}} et {{news_latest_post_title}} fonctionnent dans l'objet.
Planifier
Dans Planifications, choisissez Newsletter, puis Source du contenu : Articles d'actualité. Seuls les articles marqués Prêts à partir de ce moment sont envoyés : vos archives ne sont jamais renvoyées. Suppression intelligente n'est pas utilisé.
Sûr par conception
Le texte des articles est échappé en HTML et seuls les liens et images https sont autorisés. Gardez chaque e-mail sous environ 100 KB pour que Gmail ne tronque pas le lien de désabonnement — l'éditeur vous avertit.
L'espace de travail Articles en un coup d'œil
Ouvrez Modèles et passez à l'onglet Articles. La bibliothèque est à gauche, l'éditeur avec son aperçu en direct à droite — la même disposition que le studio de modèles.
| Élément | Ce qu'il fait |
|---|---|
| Bibliothèque | Liste chaque article avec un badge Brouillon ou Prêt, le nombre d'envois et la date de dernière modification. La recherche filtre par titre et sous-titre ; l'icône de corbeille apparaît au survol. |
| Titre, sous-titre, couverture | Le titre est obligatoire (255 caractères maximum, une ligne). Le sous-titre (500 maximum) s'affiche dessous. L'image de couverture doit être une URL https — toute autre est refusée à l'enregistrement. |
| Commutateur de statut | Les articles en Brouillon ne sont jamais envoyés. Passer un article à Prêt enregistre le moment où il l'est devenu ; ce moment détermine quelles planifications peuvent l'envoyer. |
| Éditeur Markdown | Les boutons de la barre (titre, gras, italique, lien, listes, citation, séparateur, image) insèrent la syntax autour de votre sélection. Un article peut contenir jusqu'à 100 000 caractères. |
| Aperçu en direct | Affiche l'article non enregistré dans le modèle choisi, avec le même code qu'un envoi réel, et indique la taille de l'e-mail en KB. Les marqueurs comme {{name}} utilisent des valeurs d'exemple. |
| Raccourci du marqueur | Un bouton sous l'éditeur copie {{news_posts}} pour le coller dans un modèle. |
Référence Markdown
Le texte d'un article s'écrit dans un petit sous-ensemble sûr de Markdown. Tout ce qui sort de cette liste reste du texte brut.
| Syntax | Résultat |
|---|---|
| ## Heading ### Smaller | Titre (les niveaux 1 à 3 deviennent des titres compatibles e-mail) |
| **bold** *italic* | Gras et italique |
| [text](https://example.com) | Lien. Seules les adresses http, https et mailto sont liées ; tout autre schéma (comme javascript:) reste du texte brut. |
| - item 1. item | Listes à puces et numérotées |
| > quote | Citation en bloc |
| --- | Ligne de séparation |
|  | Image. https uniquement ; ajoutez toujours une courte description pour les lecteurs qui bloquent les images. |
| (blank line) | Les paragraphes sont séparés par une ligne vide ; un simple saut de ligne reste un saut de ligne dans le paragraphe. |
| <script>alert(1)</script> | Le HTML brut n'est jamais interprété : une balise <script> ou <img> saisie s'affiche comme texte littéral. |
La famille de marqueurs {{news_posts}}
Placez-les dans un modèle ; une planification d'articles d'actualité les remplit à l'envoi, avant la résolution des tokens habituels par destinataire comme {{name}}.
| Marqueur | Devient |
|---|---|
| {{news_posts}} | Le bloc d'articles de cet envoi : couverture, titre, sous-titre et corps de chaque article, du plus ancien au plus récent. Obligatoire dans le corps du modèle. |
| {{news_posts_count}} | Le nombre d'articles de cet envoi, par exemple 1. Fonctionne dans l'objet et dans le corps. |
| {{news_latest_post_title}} | Le titre de l'article le plus récent de cet envoi. Idéal pour l'objet. |
Obligatoire dans le corps
Une planification d'articles d'actualité est refusée à l'enregistrement si le corps de son modèle ne contient pas {{news_posts}}, et une exécution échoue sans danger (les articles restent en attente) si le modèle est modifié ensuite.
Jamais envoyé en texte brut
Utilisés ailleurs — Campaign manuelle, planification RSS ou planification à modèle seul —, les marqueurs sont remplacés par du texte vide, et la vérification préalable de la Campaign vous prévient avant l'envoi.
Personnalisé et suivi
Le texte d'un article suit le circuit normal : {{name}} dans un article est personnalisé par destinataire, les liens reçoivent des paramètres UTM et le suivi des clics, et le lien de désabonnement de votre modèle reste intact.
Cycle de vie d'un article
Chaque article passe par les mêmes états simples ; le badge de la bibliothèque indique toujours l'état actuel.
Brouillon
En cours de rédaction. Jamais envoyé. Repasser un article Prêt en Brouillon efface son heure de passage à Prêt.
Prêt
En file d'envoi. Une planification ne l'envoie que s'il est devenu Prêt après l'activation du mode Articles d'actualité de cette planification. Réenregistrer un article déjà Prêt ne change pas sa place dans la file.
Envoyé
Enregistré par planification et affiché « Envoyé 1× » dans la bibliothèque. Une planification n'envoie jamais deux fois le même article, même si vous le modifiez ensuite.
Supprimé
Supprime l'article et son historique d'envoi. Les e-mails déjà remis ne sont pas affectés, et un article supprimé ne peut pas être récupéré.
Taille de l'e-mail et sécurité
Les articles portent leur texte complet dans l'e-mail — il n'y a pas de page publique — : la taille et la sécurité comptent donc plus que dans un digest de simples liens.
Échapper d'abord
Chaque caractère saisi est échappé en HTML avant toute mise en forme, de sorte que scripts et balises n'atteignent jamais la boîte de réception d'un destinataire.
https uniquement
Les images et la couverture doivent être en https. Les liens acceptent http, https et mailto. Les autres schémas s'affichent en texte brut.
Rester sous environ 100 KB
Gmail tronque les messages de plus d'environ 102 KB et masque le pied de page, lien de désabonnement compris. L'aperçu affiche la taille en KB et avertit au-delà de 80 KB ; limitez le nombre d'articles par e-mail pour les textes longs.
Pas d'archive publique
Les articles n'existent que dans les e-mails que vous envoyez. Pas de pages web, pas d'envoi d'images, pas d'appels IA automatiques — les images sont liées par URL.
Dépannage rapide
| Symptôme | À vérifier |
|---|---|
| L'aperçu n'affiche aucun article | Le modèle sélectionné n'a pas de marqueur {{news_posts}} (il est signalé « sans {{news_posts}} » dans la liste). Choisissez un autre modèle ou ajoutez le marqueur. |
| Avertissement « E-mail volumineux » | Raccourcissez l'article, retirez la mise en forme lourde ou réduisez « Articles par e-mail » dans la planification. |
| Un lien n'est pas cliquable | Écrivez-le [text](https://…) avec une adresse http, https ou mailto ; les autres schémas restent du texte. |
| Une image n'apparaît pas | L'adresse doit commencer par https et être accessible publiquement. Certaines applications de messagerie bloquent aussi les images distantes tant que le lecteur ne les autorise pas. |
Schedules & Automatisation RSS (/schedules)
Envois récurrents de newsletters (modèle ou articles d'actualité), calendrier mensuel interactif des envois, moteur de cadence, ciblage dynamique d'audience et Campaigns automatiques RSS/Atom du blog.
Inspecteur d'interface des planifications, RSS et articles d'actualité
Cliquez sur n'importe quel composant ci-dessous pour afficher la requête base de données, l'impact sur le schéma et les conseils opérationnels
Calendrier & Matrice mensuelle
Carte visuelle des plannings & cadencesMoteur de récurrence
Quotidien, hebdomadaire, mensuel & personnaliséPoller de blog automatisé
Déduplication de hachage & cacheAudience dynamique
Requête de tags à la seconde exacte de l'exécutionLogs d'occurrences
Audit d'exécution & prévention des doublonsExécution immédiate Run Now
Envoi instantané sans décaler la cadenceOptimisation hébergement
8 directives opérationnelles sélectionnéesHeartbeat Cron & Verrou
Garde de concurrence non bloquanteMode Articles d'actualité
Newsletters façon Substack5.1 Opérations bimodes : Gestionnaire interactif de planifications & Vue calendrier
MarbleSend propose deux vues opérationnelles synchronisées adaptées à différents flux de travail : un gestionnaire compact en grille Bento (/schedules) et un calendrier mensuel interactif étendu (/schedules/list).
Vue Bento & Tabulaire dense
Affiche tous les envois récurrents avec compte à rebours de la prochaine exécution, bascules d'état actif, aperçus des templates sélectionnés et raccourcis d'exécution directs.
Grille de calendrier interactive à 7 colonnes
Cartographie les prochaines livraisons sur un calendrier mensuel standard du dimanche au samedi, avec mise en évidence du jour actuel, sélecteur de mois et pastilles d'événements cliquables.
Volet de détail de la planification sélectionnée
Volet d'inspection instantané affichant les aperçus sécurisés en bac à sable des templates, les spécifications de récurrence, les règles de tags des destinataires et les commandes d'action rapide.
5.2 Moteur de cadence, règles de récurrence & Normalisation de fuseau horaire UTC
Les planifications récurrentes sont animées par SchedulerService::computeNextRun(), qui élimine le calcul manuel des horodatages au profit des mathématiques robustes de DateTimeImmutable en PHP.
Stockage universel en UTC avec présentation localisée
Toutes les valeurs next_run_at sont stockées en UTC dans cm_schedules. Lors du rendu dans le navigateur, les heures sont converties dans le fuseau horaire d'affichage configuré par l'administrateur tout en préservant les fenêtres de livraison des destinataires.
Récurrence quotidienne & hebdomadaire
Prise en charge des envois quotidiens à des heures définies, ou de sélections de jours hebdomadaires spécifiques (par exemple les mardis et jeudis matin) via des pastilles de jours interactives.
Ajustement mensuel du jour du mois
Pour les envois mensuels programmés les jours 29 à 31, MarbleSend ajuste automatiquement l'exécution au dernier jour valide des mois plus courts (par exemple le 28 ou 29 février).
Prise en compte du fuseau horaire & de l'heure d'été (DST)
Utilise les calculs natifs DateTimeZone de PHP pour garantir que les diffusions se déclenchent à l'heure locale prévue, même lors des passages à l'heure d'été.
5.3 Pipeline du poller automatisé de flux RSS & Atom
MarbleSend se connecte directement à votre blog ou flux de contenu à l'aide de SimpleXML et cURL natifs, transformant les nouveaux articles en Campaign automatisées sans outils d'intégration tiers.
Analyseur double format (RSS 2.0 & Atom 1.0)
Inspecte automatiquement l'élément racine XML, extrayant les titres, résumés de contenu, permalinks et horodatages de publication sans aucune bibliothèque externe.
Diagnostic de flux en direct avant envoi
Le bouton "Test Feed" contacte l'URL du flux en temps réel, valide le schéma XML, vérifie les réponses HTTP 200 et affiche un aperçu des 3 derniers articles.
Déduplication & Instantané initial
Suit last_rss_item_id et les dates de publication. Lors de la création initiale de la planification, MarbleSend enregistre l'ID du dernier article comme référence afin d'éviter d'envoyer rétroactivement les archives historiques.
5.4 Résolution dynamique de l'audience & Ciblage des destinataires à l'exécution
L'audience d'une planification peut aussi être limitée à un groupe (combinée à une étiquette, les deux doivent correspondre). Si le groupe est supprimé, la planification est désactivée au lieu d'envoyer silencieusement à personne.
Contrairement aux instantanés statiques de Campaign, les envois planifiés résolvent dynamiquement leur liste de destinataires à la seconde exacte où l'occurrence se déclenche.
Expansion de l'audience en temps réel
Les abonnés qui s'inscrivent ou reçoivent des tags quelques minutes avant l'exécution planifiée sont automatiquement inclus dans le prochain envoi sans nécessiter de re-sync manuel.
Filtre d'état de délivrabilité strict
La requête d'envoi applique WHERE status = 'active', excluant inconditionnellement les contacts en attente, désabonnés et supprimés des files d'attente récurrentes.
Isolation des segments basée sur les tags
Prend en charge la diffusion à tous les contacts actifs ou le ciblage de segments d'audience spécifiques correspondant à des tableaux de tags JSON (par exemple #weekly-digest, #customers).
5.5 Logs d'exécution des occurrences, audits & Politique de rattrapage unique
Chaque exécution automatisée crée une ligne d'audit immuable dans cm_schedule_occurrences, détaillant les horodatages, les résultats, les totaux de destinataires et la télémétrie des erreurs.
Télémétrie d'occurrence à 3 états
Distingue 'completed' (emails mis en file), 'skipped' (aucun nouvel article RSS détecté) et 'failed' (déconnexion SMTP, template non valide ou expiration réseau).
Protection d'idempotence avec rattrapage unique
Si le worker cron a été inactif pendant plusieurs heures d'exécution manquées, MarbleSend exécute au maximum UN seul envoi de rattrapage lors de la récupération et fait avancer next_run_at vers le futur.
Modal d'historique d'audit des occurrences
Cliquez sur "View Execution History" depuis la barre latérale pour examiner les exécutions passées, les volumes de destinataires et les logs d'erreurs de diagnostic directement dans l'interface.
5.6 Envois manuels à la demande ("Run Now") & Dérogations d'urgence
Les administrateurs peuvent contourner le compte à rebours et déclencher immédiatement un envoi non planifié de n'importe quelle planification à l'aide de l'action "Trigger Send Now".
Compilation immédiate de la file
Compile instantanément le template, résout les membres actifs de l'audience et envoie les éléments par lot dans cm_email_queue pour le prochain cycle du worker.
Calendrier de récurrence préservé
Le déclenchement d'un envoi à la demande ne décale ni ne repousse l'horodatage planifié next_run_at, maintenant la cadence calendaire normale.
Utilitaire de diagnostic & d'informations urgentes
Idéal pour tester le formatage complet d'un template avec des données d'abonnés réelles ou pour diffuser des bulletins urgents en dehors des heures ouvrables habituelles.
5.7 Concurrence infaillible du worker, prévention des chevauchements & Verrous non bloquants
MarbleSend intègre un périmètre de concurrence d'entreprise spécialement conçu pour empêcher les envois en double sur les environnements d'hébergement mutualisé économiques.
Verrou de concurrence non bloquant flock
worker.php acquiert un verrou flock exclusif sur storage/worker.lock. Si une exécution précédente est toujours en cours sur des relais SMTP à forte latence, les invocations suivantes se terminent silencieusement.
Parité de protocole pour le worker double
worker.php en CLI et cron.php en HTTP partagent des chemins d'exécution et des mécanismes de verrouillage identiques, garantissant un comportement cohérent entre le cron cPanel et les webhooks.
Réservations atomiques des occurrences
Les planifications prêtes à être exécutées sont réservées à l'aide d'instructions préparées PDO atomiques, évitant ainsi la mise en file d'attente en double, même dans des conteneurs multithread.
5.8 Réglage des performances pour hébergement mutualisé & Les 8 conseils d'optimisation
La carte dynamique Optimization Tip sur la page Schedules fournit 8 recommandations opérationnelles concrètes et éprouvées en production pour une livraison fiable en hébergement mutualisé :
Planifiez les envois le mardi ou le jeudi entre 09:00 et 10:30, heure locale des destinataires, pour obtenir les meilleurs taux d'ouverture et de clics.
Exécutez worker.php chaque minute (* * * * *) avec protection flock pour garantir une précision sous la minute sans collision de processus.
Interrogez cm_email_queue à l'aide d'instructions préparées indexées avec clauses LIMIT pour éliminer les conditions de concurrence pendant les pics de volume.
Segmentez les contacts par tags régionaux (#us-east, #apac, #emea) et attribuez des planifications échelonnées dédiées pour éviter de distribuer des emails à 3h00 du matin.
Planifiez les envois RSS 1 à 2 heures après la publication de l'article dans votre CMS, permettant ainsi aux nœuds de périphérie CDN et aux caches XML de se mettre à jour.
Purgez périodiquement les anciens logs d'exécution de cm_schedule_occurrences pour maintenir la taille des tables légère et les index de requête optimaux sur hébergement mutualisé.
Planifiez une diffusion de suivi 48 à 72 heures plus tard aux abonnés où opened_at IS NULL avec un nouvel objet pour récupérer 15 à 25 % d'engagement.
Attribuez des profils SMTP distincts pour les flux RSS automatisés et les envois marketing à fort volume afin de protéger la réputation d'expéditeur de votre domaine.
5.9 Planifications d'articles d'actualité (newsletters façon Substack)
Une planification de Newsletter peut désormais envoyer des articles au lieu d'un modèle fixe. Réglez Source du contenu sur « Articles d'actualité » : chaque exécution remet les prochains articles Prêts de Modèles → Articles, insérés dans le modèle via {{news_posts}}. Rien n'est envoyé quand aucun article n'attend.
Quelle source de contenu choisir ?
Modèle uniquement
Le même modèle à chaque exécution — pour des annonces ou rappels récurrents. Suppression intelligente est disponible.
Digest RSS
Nouveaux articles d'un flux de blog externe. La première exécution marque seulement les articles existants comme vus ; les suivantes n'envoient que les nouveaux.
Articles d'actualité
Articles que vous rédigez dans MarbleSend. Chaque article Prêt est envoyé une fois, du plus ancien au plus récent. Idéal pour une newsletter façon Substack.
Mise en place en six étapes
- 1Ouvrez Modèles → Articles et rédigez votre article en Markdown.
- 2Créez ou ouvrez un modèle et placez {{news_posts}} là où les articles doivent apparaître (le modèle de départ « Newsletter d'articles d'actualité » le contient déjà).
- 3Ouvrez Planifications → Nouvelle, gardez le type Newsletter et réglez Source du contenu sur « Articles d'actualité ».
- 4Choisissez le modèle, l'audience, le profil SMTP, le nombre d'articles par e-mail (1–20) et la cadence.
- 5Enregistrez. Seuls les articles qui deviennent Prêts après ce moment peuvent être envoyés par cette planification.
- 6Marquez l'article Prêt. La prochaine occurrence — ou Exécuter maintenant — l'envoie.
Quels articles sont envoyés à chaque exécution
À chaque occurrence, la planification choisit les articles selon quatre règles, dans cet ordre.
Prêts uniquement
Les brouillons sont ignorés, quel que soit leur âge.
Après la date butoir
Un article doit être devenu Prêt après l'activation du mode Articles d'actualité de la planification. Vos archives existantes ne sont jamais renvoyées.
Pas encore envoyé par cette planification
L'envoi est enregistré par planification : deux planifications peuvent chacune envoyer le même article une fois, jamais deux.
Les plus anciens d'abord, jusqu'à la limite
« Articles par e-mail » (1 par défaut, 20 maximum) limite le nombre d'articles regroupés. Les autres attendent l'exécution suivante.
Ce que chaque exécution enregistre
Chaque occurrence apparaît dans l'historique de la planification. Les articles ne sont marqués remis que si un lot d'e-mails a réellement été mis en file.
Envoyé
Une Campaign a été créée et mise en file, par exemple « 1 post · 5 recipients queued ». Les articles sont marqués envoyés par cette planification.
Ignoré : aucun nouvel article
Aucun article Prêt n'attend. Rien n'est envoyé et la planification réessaie à la prochaine occurrence.
Ignoré : aucun destinataire
L'audience était vide. Les articles restent en attente et partent dès que l'audience compte des contacts actifs.
Échec
Le modèle est introuvable ou ne contient plus {{news_posts}}. Les articles restent en attente ; corrigez le modèle puis relancez.
Exécuter maintenant et envois de test
Exécuter maintenant
Une vraie occurrence, exécutée par le worker en environ une minute. Envoie les articles en attente et les marque comme remis.
Envoyer un digest de test
Envoie les prochains articles en attente — ou, s'il n'y en a pas, l'article Prêt le plus récent — à une adresse via le profil SMTP propre à la planification. Ne marque jamais rien comme remis et partage la limite de tests de 5 par minute.
Modifier et mettre en pause
- Passer une planification de Modèle uniquement à Articles d'actualité fixe une nouvelle date butoir à ce moment ; revenir en arrière l'efface.
- L'enregistrement du formulaire de planification revérifie que le modèle contient {{news_posts}}. Pause et Reprise ne font que basculer l'interrupteur marche/arrêt sans jamais le vérifier : vous pouvez donc toujours mettre en pause.
- Suppression intelligente est désactivée automatiquement en mode Articles d'actualité : elle exclurait tous ceux qui ont reçu un numéro précédent.
- Articles d'actualité n'existe que pour les planifications de Newsletter ; les planifications RSS gardent leur propre logique de flux.
Lire les écrans de planification
- La liste des planifications étiquette ces planifications « Articles d'actualité » au lieu de « Newsletter ».
- Le panneau de détail indique combien d'articles Prêts attendent cette planification.
- Dans le formulaire, les modèles sans {{news_posts}} sont signalés, et un avertissement apparaît si vous en choisissez un.
Dépannage rapide
| Symptôme | À vérifier |
|---|---|
| Mon article Prêt n'a pas été envoyé | Vérifiez qu'il est devenu Prêt après l'enregistrement de la planification (ou son passage en Articles d'actualité), que la planification est activée, et consultez l'entrée d'historique : « no recipients » ou « failed ». |
| La planification indique « no new posts » juste après que j'en ai rédigé un | L'article est peut-être encore en Brouillon, ou déjà envoyé par cette planification. Ouvrez Modèles → Articles et vérifiez le badge et « Envoyé N× ». |
| Enregistrement impossible : le modèle doit contenir {{news_posts}} | Ajoutez le marqueur au corps du modèle (pas seulement à l'objet) ou choisissez un autre modèle. |
| Je veux renvoyer un ancien article | Copiez son texte dans un nouvel article et marquez celui-ci Prêt — une planification n'envoie jamais deux fois le même article. |
Settings & infrastructure (/settings)
Gestion multi-relais SMTP, battement de cœur cron, 23 langues, diagnostics de délivrabilité et activation de licence.
UI Inspector Paramètres & Infrastructure
Cliquez sur un composant ci-dessous pour afficher l'impact sur la base de données, les processus en arrière-plan et les directives opérationnelles
Profils SMTP
BYO SMTP & Relais SES GéréWorker & Cron
Cadence d'exécution de 1 minute23 Langues & Thème
Miroir RTL et Mode Sombre/ClairClés REST API
Accès développeur avec portéeWebhooks d'Événements
Push d'événements HMAC-SHA256Suite de Délivrabilité
SPF, DKIM, DMARC et BIMIFournisseurs d'AI
BYOK & Crédits MarbleSendLicence Ed25519
Token d'octroi cryptographique6.1 Architecture de livraison double: BYO SMTP & Relais Amazon SES Géré
MarbleSend découple l'exécution des campagnes des relais de livraison grâce à deux modèles de transport: (1) Bring Your Own (BYO) SMTP pour connecter vos serveurs existants, et (2) MarbleSend SMTP via Amazon SES pour une livraison cloud professionnelle instantanée sans configuration AWS ni préchauffage d'IP. Les campagnes se lient dynamiquement avec repli par défaut et comptabilité atomique.
Connectez n'importe quel fournisseur SMTP standard comme Postmark, Mailgun, Brevo, SendGrid, Resend ou la boîte cPanel de votre hébergeur. Prend en charge le port 587 avec STARTTLS, le port 465 avec SSL/TLS implicite et le port 25 local, avec authentification personnalisée et en-têtes expéditeur isolés.
6.1.1 Fournisseurs de Serveurs SMTP (Gratuits, Commerciaux et Hébergement Mutualisé)
Répertoire et Comparatif SMTPConnectez votre propre transport d'e-mails avec des identifiants SMTP standard. Choisissez entre relais cloud dédiés ou boîtes de messagerie de votre hébergeur.
Les boîtes d'hébergement mutualisé standard imposent des limites strictes (généralement 100–500 e-mails/jour). Pour les campagnes de marketing, passez à une offre Business Email ou utilisez un relais cloud dédié.
Optimisés pour les envois volumineux et une délivrabilité maximale.
| Fournisseur / Site Web | Quota Gratuit | Tarifs Commerciaux | Hôte et Port SMTP | Règles et Limites Essentielles |
|---|---|---|---|---|
| Amazon SES (Direct) | Free tier on EC2 only (62k/mo); Otherwise pay-as-you-go | $0.10 / 1,000 emails ($1 per 10k) | email-smtp.<region>.amazonaws.com Port 587 (TLS) or 465 (SSL) |
Requires AWS account setup, IAM SMTP user credentials, and sandbox exit request. |
| Brevo | 300 emails / day (Free forever) | Starter from ~$9/mo (5k emails) to ~$18/mo (20k emails) | smtp-relay.brevo.com Port 587 (TLS) |
Free tier resets daily. Great for low-volume testing without entering a credit card. |
| Mailgun (Sinch) | Trial (5,000 emails for 30 days) | Foundation: $35/mo (50,000 emails); Scale: $90/mo | smtp.mailgun.org (or smtp.eu.mailgun.org) Port 587 (TLS) or 465 (SSL) |
Robust analytics and deliverability. Supports EU data residency. |
| Twilio SendGrid | 100 emails / day (Free forever) | Essentials: ~$19.95/mo (50k emails); Pro: ~$89.95/mo | smtp.sendgrid.net Port 587 (TLS) (User: apikey) |
Requires Two-Factor Authentication. Username must literally be apikey. |
| Postmark (ActiveCampaign) | Free Developer trial: 100 emails/mo | From $15/mo (10,000 emails), $55/mo (50,000 emails) | smtp.postmarkapp.com Port 587 (TLS) or 2525 |
Industry-leading transactional speed and strict spam filters. Separate broadcast streams required. |
| Resend | 3,000 emails / month (100 / day free) | Pro: $20/mo (50,000 emails/mo) | smtp.resend.com Port 465 (SSL) or 587 (TLS) (User: resend) |
Modern developer experience, clean UI, quick domain verification via DNS. |
Les boîtes cPanel standard conviennent à une correspondance légère mais sont strictement plafonnées pour le marketing de masse.
Business Email Plans (Per Mailbox)
1 GB storage, 1 forwarding rule, 1 alias, up to 100 mailboxes/domain. Standard webmail & antispam. Strict sending cap (~100-200/day).
5 GB storage, 5 forwarding rules, 5 aliases, expandable mailbox storage. No mailbox limit per domain.
20 GB storage, 20 forwarding rules, 10 aliases, AI Kodee mailbox assistant & smart replies.
50 GB storage, 50 forwarding rules, 30 aliases, full AI suite & priority deliverability.
Hostinger Reach (Email Marketing)
100 recipients, 200 emails / month. Suitable for basic transactional testing.
500 recipients, 500 emails / month, 10 AI credits, remove Reach branding, automations.
1,000 recipients, 7,000 emails / month, 20 AI credits, custom HTML code, send-time optimization.
• cPanel Shared: Max ~500 emails/hour per cPanel domain.
• Private Email: Starter (~$1.24/mo per mailbox, 5GB). Pro (~$2.82/mo, 30GB).
• SMTP Host: mail.privateemail.com (Port 465 SSL or 587 TLS).
• Shared cPanel: Default cap ~500 emails/hour. Internal mail system may defer large sudden bursts.
• Professional Email: Integrated with Microsoft 365 or Google Workspace ($2.99–$9.99/mo).
• SMTP Host: box###.bluehost.com or mail.yourdomain.com (Port 465 SSL).
• Site Tools Mail: Included in hosting (StartUp, GrowBig, GoGeek).
• Rate Limits: ~400 emails/hour on StartUp; up to ~800/hour on GoGeek. Strictly intended for transactional mail.
• SMTP Host: mail.yourdomain.com (Port 465 SSL).
• Paid Business Email: ~$1.99/mo per mailbox (25GB storage).
• Strict Outbound Policy: Maximum 100 recipients per hour. Mass marketing prohibited via shared SMTP.
• SMTP Host: smtp.dreamhost.com (Port 465 SSL or 587 TLS).
• cPanel Limit: Max 500 emails/hour per domain on shared plans.
• Workspace Option: Google Workspace addon ($6–$18/mo).
• SMTP Host: mail.yourdomain.com (Port 465 SSL or 587 TLS).
• M365 Reseller: Email Essentials from ~$1.99–$5.99/mo (10GB-50GB).
• SMTP Relay Note: Direct SMTP AUTH requires enabling Authenticated SMTP in the M365 Admin Portal.
• SMTP Host: smtp.office365.com (Port 587 TLS).
Sélectionnez le port et le protocole de sécurité adaptés à votre réseau.
The modern standard for email client-to-relay submission (RFC 6409). Starts in cleartext and immediately upgrades connection to TLS. Supported by almost all cloud relays.
Implicit TLS/SSL wrapper connection (RFC 8314). Required by Hostinger, Namecheap cPanel, and selected enterprise relays. Highly reliable when hosting firewalls restrict 587.
Server-to-server MTA routing. Almost universally blocked on cloud hosts (Hostinger, AWS, DigitalOcean, Hetzner, etc.) to combat spam. Do NOT use for outbound SMTP credentials.
6.1.1 Relais Amazon SES Géré & Domaines d'Expéditeur Personnalisés
MANAGED SESInfrastructure d'expédition cloud d'entreprise gérée par MarbleSend via api.marblesend.com. Élimine le blocage des ports SMTP, la gestion des identifiants IAM et les risques de réputation IP sur hébergement partagé. Comprend deux modes d'expéditeur (Friendly From & Easy DKIM), des crédits initiaux gratuits, un audit de ledger atomique et une évolutivité dynamique à la demande.
Livraison cloud Amazon SES préconfigurée et gérée par MarbleSend. Ne nécessite aucune configuration de compte AWS, aucune gestion IAM ni préchauffage d'IP. Rechargez des crédits via notre prestataire de paiement à la demande avec synchronisation automatique du quota en temps réel.
Chaque e-mail expédié via MarbleSend SES réserve 1 crédit de manière atomique grâce à l'idempotence UUID (cm_addon_ledger.uq_addon_ledger_key). En cas d'échec de transmission, la réservation est immédiatement libérée et remboursée sans action manuelle.
Le modal Test Connection effectue une négociation SMTP en direct et un envoi test via MailerFactory. Il affiche le dialogue brut de socket en temps réel pour diagnostiquer les erreurs d'authentification (535 Auth Failed), de relais (550 Relay Denied) et de délai TLS.
Chaque campagne, planification récurrente ou répondeur automatique peut être associé à un profil SMTP dédié via cm_campaigns.smtp_profile_id. Sans affectation, le moteur achemine automatiquement les envois vers le profil par défaut (is_default = 1).
Que vous choisissiez BYO SMTP ou MarbleSend SES, votre domaine d'expédition doit posséder des enregistrements SPF, DKIM et DMARC valides. La suite de délivrabilité 4-piliers intégrée vérifie activement votre DNS pour garantir l'arrivée en boîte de réception.
6.1.2 Règles d’envoi avec le SES Relay
Amazon SES ne convient qu’aux expéditeurs qui gardent leurs listes propres ; ces règles sont donc appliquées par le relais MarbleSend lui-même, pas seulement par cette application. Elles ne peuvent pas être désactivées et s’appliquent à chaque e-mail envoyé via le SES Relay.
Avant le premier envoi, renseignez Settings → SMTP → Identité de l’expéditeur et utilisation acceptable : nom légal, adresse postale, pays, numéro de téléphone et acceptation de la Politique d’utilisation acceptable. L’envoi reste bloqué tant que ce n’est pas enregistré. Votre nom et votre adresse figurent dans le pied de chaque e-mail ; le téléphone n’est jamais affiché.
Le corps de chaque campagne doit contenir la balise {{unsubscribe_link}}, sinon l’envoi est refusé. De plus, le relais ajoute les en-têtes List-Unsubscribe et en un clic, ainsi qu’un pied avec votre nom, votre adresse, un lien de désinscription et « Sent with MarbleSend ». Le pied ne peut pas être retiré.
Tant que le SES Relay est utilisé, les pages d’inscription et l’API utilisent toujours le double opt-in, l’inscription publique exige Cloudflare Turnstile et un import CSV demande de cocher que tout le monde a donné son accord. Une personne désinscrite ou supprimée ne peut pas se réinscrire via un formulaire public.
Les rebonds définitifs et les plaintes pour spam parviennent automatiquement à MarbleSend et passent le contact en supprimé. Le relais refuse aussi d’envoyer à une adresse supprimée, sans consommer de crédit. Les rebonds temporaires sont réessayés et ne suppriment un contact qu’après des échecs répétés.
Chaque compte a une limite d’envoi quotidienne (2 000 e-mails par défaut). Si les taux de rebond ou de plainte deviennent trop élevés, l’envoi se met en pause automatiquement jusqu’à examen du compte par le support, et il s’arrête aussi si la licence est inactive. Une bannière dans Settings → SMTP en donne la raison, et les e-mails en file attendent au lieu d’être perdus.
Les e-mails sont signés en DKIM pour marblesend.com (ou pour votre propre domaine une fois vérifié). Le return path utilise mail.marblesend.com : SPF est aligné et DMARC réussit. Les réponses vont à l’adresse Reply-To que vous définissez.
Répertoire de configuration 3 CNAME Easy DKIM (Multi-fournisseurs)
Guide complet de configuration DNS pas-à-pas pour intégrer les 3 enregistrements CNAME Easy DKIM d'AWS SES auprès des principaux bureaux d'enregistrement et hébergeurs, évitant les erreurs de syntaxe et garantissant une validation rapide.
Architecture DNS universelle et règles d'or
Easy DKIM délègue la signature cryptographique à Amazon SES via 3 enregistrements CNAME. Comme AWS assure la rotation automatique des clés RSA 1024/2048 bits sans nécessiter de mise à jour DNS manuelle, ces 3 enregistrements CNAME doivent rester actifs en permanence.
| Type d'enregistrement | Hôte / Nom | Valeur / Cible / Pointe vers | TTL |
|---|---|---|---|
| CNAME | <token1>._domainkey.yourdomain.com | <token1>.dkim.amazonses.com | 300 (or Auto) |
| CNAME | <token2>._domainkey.yourdomain.com | <token2>.dkim.amazonses.com | 300 (or Auto) |
| CNAME | <token3>._domainkey.yourdomain.com | <token3>.dkim.amazonses.com | 300 (or Auto) |
Règle 1 : Attention au piège du "Double Domaine"
La plupart des bureaux d'enregistrement et panneaux d'hébergement ajoutent automatiquement votre nom de domaine racine au champ Hôte/Nom. Si vous collez "token._domainkey.votredomaine.fr", le DNS résoudra "token._domainkey.votredomaine.fr.votredomaine.fr", provoquant un échec immédiat. Saisissez uniquement "token._domainkey".
Règle 2 : CNAME, pas TXT
Contrairement au DKIM manuel classique qui utilise un enregistrement TXT avec une clé publique statique, Amazon SES Easy DKIM utilise 3 enregistrements CNAME pointant vers token.dkim.amazonses.com. Ne sélectionnez pas TXT.
Règle 3 : Mode Proxy et Cloudflare Nuage Gris
Si vous utilisez Cloudflare ou un proxy HTTP, réglez les 3 enregistrements CNAME DKIM sur "DNS uniquement" (Nuage gris / Désactivé). Le proxy HTTP masque la cible CNAME et rompt l'authentification cryptographique des emails.
# Check resolution via dig (macOS / Linux): dig CNAME <token1>._domainkey.yourdomain.com +short # Check resolution via nslookup (Windows / PowerShell): nslookup -type=CNAME <token1>._domainkey.yourdomain.com
Hostinger (Zone DNS hPanel)
hPanel DNS| Type d'enregistrement | Hôte / Nom | Valeur / Cible / Pointe vers | TTL |
|---|---|---|---|
| CNAME | <token>._domainkey (hPanel auto-appends .yourdomain.com) | <token>.dkim.amazonses.com | 300 (or 14400) |
Connectez-vous à votre tableau de bord hPanel Hostinger et accédez à Domaines.
Sélectionnez votre domaine et cliquez sur DNS / Serveurs de noms dans la barre latérale.
Dans Gérer les enregistrements DNS, sélectionnez CNAME dans le menu déroulant Type.
Dans le champ Nom, entrez UNIQUEMENT token._domainkey (hPanel ajoute automatiquement .votredomaine.fr).
Dans le champ Cible, entrez token.dkim.amazonses.com et laissez le TTL sur 300 ou 14400.
Cliquez sur Ajouter un enregistrement. Répétez pour les 3 jetons générés dans MarbleSend.
DreamHost (Panneau Web DreamHost)
DreamHost Web Panel| Type d'enregistrement | Hôte / Nom | Valeur / Cible / Pointe vers | TTL |
|---|---|---|---|
| CNAME | <token>._domainkey (DreamHost appends .yourdomain.com) | <token>.dkim.amazonses.com | Default |
Connectez-vous au panneau Web DreamHost et accédez à Sites web > Gérer les sites web.
Localisez votre domaine et cliquez sur Paramètres DNS (ou Domaines > Gérer les domaines > DNS).
Faites défiler jusqu'à la section "Ajouter un enregistrement DNS personnalisé" et cliquez sur Ajouter.
Dans le champ Nom, saisissez token._domainkey (DreamHost complète .votredomaine.fr automatiquement).
Sélectionnez le Type CNAME et saisissez token.dkim.amazonses.com dans le champ Valeur.
Cliquez sur Enregistrer / Ajouter. Répétez l'opération pour les 3 jetons.
Namecheap (DNS Avancé)
Advanced DNS| Type d'enregistrement | Hôte / Nom | Valeur / Cible / Pointe vers | TTL |
|---|---|---|---|
| CNAME Record | <token>._domainkey (never paste root domain here) | <token>.dkim.amazonses.com | Automatic (or 1 min) |
Connectez-vous à Namecheap, ouvrez la Domain List et cliquez sur Manage à côté de votre domaine.
Basculez sur l'onglet Advanced DNS en haut de la page.
Dans la section Host Records, cliquez sur le bouton rouge ADD NEW RECORD.
Sélectionnez CNAME Record dans le menu déroulant Type.
Dans le champ Host, entrez SEULEMENT token._domainkey (n'incluez jamais votre nom de domaine).
Dans Target, collez token.dkim.amazonses.com, réglez TTL sur Automatic (ou 1 min) et validez avec la coche verte ✓. Répétez pour les 3 enregistrements.
Bluehost (Gestionnaire de compte / Zone Editor)
Bluehost DNS| Type d'enregistrement | Hôte / Nom | Valeur / Cible / Pointe vers | TTL |
|---|---|---|---|
| CNAME | <token>._domainkey (Bluehost handles suffix automatically) | <token>.dkim.amazonses.com | 4 Hours (or Default) |
Connectez-vous à Bluehost, cliquez sur Domaines et choisissez votre nom de domaine.
Accédez à l'onglet DNS (ou ouvrez cPanel Zone Editor en hébergement cPanel classique).
Faites défiler jusqu'à la section CNAME (Alias) et cliquez sur Add Record.
Dans le champ Host Record, saisissez token._domainkey.
Dans Points To, collez token.dkim.amazonses.com et sélectionnez le TTL (4 Hours ou Default).
Cliquez sur Save. Répétez pour les 2 autres jetons CNAME.
SiteGround (Éditeur de zone DNS Site Tools)
Site Tools DNS| Type d'enregistrement | Hôte / Nom | Valeur / Cible / Pointe vers | TTL |
|---|---|---|---|
| CNAME | <token>._domainkey (Site Tools appends .yourdomain.com) | <token>.dkim.amazonses.com | 1 hour (3600) |
Connectez-vous à SiteGround, allez dans Sites web et ouvrez Site Tools pour votre domaine.
Dans le menu latéral, développez Domaine et cliquez sur Éditeur de zone DNS.
Sélectionnez l'onglet CNAME sous Créer un nouvel enregistrement.
Dans le champ Nom, tapez token._domainkey (Site Tools verrouille .votredomaine.fr à droite).
Dans Pointe vers, collez token.dkim.amazonses.com et laissez le TTL sur 1 heure (3600).
Cliquez sur Créer. Répétez l'opération pour les 3 jetons.
HostGator (cPanel Zone Editor)
cPanel Zone Editor| Type d'enregistrement | Hôte / Nom | Valeur / Cible / Pointe vers | TTL |
|---|---|---|---|
| CNAME | <token>._domainkey (cPanel automatically appends dot) | <token>.dkim.amazonses.com | 14400 (or 3600) |
Connectez-vous au portail HostGator et ouvrez cPanel.
Dans la section Domaines, cliquez sur Zone Editor.
Trouvez votre domaine et cliquez sur + CNAME Record (ou Gérer > Ajouter un enregistrement).
Dans Nom, saisissez token._domainkey (cPanel ajoute automatiquement votre domaine et un point).
Dans CNAME / Record, saisissez token.dkim.amazonses.com.
Cliquez sur Ajouter un enregistrement CNAME. Répétez pour les 3 jetons.
GoDaddy (Portefeuille de domaines DNS)
GoDaddy DNS| Type d'enregistrement | Hôte / Nom | Valeur / Cible / Pointe vers | TTL |
|---|---|---|---|
| CNAME | <token>._domainkey (never include root domain in GoDaddy) | <token>.dkim.amazonses.com | 1/2 Hour (or Default) |
Connectez-vous à votre compte GoDaddy et ouvrez Mes produits.
Sous Domaines, repérez votre domaine et cliquez sur DNS (ou les trois points > Gérer les DNS).
Dans la section Enregistrements DNS, cliquez sur Ajouter un nouvel enregistrement.
Sélectionnez CNAME dans le menu déroulant Type.
Dans le champ Nom, écrivez UNIQUEMENT token._domainkey (ne saisissez pas .votredomaine.fr !).
Dans Valeur, saisissez token.dkim.amazonses.com, choisissez TTL 1/2 heure (ou Par défaut) et enregistrez. Répétez pour les 3 enregistrements.
Après avoir enregistré les 3 enregistrements CNAME, la propagation DNS prend généralement 5 à 30 minutes (jusqu'à 24–48 h selon le TTL). Retournez dans Paramètres > SMTP de MarbleSend, ouvrez la carte du domaine expéditeur personnalisé et cliquez sur "Vérifier DNS". Une fois validé par Amazon SES, le badge passera à Vérifié.
6.2 Heartbeat du Worker en Arrière-Plan, Cron de 1 Minute & Concurrency Guard
MarbleSend envoie les e-mails en arrière-plan. Une tâche cron est un minuteur de votre panneau d'hébergement qui réveille MarbleSend chaque minute afin qu'il puisse exécuter les planifications et les autoresponders, réessayer les envois échoués, collecter les bounces et poursuivre une longue Campaign. Une Campaign que vous envoyez démarre aussitôt, mais tout ce qui doit se produire plus tard dépend de ce minuteur. Si Settings → Système affiche Cron non détecté, le minuteur est absent, ne s'exécute pas chaque minute ou pointe au mauvais endroit. Les trois étapes ci-dessous le corrigent.
Ouvrez Settings → Système, repérez Commande Cron Job et cliquez sur Copier la commande. La ligne contient déjà le bon folder et, quand votre serveur nous l'indique, le bon PHP. Utilisez-la telle quelle ; les exemples plus bas dans cette page montrent seulement la forme d'une ligne. Si Settings indique qu'il n'a pas pu détecter PHP, demandez à votre hébergeur le chemin de PHP en ligne de commande et remplacez le mot php au début de la ligne.
Choisissez votre hébergeur ci-dessous. Les noms de menus changent de temps à autre : cherchez la correspondance la plus proche. Quel que soit le panneau, la tâche doit s'exécuter chaque minute (* * * * *) et sa commande est la ligne de l'étape 1. Plesk, DirectAdmin et d'autres panneaux l'appellent Scheduled Tasks ou Cron Jobs.
Hostinger (hPanel)
- Ouvrez hPanel → Websites → Dashboard pour votre site, puis cliquez sur Cron Jobs dans la barre latérale.
- Réglez Type sur Custom. (Le type PHP n'accepte que le chemin d'un file .php ; votre ligne contient aussi la commande PHP.)
- Collez la ligne de l'étape 1 dans Command to run.
- Réglez la planification sur chaque minute, ou saisissez * * * * *.
- Cliquez sur Save. La tâche apparaît sous List of Cron Jobs, où vous pouvez aussi lire sa dernière sortie.
Hostinger exécute les tâches cron en UTC. L'offre Single autorise 2 tâches cron ; les offres Premium et supérieures sont sans limite.
Namecheap
Ouvrez cPanel depuis votre compte d'hébergement Namecheap, puis suivez ces étapes.
- Ouvrez cPanel et, dans la section Advanced, cliquez sur Cron Jobs.
- Sous Add New Cron Job, choisissez Once Per Minute (* * * * *) dans Common Settings.
- Collez la ligne de l'étape 1 dans Command.
- Cliquez sur Add New Cron Job. La tâche s'exécute chaque minute à partir de maintenant.
Namecheap n'autorise pas, sur les serveurs mutualisés, de tâches cron plus fréquentes que toutes les 5 minutes, ni plus de 5 tâches cron. Utilisez Web-Cron plus bas si vous avez besoin de chaque minute.
Bluehost
- Connectez-vous au Bluehost Portal, cliquez sur Websites, puis sur Manage Site pour votre site.
- Ouvrez l'onglet Advanced, repérez Cron Jobs et cliquez sur Manage, puis sur Add Cron.
- Choisissez une fréquence dans Common Settings (ou renseignez Minute, Hour, Day, Month et Weekday).
- Collez la ligne de l'étape 1 dans Command et cliquez sur Add.
La documentation de Bluehost indique que l'hébergement mutualisé n'exécute les tâches cron que toutes les 15 minutes ou moins souvent (une page mentionne 5 minutes). Utilisez Web-Cron plus bas si vous avez besoin de chaque minute.
HostGator
Dans le Customer Portal, ouvrez Websites → Manage Site → Advanced, puis sous Cron Jobs cliquez sur Manage et Add Cron. Le formulaire a les mêmes champs que cPanel, donc les étapes ci-dessous s'appliquent. Ou ouvrez cPanel → Advanced → Cron Jobs.
- Ouvrez cPanel et, dans la section Advanced, cliquez sur Cron Jobs.
- Sous Add New Cron Job, choisissez Once Per Minute (* * * * *) dans Common Settings.
- Collez la ligne de l'étape 1 dans Command.
- Cliquez sur Add New Cron Job. La tâche s'exécute chaque minute à partir de maintenant.
Les pages d'aide de HostGator n'indiquent pas l'intervalle le plus court autorisé en hébergement mutualisé. Si chaque minute est refusée, utilisez Web-Cron plus bas.
GoDaddy
Sur la page de votre produit GoDaddy, à côté de Linux Hosting, cliquez sur Manage, puis sur cPanel Admin, puis suivez ces étapes.
- Ouvrez cPanel et, dans la section Advanced, cliquez sur Cron Jobs.
- Sous Add New Cron Job, choisissez Once Per Minute (* * * * *) dans Common Settings.
- Collez la ligne de l'étape 1 dans Command.
- Cliquez sur Add New Cron Job. La tâche s'exécute chaque minute à partir de maintenant.
Les pages d'aide de GoDaddy n'indiquent pas l'intervalle le plus court autorisé. Si chaque minute est refusée, utilisez Web-Cron plus bas.
DreamHost
- Ouvrez le panneau DreamHost, allez dans Cron Jobs et cliquez sur Add New Cron Job.
- Choisissez un utilisateur (un utilisateur SFTP ou shell existant), donnez un titre à la tâche et, en option, une adresse e-mail pour sa sortie.
- Collez la ligne de l'étape 1 dans Command. DreamHost place PHP dans des chemins tels que /usr/local/php83/bin/php (utilisez votre version de PHP).
- Réglez l'horaire et activez locking pour que deux exécutions ne se chevauchent jamais, puis enregistrez.
En horaire personnalisé, le panneau permet de choisir au plus 12 minutes différentes par heure ; la planification régulière la plus courte possible est donc toutes les 5 minutes. Les heures sont en heure du Pacifique. Utilisez Web-Cron plus bas si vous avez besoin de chaque minute.
SiteGround
- Ouvrez Site Tools → Devs → Cron Jobs.
- Choisissez l'intervalle dans la liste (ou réglez minute, heure, jour, mois et jour de la semaine).
- Collez la ligne de l'étape 1 dans Command. Une adresse e-mail pour la sortie est facultative.
- Cliquez sur Create.
La documentation de SiteGround présente des préréglages comme Twice Per Hour et n'indique pas l'intervalle le plus court. Si votre offre n'a pas d'option chaque minute, utilisez Web-Cron plus bas.
- Ouvrez Settings → Système et copiez la Web-Cron URL. Gardez-la privée : elle contient votre jeton secret.
- Créez un compte gratuit sur un service cron comme cron-job.org.
- Créez une tâche, collez l'URL et réglez-la pour s'exécuter chaque minute. Enregistrez et activez-la.
- Utilisez Web-Cron ou une tâche cron de votre hébergeur, pas les deux : une seule suffit.
Attendez une ou deux minutes, puis rechargez Settings → Système. Le badge doit indiquer Actif et Dernier battement doit afficher une heure de la dernière minute. Santé du site sur la même page doit afficher le worker comme Réussi. Si votre hébergeur n'autorise une tâche que toutes les 5 ou 15 minutes, le badge peut alterner entre Actif et Cron non détecté, car il attend une exécution dans les 5 dernières minutes ; les e-mails partent quand même à chaque exécution du worker.
- La commande PHP est incorrecte. Demandez à votre hébergeur le chemin de PHP en ligne de commande (par exemple /opt/alt/php83/usr/bin/php chez Hostinger ou /usr/local/bin/php chez de nombreux hébergeurs cPanel) et remplacez php au début de la ligne.
- Seule une partie de la ligne a été collée. Collez la ligne entière, y compris >/dev/null 2>&1 à la fin.
- Le folder est incorrect. worker.php se trouve dans le folder qui contient public, pas dans public.
- Pour voir l'erreur, exécutez la tâche une fois sans >/dev/null 2>&1 et lisez sa sortie. Un worker qui fonctionne affiche une ligne comme worker.php: processed=0.
- La tâche concerne un autre site du même compte. Vérifiez le folder dans la commande.
- Laissez jusqu'à 5 minutes après l'enregistrement avant de vérifier à nouveau.
Pour les utilisateurs techniques
La compilation des e-mails, la résolution des requêtes d'audience, l'expédition et le traitement des webhooks fonctionnent de manière asynchrone via un worker en arrière-plan de 1 minute. MarbleSend utilise une architecture à double point d'entrée (CLI worker.php ou HTTP cron.php) protégée par des verrous de fichiers non bloquants pour éliminer les exécutions chevauchantes sur hébergement mutualisé.
* * * * * php /home/USER/your-folder/worker.php >/dev/null 2>&1
S'exécute directement depuis le shell du système d'exploitation (* * * * * php /chemin/vers/worker.php >/dev/null 2>&1). Contourne complètement les délais d'attente HTTP, idéal sur cPanel, Plesk et DirectAdmin.
GET https://your-domain.com/cron.php?token=SECURE_TOKEN
Pour les hébergements sans accès crontab shell, appeler GET /cron.php?token=SECURE_TOKEN via des services tiers (comme cron-job.org ou UptimeRobot) déclenche exactement le même traitement de file d'attente en toute sécurité.
Le worker verrouille storage/worker.lock avec flock(LOCK_EX | LOCK_NB) au démarrage. Si une exécution précédente traite encore une file d'attente importante, les exécutions suivantes se terminent sans race condition ni épuisement de mémoire.
Revendique des lots de 50 éléments de manière atomique à l'aide de requêtes d'état indexées. Les échecs d'envoi entraînent un backoff exponentiel avec compteurs de tentatives jusqu'à max_attempts avant l'état échoué.
6.3 23 Langues Natives, RTL Arabe & Machine de Sécurité Administrateur
MarbleSend est conçu comme une plateforme auto-hébergée internationale. Il intègre 23 dictionnaires de langues natives entièrement organisés par des humains, la mise en miroir automatique de droite à gauche pour l'arabe, la personnalisation persistante du thème tri-state et un périmètre de sécurité renforcé.
Les fichiers de langues dans app/lang/*.php sont de purs tableaux PHP chargés en mémoire en moins d'une milliseconde, sans binaire serveur gettext ni dépendance d'API de traduction externe.
La sélection de l'arabe (ar) injecte automatiquement dir='rtl' dans la racine du document HTML, inversant les barres latérales, les colonnes de tableaux, les volets et les icônes de navigation sur toute l'interface.
Permet de basculer facilement entre Dark Palette, Light Palette et la préférence du système. La sélection est enregistrée dans les cookies (marblesend_theme) pour garantir un chargement sans aucun décalage visuel.
Les identifiants d'administrateur stockés dans cm_settings.admin_user sont chiffrés avec bcrypt (facteur de travail 12). Protège contre la fixation de session via la régénération automatique de l'ID de session à la connexion.
6.3.1 Authentification à deux facteurs (TOTP) et configuration du code QR
L’authentification à deux facteurs ajoute un second verrou au compte administrateur : après le mot de passe, MarbleSend demande un code à 6 chiffres qui change toutes les 30 secondes et que seul votre téléphone peut générer. Elle est facultative, s’active en environ une minute et fonctionne avec toute application d’authentification standard comme Google Authenticator, Microsoft Authenticator, 1Password, Bitwarden, Authy ou Aegis. Vous la trouverez dans Settings → Langue et Compte → Authentification à deux facteurs (TOTP).
MarbleSend utilise le standard ouvert TOTP (RFC 6238 : HMAC-SHA1, 6 chiffres, pas de 30 secondes). L’activation crée un secret aléatoire partagé une seule fois avec votre application. Ensuite, la connexion demande le mot de passe puis un code valide. Un code déjà utilisé ne peut pas être rejoué et la seconde étape expire après 5 minutes.
1) Ouvrez Settings → Langue et Compte et cliquez sur Activer. 2) Dans votre application d’authentification, choisissez « Scanner un code QR » et scannez le carré affiché à l’écran. 3) Saisissez le code à 6 chiffres qu’affiche maintenant votre application et cliquez sur « Confirmer et activer ». 4) Enregistrez les huit codes de récupération, affichés une seule fois : copiez-les dans un gestionnaire de mots de passe ou imprimez-les.
L’image QR est dessinée par votre propre installation sous forme de petit graphique vectoriel ; le secret n’est jamais envoyé à un générateur de QR en ligne ni à un tiers. Si vous ne pouvez pas scanner (par exemple si l’application est sur le même téléphone), utilisez la clé de configuration ou le lien otpauth affiché sous le code QR. Le secret est stocké chiffré (AES-256-GCM) avec votre ENCRYPTION_KEY, comme tous les autres identifiants.
Après le bon mot de passe, le code à 6 chiffres vous est demandé. Les codes erronés sont limités par compte : deviner n’est pas envisageable. Si des codes correctement saisis sont refusés, vérifiez que la date et l’heure du téléphone sont réglées en automatique ; une horloge décalée produit des codes faux.
Huit codes à usage unique sont créés à l’activation de la 2FA. Chacun fonctionne une fois dans le champ du code à la place du code à 6 chiffres. Ils ne sont conservés que sous forme de hachages et ne peuvent donc plus être affichés ; utilisez « Nouveaux codes de récupération » (il faut un code valide) pour remplacer tout le lot, ce qui invalide les anciens.
Le lien envoyé par e-mail pour un mot de passe oublié ne contourne volontairement pas la 2FA ; il n’aide donc pas ici. Sur le serveur, exécutez « php tools/reset-admin.php » (SSH ou terminal de votre hébergeur) : il réinitialise le mot de passe administrateur, efface les verrouillages, met fin à toutes les sessions et désactive la 2FA ; vous pouvez ensuite la réactiver avec le nouvel appareil. Pour la désactiver normalement, utilisez Désactiver dans la même carte (mot de passe plus un code valide ou de récupération).
6.3.2 Protection de l’inscription (Cloudflare Turnstile) : obtenir vos clés gratuites
Turnstile est l’alternative gratuite et respectueuse de la vie privée de Cloudflare au CAPTCHA. Lorsqu’il est activé, vos pages d’inscription publiques (les formulaires /s/votre-page et /subscribe) vérifient que le visiteur est une vraie personne avant d’accepter un abonnement, ce qui empêche les robots d’inonder votre liste et vos e-mails de confirmation. Il s’ajoute au honeypot intégré et aux limites par IP et par adresse, et il est facultatif, sauf tant que vous envoyez via le SES Relay (voir la dernière note). Vous avez besoin de deux clés, une Site key (publique) et une Secret key (privée), issues de votre propre compte Cloudflare gratuit ; votre domaine n’a pas besoin d’utiliser Cloudflare pour le DNS.
Rendez-vous sur dash.cloudflare.com et inscrivez-vous (c’est gratuit) ou connectez-vous. Vous n’avez pas besoin d’ajouter votre site à Cloudflare ni de modifier votre DNS pour utiliser Turnstile.
Dans le menu du tableau de bord, ouvrez « Turnstile » (ou cherchez-le), puis cliquez sur « Add widget » (les anciens tableaux de bord affichent « Add site »). Les noms de menu changent de temps en temps ; cherchez Turnstile sous Application security.
Donnez-lui le nom de votre choix, par exemple « MarbleSend signup ». Sous Hostname, ajoutez le domaine où fonctionne MarbleSend, sans https:// ni chemin, par exemple app.votredomaine.com. Si vos pages d’inscription s’affichent sur un autre domaine, ajoutez-le aussi. N’ajoutez localhost que pour tester sur votre propre ordinateur.
Choisissez Managed (recommandé) : la plupart des visiteurs passent sans énigme et Cloudflare ne demande un clic rapide que lorsqu’une visite paraît suspecte. Non-interactive affiche une courte barre de progression sans clic, et Invisible n’affiche rien du tout. Laissez pre-clearance désactivé, puis cliquez sur Create.
Cloudflare affiche une Site key (publique) et une Secret key (privée). Copiez les deux. Le secret n’est utilisé que par votre serveur pour confirmer chaque visiteur auprès de Cloudflare ; ne le collez jamais dans un endroit public. Vous pourrez le consulter ou le renouveler plus tard dans les paramètres du widget.
Ouvrez Settings → Langue et Compte → Protection de l'inscription (Cloudflare Turnstile), collez la Site key et la Secret key, puis cliquez sur Enregistrer. Le badge passe à « La protection est ACTIVÉE ». Pour désactiver plus tard, videz les deux champs et enregistrez. Le secret enregistré est stocké chiffré et n’est plus jamais affiché ; laissez le champ vide pour le conserver.
Ouvrez l’une de vos pages d’inscription publiques dans une fenêtre de navigation privée : le widget Turnstile apparaît au-dessus du bouton. Inscrivez-vous avec une adresse de test et vous devriez recevoir l’e-mail de confirmation. Un envoi qui n’a pas passé la vérification est rejeté.
Si votre serveur ne peut pas joindre le service de vérification de Cloudflare (panne ou connexion sortante bloquée), MarbleSend laisse normalement passer l’inscription et consigne l’événement plutôt que de bloquer tous les visiteurs ; le honeypot et les limites par IP et par adresse continuent de s’appliquer. Tant que vous envoyez via le SES Relay, c’est l’inverse et le système échoue en mode fermé : les inscriptions sont refusées jusqu’à ce que Cloudflare soit de nouveau joignable.
Cloudflare publie des clés factices pour les tests : la Site key 1x00000000000000000000AA avec la Secret key 1x0000000000000000000000000000000AA réussit toujours. Elles ne protègent jamais un vrai site ; remplacez-les par vos propres clés avant la mise en ligne.
Le widget n’apparaît pas : vérifiez que le nom d’hôte de la page figure dans le widget Turnstile et qu’aucune extension du navigateur ne bloque challenges.cloudflare.com. « Invalid site key » : la Site key a été copiée avec un espace ou appartient à un autre widget. Des visiteurs réels sont refusés : recollez la Secret key ; elle doit appartenir au même widget que la Site key.
Si vous envoyez via le Managed Amazon SES Relay, Turnstile est obligatoire pour les formulaires d’inscription publics. Tant que les deux clés ne sont pas enregistrées, la page d’inscription affiche « l’inscription est temporairement indisponible » et Settings → Langue et Compte affiche un avis avec un bouton qui vous mène à la bonne carte. Dans ce mode, chaque nouvel abonné doit aussi confirmer par e-mail (double opt-in), même si une page d’inscription ou un appel API demande un single opt-in.
6.4 Clés REST API avec Portée & Accès Programmatique Développeur
La REST API permet aux sites web externes, landing pages, applications mobiles et au plugin officiel WordPress MarbleSend Forms d'interagir en toute sécurité avec vos contacts et votre moteur de diffusion. Les clés API utilisent un préfixe cryptographique, un stockage unidirectionnel SHA-256 et des portées de capacité granulaires.
Les clés sont générées avec un préfixe ms_ suivi de 32 octets aléatoires cryptographiquement sécurisés via random_bytes(24). La clé brute n'est révélée qu'une seule fois et ne peut plus jamais être récupérée.
Seul le hachage SHA-256 (hash('sha256', $rawKey)) est conservé dans cm_api_keys.key_hash. Même en cas de lecture directe de la base de données, les jetons actifs ne peuvent être ni déchiffrés ni récupérés.
Restreignez les clés à des autorisations précises : contacts:read, contacts:write, campaigns:read, campaigns:write, campaigns:send, schedules:read et schedules:write pour appliquer le moindre privilège.
Les requêtes entrantes s'authentifient via les en-têtes Authorization: Bearer ms_... évalués avec hash_equals(). Les journaux enregistrent l'horodatage exact last_used_at à chaque appel réussi.
6.5 Webhooks d'Événements Sortants & Livraison Cryptographique HMAC-SHA256
Les événements de contact (subscribed, confirmed, unsubscribed, suppressed) incluent désormais un tableau groups de {id, name} à côté de tags.
Les webhooks fournissent un flux d'événements HTTP en temps réel vers des endpoints externes, permettant aux CRM, alertes Slack ou flux d'automatisation de réagir instantanément aux inscriptions, diffusions de campagnes, désabonnements et rebonds durs.
Abonnez-vous aux déclencheurs essentiels : contact.created, contact.unsubscribed, campaign.sent, campaign.bounced et link.clicked avec activation individuelle par webhook.
Chaque requête POST de webhook comprend X-MarbleSend-Signature: sha256=... calculé avec hash_hmac('sha256', $payload, $secret), permettant aux serveurs récepteurs de vérifier l'authenticité.
Les échecs de livraison de webhooks (HTTP 5xx ou délais d'attente) déclenchent des tentatives avec backoff exponentiel. Les endpoints avec échecs consécutifs sont automatiquement suspendus pour éviter la surcharge.
Le bouton Test Webhook envoie immédiatement des charges utiles de test. Le volet d'historique de livraison affiche les codes d'état de réponse HTTP, la latence en millisecondes et les messages d'erreur.
6.6 La Suite de Délivrabilité à 4 Piliers (SPF, DKIM, DMARC, BIMI)
La délivrabilité détermine si vos messages arrivent dans la boîte de réception ou dans les spams. MarbleSend intègre un moteur d'inspection DNS qui exécute quatre requêtes séquentielles non bloquantes directement auprès des serveurs de noms faisant autorité sans dépendance d'API tierce.
Interroge les enregistrements TXT racines pour la syntaxe v=spf1. Vérifie les hôtes SMTP autorisés, signale les limites de recherche DNS (>10 recherches provoquent un hardfail) et vérifie les qualificatifs (~all ou -all).
Inspecte selector._domainkey.domain.com pour valider les clés cryptographiques publiques RSA ou Ed25519. Garantit que les en-têtes d'e-mails sortants peuvent être vérifiés cryptographiquement.
Vérifie _dmarc.domain.com pour les balises de stratégie (p=none, p=quarantine ou p=reject). En 2026, Gmail et Yahoo exigent des enregistrements DMARC actifs avec rapports rua.
Interroge default._bimi.domain.com pour les fichiers de logo de marque SVG Tiny P.S. et certificats VMC, activant l'affichage d'avatars de marque vérifiés directement dans Gmail, Yahoo et Apple Mail.
6.7 Moteur IA bi-mode: Fournisseurs BYOK & Crédits IA MarbleSend
MarbleSend propose un moteur d'IA bi-mode polyvalent pour la rédaction, la suggestion d'objets et l'audit anti-spam: (1) Bring Your Own Key (BYOK) pour se connecter directement aux grands modèles de langage sans marge, et (2) Crédits IA MarbleSend pour un accès instantané à la carte à des modèles sélectionnés sans gérer de clés API.
Connectez-vous directement à OpenAI, Anthropic Claude, Google Gemini, DeepSeek, Moonshot, OpenRouter ou à vos instances privées Ollama. Vos clés API sont chiffrées au repos via AES-256-GCM. Les requêtes vont directement de votre serveur à l'API du fournisseur sans frais intermédiaires.
Crédits IA prépayés gérés directement via MarbleSend. Inclut des modèles sélectionnés ultra-performants optimisés pour la conversion marketing et la délivrabilité. Le serveur fournisseur gère le routage et les mises à niveau de manière dynamique, déduisant 1 crédit par génération atomiquement.
Official add-on pricing is retrieved dynamically from admin.marblesend.com. Purchase top-up credit packs via global and local payment gateways with instant real-time balance activation.
All BYOK credentials are encrypted at rest with hardware-accelerated AES-256-GCM using your installation's unique APP_KEY. No prompt contents, contact lists, or recipient emails are ever stored or logged by the license server.
6.7.1 Sélection du Modèle par Défaut et Routage d'Exécution
Définit la façon dont MarbleSend achemine la rédaction IA, les suggestions d'objets et les audits de délivrabilité. Basculez facilement entre les relais gérés et vos propres clés BYOK.
Accès sans configuration à des modèles d'élite sélectionnés pour la conversion email. Aucun compte développeur externe ni clé API requis.
Communication directe de serveur à fournisseur sans marge ajoutée. Choisissez un fournisseur configuré et un identifiant de modèle par défaut.
Templates Studio, l'inspecteur de score d'objet et l'assistant IA s'exécutent automatiquement selon le modèle actif avec repli fluide en cas de solde épuisé.
La sélection active est enregistrée dans cm_settings.ai_provider_default, garantissant une exécution synchronisée entre sessions admin et tâches worker.
6.7.2 Crédits IA MarbleSend et Hub de Relais Géré
Les Crédits IA MarbleSend fournissent une infrastructure prépayée instantanée pour la rédaction email sans contraintes de facturation ou quotas tiers.
Chaque licence activée reçoit des crédits IA initiaux gratuits récupérés dynamiquement depuis le serveur de licences pour tester AI Assist sans attendre.
Les générations débitent exactement 1 crédit par requête via cm_addon_ledger. Des UUID uniques de transaction empêchent tout double débit lors des reconnexions.
Les packs de crédits (ex. ai_100) sont chargés dynamiquement depuis le catalogue du fournisseur. Paiements sécurisés gérés par notre prestataire de paiement.
Les événements webhook créditent instantanément votre compte après paiement. Un bouton d'actualisation en 1 clic assure une synchronisation immédiate.
6.7.3 Fournisseurs Configurés et Infrastructure BYOK
Connectez et orchestrez plusieurs fournisseurs LLM avec stockage chiffré des clés, prise en charge de protocoles doubles et diagnostics de connexion instantanés.
Maintenez des liaisons simultanées vers OpenAI, Anthropic Claude, Google Gemini, DeepSeek, Kimi/Moonshot, OpenRouter ou instances privées Ollama.
Prend en charge les points de terminaison compatibles OpenAI (/chat/completions) et le format messages d'Anthropic (/v1/messages) avec URLs proxy personnalisées.
Toutes les clés API BYOK sont chiffrées au repos par accélération matérielle AES-256-GCM. Elles ne sont jamais divulguées dans le HTML ou les logs.
Le bouton de test de connexion envoie une requête légère pour vérifier les identifiants et mesurer la latence aller-retour (ms) avant la mise en production.
Comment Obtenir les Clés API des Principaux Fournisseurs
MarbleSend se connecte directement aux fournisseurs d'IA via BYOK sans passer par des proxys tiers. Retrouvez ci-dessous les liens officiels et consignes de génération :
Fournisseurs Locaux, Auto-Hébergés et Alternatifs (Ollama, Groq, Mistral, GLM)
Pour une IA locale gratuite, installez Ollama (ollama.com), lancez un modèle (ex. : ollama run llama3.1), réglez Base URL sur http://localhost:11434/v1, sélectionnez le format OpenAI et cochez "No Auth". Pour une inférence cloud ultra-rapide, inscrivez-vous sur console.groq.com.
Configuration des AI Providers dans les Settings (/settings)
Une fois votre clé API et votre ID de modèle obtenus, configurez MarbleSend selon ces étapes simples :
Dans le menu latéral, cliquez sur Settings puis ouvrez l'onglet "AI Providers" (accessible directement sur /settings).
Cliquez sur un bouton prédéfini Quick Add (OpenAI, DeepSeek, Gemini, Anthropic, etc.) pour un pré-remplissage immédiat ou sur "+ Add Provider".
Sélectionnez le format : "OpenAI format" ou "Anthropic format". Confirmez la Base URL correspondante.
Collez votre clé secrète. MarbleSend la stocke chiffrée en AES-256-GCM via Crypto.php sans aucune exposition en clair.
Saisissez l'ID de modèle et la limite de context window, puis cliquez sur "Test Connection" pour valider la communication en direct.
Dans la section "Default AI Model" en haut, choisissez le fournisseur et le modèle configurés, puis cliquez sur "Save Default".
6.8 Moteur de Token d'Octroi de Licence Cryptographique Ed25519
MarbleSend vérifie l'authenticité du produit par cryptographie asymétrique Ed25519 via l'extension native libsodium de PHP. Un License Grant Token signé est émis lors de l'activation initiale et validé localement sans connexion permanente.
Valide la signature numérique avec sodium_crypto_sign_verify_detached(). Toute altération manuelle en base de données invalide immédiatement la signature mathématique, garantissant une intégrité absolue.
Le jeton signé intègre le nom d'hôte du domaine sous licence, le niveau de licence (Regular ou Extended) et les droits actifs. Les déplacements multi-domaines peuvent être effectués directement depuis l'interface des paramètres.
Les coupures de réseau temporaires ou la maintenance du serveur de licences n'interrompront jamais les campagnes d'e-mails en cours ni l'exécution du cron. MarbleSend offre une période de grâce de 7 jours avant restriction.
Si une licence expire, MarbleSend applique un verrouillage souple : les données d'abonnés existantes, les campagnes, les rapports et les outils d'exportation restent accessibles à 100 %, tandis que les nouveaux envois sont suspendus.
Une fois par jour, le worker demande au serveur de licences s'il existe une version plus récente. Il n'envoie que votre code d'achat et la version installée, exactement comme la vérification manuelle. Désactivez-le avec « Mises à jour des versions » dans cet onglet : aucune vérification n'est effectuée et aucune bannière de mise à jour n'est affichée. Les installations de développement (APP_ENV=local) n'effectuent jamais cet appel. Rien concernant vos contacts ou vos Campaigns n'est jamais envoyé.
« Journal des modifications » (barre latérale, au-dessus de Documentation) liste chaque version avec son guide de mise à niveau. Lorsqu'une version plus récente existe, vous voyez une bannière sur le tableau de bord (une mise à jour de sécurité affiche une bannière rouge sur chaque page et ne peut pas être fermée), un point à côté de « Journal des modifications » et, si l'option est activée, un e-mail par version à l'adresse de l'administrateur via votre profil SMTP par défaut. Les notes de version sont rédigées en anglais.
Foire aux questions & diagnostics
Solutions immédiates pour les problèmes d'hébergement mutualisé les plus courants.
7.1 Diagnostic Dashboard & opérations
7.1.1 Pourquoi le Dashboard affiche-t-il l'état "Worker Not Detected" ou inactif ?
La tâche cron du système d'exploitation ne s'exécute pas, le chemin PHP CLI est erroné ou un file de verrou résiduel bloque l'exécution.
Le worker met à jour cm_settings.worker_last_run avec un horodatage UTC à chaque pulsation. Le dashboard signale une inactivité si le délai dépasse 180 secondes.
Rendez-vous dans Settings → System. Copiez la ligne crontab exacte. Si le cron CLI est restreint, configurez l'URL Web-Cron sur cron-job.org toutes les 1 minute. Si le verrou persiste, vérifiez storage/worker.lock.
7.1.2 Pourquoi les taux d'ouverture et de clic diffèrent-ils entre le Dashboard et les journaux du fournisseur SMTP ?
Préchargement Apple Mail Privacy Protection (MPP), mise en cache proxy, blocage des images par le destinataire ou bloqueurs retirant les paramètres UTM.
MarbleSend intègre un GIF de suivi transparent 1x1 dans les emails sortants pour consigner cm_email_logs.opened_at. Si les images sont bloquées, l'ouverture n'est pas enregistrée ; Apple MPP précharge les images immédiatement sur ses serveurs.
Fiez-vous aux clics uniques (CTR) comme indicateur majeur d'engagement. MarbleSend redirige les liens des templates via public/click.php afin de consigner des clics infalsifiables.
7.2 Diagnostic d'envoi de Campaign & Preflight
7.2.1 Pourquoi mon envoi de campaign s'est-il interrompu ou mis en pause en cours de route ?
Limites de temps d'exécution PHP CLI ou du serveur web en shared hosting (max_execution_time 30s/60s) atteintes lors d'envois massifs.
MarbleSend traite la file d'attente par lots atomiques de 50 destinataires. À l'approche de la limite de temps, le worker quitte proprement et valide l'avancement dans cm_email_queue pour préserver la mémoire.
Aucune intervention manuelle requise ! Le cycle cron de la minute suivante reprendra automatiquement le lot d'éléments pending dans cm_email_queue sans aucun doublon.
7.2.2 Pourquoi la vérification de sécurité Preflight automatique en 6 points bloque-t-elle le lancement de ma campaign ?
Balise obligatoire {{unsubscribe_link}} manquante, objet non valide, aucun destinataire actif sélectionné ou syntax de token non fermée.
Le moteur Preflight contrôle 6 vecteurs critiques de conformité et de deliverability avant d'autoriser la transition d'état vers queued ou sending.
Consultez les avertissements rouges dans la modale preflight de la campaign. Insérez {{unsubscribe_link}} (requis par la RFC 8058 et CAN-SPAM) et vérifiez les tags des contacts actifs.
7.2.3 Quand le bouton "Resend to Non-openers" devient-il actif et comment évite-t-il la lassitude des abonnés ?
Le bouton dans le rapport de campaign est désactivé tant que l'envoi est en cours ou qu'un délai de temporisation sécurisé n'est pas écoulé.
MarbleSend exige le statut campaign = completed et préconise un délai d'au moins 24 à 48 heures pour laisser le temps aux destinataires sur d'autres fuseaux d'ouvrir l'email.
Une fois l'envoi terminé, cliquez sur "Resend to Non-openers". Cela génère une sous-campagne ciblant uniquement les contacts ayant opened_at IS NULL, vous permettant de tester un autre objet.
7.3 Gestion des Contacts, import CSV & rebonds
7.3.1 Pourquoi l'outil d'import CSV a-t-il ignoré des lignes ou échoué à importer certains record d'abonnés ?
Syntax d'email non conforme à la RFC 5322, adresses en double avec l'option "Skip Duplicates", encodage non UTF-8 ou contacts supprimés/bloqués.
MarbleSend analyse chaque ligne, vérifie la syntax via filter_var(FILTER_VALIDATE_EMAIL) et contrôle cm_contacts pour ne pas écraser les statuts unsubscribed ou bounced.
Enregistrez votre file CSV au format UTF-8 sans BOM. Vérifiez le mappage des colonnes (email, name, tags). Consultez la modale de progression pour repérer les numéros de ligne ignorés.
7.3.2 Comment MarbleSend gère-t-il les rebonds temporaires (Soft Bounces) par rapport aux définitifs (Hard Bounces) ?
Échecs de distribution permanents (codes d'erreur SMTP 5xx : boîte inexistante) versus échecs temporaires (codes d'erreur SMTP 4xx : boîte pleine, limite de débit).
Une réponse 5xx bascule immédiatement le contact en statut bounced. Une réponse 4xx consigne une tentative dans cm_email_logs et réessaie jusqu'à 3 fois avant de marquer bounced.
Ne tentez pas de réactiver des contacts en rebond dur (hard bounce). Cela dégraderait fortement la réputation de votre domaine auprès de Gmail et Yahoo.
7.4 Rendu des Templates, Outlook & conception email-safe
7.4.1 Pourquoi mon template d'email apparaît-il déformé ou mal aligné dans Microsoft Outlook pour bureau ?
Microsoft Outlook pour Windows emploie le moteur de rendu de Microsoft Word (MSO), qui ne supporte pas CSS Flexbox, Grid, margin auto ni les balises de mise en page HTML5.
Word MSO ne respecte que les structures traditionnelles à base de tableaux (nested <table>, <tr>, <td>) avec largeurs explicites en pixels et styles inline.
Utilisez les 8 starter layouts email-safe intégrés à MarbleSend. Ils reposent sur des tableaux HTML imbriqués et des commentaires conditionnels MSO (<!--[if mso]>) pour un rendu parfait sur Outlook.
7.4.2 Pourquoi Gmail indique-t-il "[Message clipped] View entire message" en bas de mes emails ?
La taille du code HTML brut de l'email excède la limite stricte de 102 Ko (104 448 octets) imposée par Gmail.
Au-delà de 102 Ko, Gmail tronque le message, dissimulant une partie du contenu ainsi que le lien de désinscription du pied de page et le pixel de suivi.
Hébergez vos images sur des serveurs HTTPS externes plutôt que d'intégrer des chaînes base64 inline. Évitez le CSS superflu. Dans Templates Studio, cliquez sur "Clean HTML" avant l'envoi.
7.4.3 Pourquoi {{news_posts}} est-il vide ou absent de mon e-mail ?
Le marqueur n'est rempli que par une planification de Newsletter dont la Source du contenu est « Articles d'actualité ». Dans une Campaign manuelle, une planification RSS ou une planification à modèle seul, il est remplacé par du texte vide.
La vérification préalable de la Campaign affiche un avertissement quand un modèle utilise {{news_posts}} sans source d'articles d'actualité ; l'aperçu dans Modèles → Articles montre toujours le bloc rempli.
Envoyez le modèle via une planification de Newsletter réglée sur « Articles d'actualité », ou retirez le marqueur des modèles utilisés ailleurs.
7.5 Schedules, flux RSS & cadence du Worker
7.5.1 Pourquoi mon schedule RSS automatisé n'a-t-il rien envoyé lors de la publication d'un nouvel article ?
L'URL du flux était inaccessible, la syntax XML était corrompue ou le GUID du dernier article correspondait à cm_schedules.last_rss_item_id.
MarbleSend enregistre une empreinte SHA-256 du dernier élément dans last_rss_item_id. En l'absence de nouvel <item> ou <entry>, le worker termine son exécution sans créer d'élément en file.
Ouvrez le schedule dans /schedules et cliquez sur "Test Feed" pour inspecter la réponse XML en direct. Assurez-vous que le flux RSS renvoie des balises <pubDate> valides et un <guid> unique.
7.5.2 Qu'advient-il des schedules récurrents si le serveur ou le cron du worker est resté hors ligne plusieurs jours ?
Plusieurs occurrences planifiées se sont accumulées pendant que le processus worker ne pouvait pas tourner.
MarbleSend applique une stricte "Single Catch-Up Policy" dans SchedulerService. Plutôt que de lancer toutes les occurrences en retard (ce qui spammerait les boîtes), il n'exécute que la plus récente.
Dès que le cron redémarre, exactement 1 broadcast de rattrapage est assemblé et envoyé. L'horodatage next_run_at du schedule est automatiquement recalé sur la prochaine échéance prévue.
7.5.3 Pourquoi ma planification d'articles d'actualité n'a-t-elle pas envoyé mon article Prêt ?
L'article est devenu Prêt avant l'activation du mode Articles d'actualité de la planification, il a déjà été remis par cette planification, ou l'audience ou le modèle ont bloqué l'exécution.
Ouvrez l'historique de la planification : « no new posts » signifie que rien n'est éligible, « no recipients » que l'audience était vide, et « failed » que le modèle est absent ou ne contient pas {{news_posts}}.
Marquez Prêt une copie de l'article une fois la planification créée, corrigez l'audience ou le modèle, puis utilisez Exécuter maintenant.
7.5.4 Deux planifications peuvent-elles envoyer le même article ?
L'envoi est suivi par planification, pas par article.
Chaque planification d'articles d'actualité tient son propre registre des articles remis ; la bibliothèque affiche donc le total « Envoyé N× ».
Oui — un article Prêt après la création des deux planifications est envoyé une fois par chacune ; aucune ne l'envoie deux fois.
7.6 Settings, Deliverability, Webhooks & licences
7.6.1 Comment résoudre les erreurs SMTP "535 Authentication Failed" ou "550 Relay Access Denied" ?
Identifiants SMTP erronés, discordance entre port et chiffrement (Port 587 STARTTLS vs Port 465 SSL) ou adresse email d'expéditeur non validée.
Settings → SMTP comprend un test de socket en direct qui affiche le dialogue brut entre PHPMailer et votre serveur SMTP.
Utilisez le port 587 avec TLS pour la majorité des relais. Pour Gmail/Google Workspace, générez un App Password. Pour Amazon SES, validez le domaine d'expédition. Pour cPanel, indiquez l'adresse complète comme nom d'utilisateur.
7.6.2 Pourquoi la Deliverability Suite indique-t-elle des erreurs de validation SPF, DKIM ou DMARC ?
Enregistrements DNS absents sur le domaine expéditeur, dépassement de la limite de 10 requêtes pour SPF ou préfixe de sélecteur DKIM erroné.
MarbleSend réalise des requêtes DNS non bloquantes (dns_get_record) directement auprès des serveurs de noms faisant foi pour SPF (root TXT), DKIM (selector._domainkey) et DMARC (_dmarc).
Ajoutez le mécanisme include de votre relais SMTP à votre record SPF. Vérifiez que le sélecteur DKIM concorde avec votre relais. Veillez à inclure une adresse rua d'analyse dans votre enregistrement DMARC.
7.6.3 Comment fonctionne le Circuit Breaker des Webhooks et comment réactiver un endpoint mis en pause ?
Votre endpoint de réception a renvoyé des erreurs HTTP 5xx répétées, des délais d'attente (>10s) ou des erreurs 404 Not Found.
Afin d'éviter l'engorgement de la file du serveur, MarbleSend enregistre les tentatives et désactive automatiquement le webhook (enabled = 0) après plusieurs échecs consécutifs.
Ouvrez le panneau d'historique de livraison des webhooks pour inspecter les codes d'état HTTP et les corps d'erreur. Une fois votre API corrigée, cliquez sur "Test Webhook", vérifiez la signature HMAC et réactivez-le.
7.6.4 Comment fonctionne la validation de licence Ed25519 et qu'est-ce que le délai de grâce hors ligne de 7 jours ?
Coupures réseau, défaillances de résolution DNS ou maintenance temporaire sur le serveur de licences en amont.
L'authenticité de la licence est contrôlée localement en mémoire au moyen de libsodium sodium_crypto_sign_verify_detached(). Toute altération de la base invalide immédiatement la signature cryptographique.
MarbleSend intègre une période de grâce hors ligne de 7 jours (grace_until). Les envois en cours se poursuivent sans interruption. En cas d'expiration, les données de contacts et rapports restent 100 % accessibles sous soft-lock.
Intégrations WordPress & Formulaires Tiers
Recueillez des abonnés sur un site WordPress et envoyez-les à MarbleSend. Le plugin complémentaire a son propre formulaire d'abonnement et connecte WPForms, Contact Form 7, Fluent Forms, Formidable Forms et Forminator.
Inspecteur d'intégration de formulaires
Sélectionnez un composant pour voir son hook, ce qu'il envoie et un conseil de configuration.
Pont REST API
Aucune base de données partagéeFile d'envoi
Stockage transientMarbleSend Form
Shortcode, Block & WidgetHook WPForms
wpforms_process_completeHook Contact Form 7
wpcf7_mail_sentHook Fluent Forms
submission_insertedFormidable Forms
frm_after_create_entryHook Forminator
submit_before_set_fieldsAutoresponders par tag
Tags et emails de bienvenueInstallez d'abord le plugin complémentaire (marblesend-forms.zip)
MarbleSend tourne sur son propre serveur : WordPress a donc besoin d'un petit plugin pour lui envoyer des abonnés. Le plugin fait fonctionner le formulaire MarbleSend intégré et connecte WPForms, Contact Form 7, Fluent Forms, Formidable Forms et Forminator. Il est gratuit, demande WordPress 6.3 ou plus récent et PHP 7.4 ou plus récent, et ne parle à MarbleSend que par la REST API.
Où apparaissent les menus Settings ?
Une fois le plugin activé, WordPress affiche deux pages sous Settings dans wp-admin : MarbleSend Forms (URL de connexion, API key, tags par défaut et journal des échecs) et MarbleSend Integrations (association des champs de chaque plugin de formulaires). Les deux se trouvent dans WordPress. Le tableau de bord MarbleSend ne les a pas. Vos propres formulaires, avec leur groupe, leurs tags et leur protection anti-spam, se gèrent sous MarbleSend Forms dans la barre latérale.
1. Téléchargez marblesend-forms.zip
Téléchargez marblesend-forms.zip depuis Settings → Licence dans MarbleSend, ou directement depuis https://marblesend.com/download/marblesend-forms.zip. C'est un zip de plugin WordPress prêt à installer : envoyez-le tel quel, sans le décompresser.
2. Installez et activez dans WordPress
Dans wp-admin, allez à Plugins → Add New → Upload Plugin, choisissez marblesend-forms.zip, cliquez sur Install Now puis sur Activate Plugin. Pour mettre à jour plus tard, envoyez le nouveau zip de la même façon. WordPress propose de remplacer la version installée, et vos réglages sont conservés.
3. Connectez l'API key (contacts:write)
Dans MarbleSend, ouvrez Settings → API et Webhooks et créez une API key avec le scope contacts:write. Dans WordPress, ouvrez Settings → MarbleSend Forms, saisissez votre MarbleSend Site URL et la key, enregistrez, puis cliquez sur Test Connection. Le résultat doit afficher Connected avec le scope contacts:write. Choisissez ensuite un Default Group et des Default Tags dans les listes chargées depuis MarbleSend, ou créez-y un nouveau groupe.
4. Associez vos formulaires
Dans wp-admin, ouvrez Settings → MarbleSend Integrations. Chaque plugin de formulaires actif apparaît avec ses formulaires. Cochez Enabled, saisissez le champ email et, si le formulaire en a un, le champ nom, ajoutez des tags si vous le souhaitez, puis enregistrez. Le formulaire intégré n'a pas besoin d'association.
8.1 Comment le plugin dialogue avec MarbleSend
Le plugin appelle la REST API de MarbleSend en HTTPS : WordPress et MarbleSend peuvent donc tourner sur des serveurs différents. Il n'a aucun accès à la base de données de MarbleSend.
WordPress ne lit jamais les tables de MarbleSend, et MarbleSend ne lit jamais wp_posts ni wp_users. Les deux peuvent tourner sur des hébergements séparés avec des bases de données séparées.
Chaque requête porte une API key Bearer issue de Settings → API et Webhooks. Le scope contacts:write suffit : la key ne peut ni envoyer de Campaigns ni modifier de planifications.
Test Connection dans Settings → MarbleSend Forms appelle GET /api/verify-key et affiche les scopes de la key : une URL ou une key erronée se voit tout de suite.
Chaque envoi part vers POST /api/contacts. Un nouvel email devient un contact. Un contact existant garde son statut et reçoit les nouveaux tags en plus des siens ; son nom ne change que si le formulaire en envoie un. Avec le double opt-in activé, un nouveau contact reste pending jusqu'à sa confirmation.
curl -X POST https://your-domain.com/api/contacts \
-H "Authorization: Bearer ms_live_abc123..." \
-H "Content-Type: application/json" \
-d '{"email":"visitor@example.com","name":"John Doe","tags":["newsletter","source:wpforms"]}'
Facultatif : ajoutez "group_ids":[1,2] pour placer le contact dans des groupes précis (listez-les avec GET /api/groups ; omis = General). GET /api/contacts accepte group_id pour filtrer par groupe.
8.2 File d'envoi et WP-Cron
Un MarbleSend lent ou injoignable ne doit ni bloquer le formulaire d'un visiteur ni faire perdre un lead. Les envois des plugins de formulaires sont mis en file et transmis en arrière-plan.
Quand un plugin de formulaires soumet, MarbleSend_Integration_Base::dispatch() nettoie les champs et les enregistre dans un transient WordPress (set_transient). Aucune requête vers MarbleSend n'a lieu pendant que le visiteur attend.
Un événement WP-Cron, marblesend_forms_process_queue, est planifié environ une minute plus tard et transmet les envois en file.
WP-Cron envoie chaque élément de la file une seule fois. Le formulaire intégré appelle d'abord MarbleSend directement et ne met l'envoi en file, pour une tentative de WP-Cron, que si cet appel échoue. Un élément en file est conservé une heure au plus.
Si l'envoi échoue, ou si un élément expire avant que WP-Cron ait pu l'envoyer, le plugin ajoute une ligne à marblesend_forms_log (les 50 derniers records sont conservés) et affiche un avis d'administrateur dans wp-admin. Settings → MarbleSend Forms liste le journal et le nombre d'éléments en attente.
// Non-blocking submission buffer in WordPress
set_transient('marblesend_forms_queue_' . wp_generate_uuid4(), $payload, 3600);
if (!wp_next_scheduled('marblesend_forms_process_queue')) {
wp_schedule_single_event(time() + 5, 'marblesend_forms_process_queue');
}
8.3 Le formulaire d'abonnement intégré
Le plugin inclut un formulaire d'abonnement : vous n'avez pas besoin d'un constructeur de formulaires. Ajoutez-le avec un shortcode, un bloc Gutenberg ou un widget. Les trois exécutent le même code.
Utilisez [marblesend_form], le bloc Gutenberg marblesend/subscribe-form ou le widget MarbleSend Subscribe Form. Le shortcode accepte tags, show_name (1 ou 0) et consent (le texte d'une case à cocher obligatoire). Le bloc et le widget offrent les mêmes options. Créez vos propres formulaires dans MarbleSend Forms → Add New Form et intégrez-en un avec [marblesend_form id="12"].
Un champ honeypot hors écran (marblesend_hp), un nonce demandé à l'envoi du formulaire afin qu'une page en cache ne serve jamais un nonce expiré, et une limite de 5 envois par 60 secondes par IP (stockée hachée). Une requête qui remplit le honeypot ou n'a pas de nonce valide reçoit un message de succès d'apparence normale et est écartée. Trop de requêtes reçoivent un bref message « patientez un instant ». Les formulaires créés dans l'éditeur peuvent aussi utiliser Cloudflare Turnstile ou Google reCAPTCHA, réglés dans Settings → MarbleSend Forms.
La page ne se recharge pas. Le plugin envoie aussitôt le contact à MarbleSend (délai de 5 secondes). Si MarbleSend est injoignable, ou si le plugin n'est pas encore configuré, l'envoi passe en file pour une tentative de WP-Cron et le visiteur voit quand même le message de succès. Si la requête elle-même échoue, le formulaire affiche une erreur et peut être renvoyé.
Quand le visiteur ne donne qu'un email, un nouveau contact est nommé d'après la partie avant le @, car l'API exige un nom. Un contact existant garde son nom. Chaque contact reçoit le tag source:wp-form ainsi que les tags du formulaire et de Settings → MarbleSend Forms. Avec le double opt-in activé, le visiteur voit un message l'invitant à vérifier ses emails. Le contact rejoint le groupe du formulaire, ou le Default Group de Settings → MarbleSend Forms.
[marblesend_form tags="newsletter,inbound" show_name="1" consent="I agree to receive email updates and accept the privacy policy."]
8.4 WPForms (Lite et Pro)
WPForms est l'un des constructeurs de formulaires les plus utilisés. Le plugin lit l'envoi une fois que WPForms l'a validé : aucun module complémentaire WPForms n'est nécessaire.
Le plugin détecte WPForms avec function_exists('wpforms') et écoute l'action wpforms_process_complete (priorité 10), qui reçoit les champs validés.
WPForms identifie les champs par un numéro. Sélectionnez un champ dans le constructeur et lisez son ID en haut des options du champ, par exemple Field ID #2. Saisissez ce numéro dans l'association. Un champ de nom avec prénom et nom est réuni en un seul nom.
1. Notez l'ID du champ Email et, s'il existe, du champ Nom. 2. Ouvrez Settings → MarbleSend Integrations et repérez WPForms. 3. Cochez Enabled, saisissez les ID et les tags éventuels. 4. Enregistrez.
Chaque contact venant de WPForms reçoit le tag source:wpforms à côté de vos propres tags, ce qui permet d'envoyer une Campaign à ce seul groupe.
add_action('wpforms_process_complete', function($fields, $entry, $form_data, $entry_id) {
$email = $fields[1]['value'] ?? ''; // Numeric Field ID #1
$name = $fields[0]['value'] ?? ''; // Numeric Field ID #0
MarbleSend_Integration_Base::dispatch('wpforms', $form_data['id'], $email, $name);
}, 10, 4);
8.5 Contact Form 7 (CF7)
Contact Form 7 définit ses champs sous forme de tags dans un modèle texte. Le plugin intervient après l'envoi de l'email du formulaire.
Le plugin détecte CF7 avec class_exists('WPCF7_ContactForm') et écoute wpcf7_mail_sent (priorité 10). Un lead n'est transmis qu'après les contrôles anti-spam et de validation et l'envoi de l'email propre à Contact Form 7. Si l'envoi d'email échoue chez votre hébergeur, rien n'est transmis.
CF7 nomme un champ dans son tag, par exemple [email* your-email] et [text your-name]. Saisissez le nom (your-email, your-name) dans les cases Email Field et Name Field.
Le plugin lit les données envoyées avec WPCF7_Submission::get_instance()->get_posted_data(), ce qui fonctionne avec l'envoi AJAX de CF7.
1. Dans Contact → Contact Forms, ouvrez le formulaire et notez les noms des tags. 2. Dans Settings → MarbleSend Integrations, repérez Contact Form 7. 3. Cochez Enabled, saisissez your-email et, si le formulaire en a un, your-name, puis ajoutez des tags si besoin. 4. Enregistrez.
add_action('wpcf7_mail_sent', function($contact_form) {
$submission = WPCF7_Submission::get_instance();
$data = $submission ? $submission->get_posted_data() : [];
$email = $data['your-email'] ?? '';
$name = $data['your-name'] ?? '';
MarbleSend_Integration_Base::dispatch('cf7', $contact_form->id(), $email, $name);
}, 10, 1);
8.6 Fluent Forms (Free et Pro)
Le plugin écoute l'action que Fluent Forms déclenche après l'enregistrement d'une entrée.
Le plugin détecte Fluent Forms avec function_exists('wpFluent') et écoute fluentform/submission_inserted (priorité 10), qui reçoit $entry_id, $form_data et $form.
Fluent Forms identifie les champs par leur Name Attribute, par exemple email pour l'email et names pour le champ de nom (prénom et nom sont réunis). Vous le trouverez dans les réglages du champ, sous Advanced Options.
La page Integrations liste vos formulaires en lisant la table de formulaires de Fluent Forms : inutile de chercher les ID de formulaire.
1. Vérifiez le Name Attribute des champs email et nom. 2. Dans Settings → MarbleSend Integrations, cochez Enabled pour le formulaire et saisissez les deux. 3. Ajoutez des tags et enregistrez. Les nouveaux contacts reçoivent le tag source:fluentforms.
add_action('fluentform/submission_inserted', function($entryId, $formData, $form) {
$email = $formData['email'] ?? '';
$name = is_array($formData['names'] ?? null) ? implode(' ', $formData['names']) : ($formData['first_name'] ?? '');
MarbleSend_Integration_Base::dispatch('fluentforms', $form->id, $email, $name);
}, 10, 3);
8.7 Formidable Forms (Lite et Pro)
Le plugin lit l'entrée juste après son enregistrement par Formidable Forms.
Le plugin détecte Formidable avec class_exists('FrmForm') et écoute frm_after_create_entry (priorité 30), qui reçoit $entry_id et $form_id.
Formidable attribue un Field ID numérique (p. ex. 12) à chaque champ. Saisissez-le dans l'association ; les clés de champ ne sont pas prises en charge. Les données sont extraites via FrmEntry::getOne($entry_id)->metas.
Le plugin s'exécute après la création de l'entrée : seuls les envois qui ont passé la validation de Formidable sont transmis.
1. Dans le constructeur Formidable, cliquez sur le champ email et notez son Field ID. 2. Dans Settings → MarbleSend Integrations, activez le formulaire et saisissez le Field ID. 3. Enregistrez l'association. Les leads importés reçoivent le tag source:formidable.
add_action('frm_after_create_entry', function($entryId, $formId) {
$entry = FrmEntry::getOne($entryId, true);
$email = $entry->metas[12] ?? $entry->metas['email-address'] ?? '';
$name = $entry->metas[11] ?? $entry->metas['full-name'] ?? '';
MarbleSend_Integration_Base::dispatch('formidable', $formId, $email, $name);
}, 30, 2);
8.8 Forminator (Free et Pro)
Le plugin écoute le hook que Forminator déclenche pendant le traitement d'un envoi.
Le plugin détecte Forminator avec class_exists('Forminator_API') et écoute forminator_custom_form_submit_before_set_fields (priorité 10), qui reçoit $entry, $form_id et $field_data.
Forminator attribue à chaque champ un element ID tel que email-1, name-1 ou text-1. Saisissez ces ID dans l'association. L'éditeur de formulaire les affiche.
La page Integrations liste vos formulaires Forminator par nom, lus avec Forminator_API::get_forms().
1. Ouvrez Forminator et notez les element ID (email-1, name-1). 2. Dans Settings → MarbleSend Integrations, repérez Forminator et saisissez les ID. 3. Ajoutez des tags et enregistrez. 4. Faites un envoi de test et vérifiez que le contact porte le tag source:forminator.
add_action('forminator_custom_form_submit_before_set_fields', function($formId, $response, $fieldData) {
$fields = array_column($fieldData, 'value', 'name');
$email = $fields['email-1'] ?? '';
$name = $fields['name-1'] ?? '';
MarbleSend_Integration_Base::dispatch('forminator', $formId, $email, $name);
}, 10, 3);
8.9 Tags, segments et autoresponders
Les contacts du plugin WordPress rejoignent le groupe choisi dans Settings → MarbleSend Forms (Default Group) ou sur le formulaire, et arrivent dans General si aucun n'est choisi. Utilisez les tags pour les segmenter, ou déplacez-les vers des groupes depuis Contacts.
Recueillir un email n'est que la première étape. Les tags déterminent ce qui arrive ensuite au contact.
En plus de vos propres tags, chaque contact reçoit source:<slug> : source:wp-form, source:wpforms, source:cf7, source:fluentforms, source:formidable ou source:forminator. Utilisez-les pour envoyer une Campaign aux abonnés d'un seul plugin de formulaires.
Dans /contacts → Autoresponders, créez une règle pour le tag attribué à votre formulaire WordPress. Quand le contact devient actif (juste après l'envoi, ou après confirmation du double opt-in), MarbleSend met en file votre email de bienvenue avec le modèle et le profil SMTP que vous avez choisis.
Le plugin envoie les leads directement à votre propre installation MarbleSend. Un service comme Zapier ou Make ne fait pas partie du trajet.
Avec le double opt-in activé, les nouveaux contacts sont enregistrés comme pending avec consent_source = 'api'. MarbleSend envoie par email un lien de confirmation ({{confirm_link}}). Quand le contact clique dessus, le statut passe à active et l'heure ainsi que l'adresse IP sont consignées pour le RGPD.
{
"email": "lead@agency.com",
"name": "Jane Smith",
"tags": ["source:wpforms", "ebook-download", "vip-inbound"],
"consent_source": "api"
}
8.10 Dépannage
Problèmes courants lors de la connexion de formulaires WordPress, avec la cause, la façon de vérifier et la solution.
Pourquoi les envois arrivent-ils en retard, ou pas du tout, dans MarbleSend ?
WP-Cron ne s'exécute que lorsque quelqu'un visite le site. Sur un site peu fréquenté ou de préproduction, les envois en file attendent la visite suivante. Un envoi en file est conservé une heure. Si WP-Cron ne s'exécute pas dans ce délai, l'envoi est perdu et marblesend_forms_log note qu'un envoi a expiré (il ne peut pas nommer le visiteur, car les données stockées ont aussi expiré).
Ouvrez Settings → MarbleSend Forms dans wp-admin. Le compteur d'éléments en attente indique ceux qui attendent marblesend_forms_process_queue. Une entrée du journal disant qu'un envoi en file a expiré signifie que WP-Cron ne s'est pas exécuté pendant plus d'une heure.
Ouvrez https://your-site.com/wp-cron.php?doing_wp_cron pour l'exécuter une fois, ou configurez une vraie tâche cron sur le serveur (* * * * * wget -q -O - https://your-site.com/wp-cron.php >/dev/null 2>&1).
Pourquoi le journal indique-t-il « Skipped: no valid email in form submission » ?
Le champ email de l'association contient une faute de frappe, ou le visiteur a envoyé une adresse vide ou invalide que sanitize_email() a rejetée.
MarbleSend_Integration_Base::log_skip() écrit une entrée dans marblesend_forms_log chaque fois qu'un formulaire activé ne produit aucun email valide.
Vérifiez l'identifiant qu'utilise votre constructeur de formulaires : un numéro pour WPForms (par exemple 2) et Formidable Forms, le nom du tag pour Contact Form 7 (your-email), le Name Attribute pour Fluent Forms (email) et l'element ID pour Forminator (email-1).
Pourquoi WordPress signale-t-il une API key invalide ou un scope manquant ?
La key utilisée dans WordPress a été révoquée, a expiré, a été supprimée dans MarbleSend, ou a été créée sans le scope contacts:write.
Test Connection appelle GET /api/verify-key. Une réponse HTTP 401 ou 403 signifie que l'authentification a échoué.
Dans MarbleSend, ouvrez Settings → API et Webhooks et créez une nouvelle key avec le scope contacts:write (ou admin). Copiez le token qui commence par ms_ dans Settings → MarbleSend Forms côté WordPress.
Pourquoi des leads Contact Form 7 disparaissent-ils quand le formulaire affiche une erreur ?
Le plugin ne transmet un lead qu'après l'envoi de l'email propre à Contact Form 7. Quand l'email échoue, CF7 affiche son message d'erreur et le lead n'est pas transmis.
Envoyez le formulaire vous-même. Si vous voyez « There was an error trying to send your message », CF7 n'a pas pu envoyer son email.
Réparez l'envoi d'emails de votre site WordPress, par exemple avec un plugin SMTP. Dès que CF7 peut envoyer son email, le lead arrive dans MarbleSend.
Pourquoi un contact porte-t-il son adresse email comme nom ?
Le formulaire n'a pas de champ nom, ou aucun champ nom n'est associé. L'API de MarbleSend exige un nom : un nouveau contact reçoit donc la partie de l'email avant le @.
Regardez la ligne du formulaire dans Settings → MarbleSend Integrations : la case Name Field est vide. Un contact qui existait déjà n'est pas touché, car il garde son nom.
Ajoutez un champ nom au formulaire et saisissez-le dans l'association. Les contacts déjà créés gardent leur nom actuel ; modifiez-le dans /contacts si nécessaire.