Guide technique officiel Architecture PHP 8.2+ Zero-Build Optimisé pour l'hébergement mutualisé

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.

Filter:
Base

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.

100% PDO préparé

Zéro injection SQL

Chaque requête de base de données utilise des requêtes préparées strictes sans surcharge d'ORM.

AES-256-GCM

Chiffrement au repos

Identifiants SMTP, clés API d'IA et secrets webhook chiffrés dans Crypto.php.

File d'attente atomique

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.

UI Zero-Build

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.

IMMUNITY

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.

PERFORMANCE

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.

IDEMPOTENCY

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.

SINGLE-TENANT

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.

AES-256-GCM

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.

RANDOM_BYTES()

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.

SECRETS CATALOG

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.

MASTER KEY ISOLATION

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.

UNIFIED RUNNER

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.

CLI & WEB-CRON

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.

ATOMIC CLAIM

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 RECOVERY

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.

Module 01

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-plan
Carte KPI 1

Total envoyés

Agrégation des logs & compteur mensuel
Carte KPI 2

Ouverts / Taux d'ouverture

Pixel de suivi 1x1 & note Apple MPP
Carte KPI 3

Cliqués / CTR

Injecteur de redirection de clics
KPI 04

Audience désinscrite

Taux de désinscription & conformité RFC
Carte d'opération 4

Battement de cœur du worker

Statut du cron & intervalle de 1 min
Visualiseur

Graphique de croissance du volume

Échelle 7j, 30j, 90j, YTD
Flux d'activité

Tableau des diffusions récentes

Cycle de vie des statuts & piste d'audit
Bannière de sécurité

Santé de la délivrabilité

Disponibilité du profil SMTP

Impact sur la base de données :

Astuce de pro pour l'équipe support :

1.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.

Périodes sélectionnables (7j, 30j, 90j, YTD)

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).

Barres flexibles légères sans dépendances

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.

Télémétrie double métrique dans l'infobulle

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.

Completed

status = 'completed'

Sending

status = 'sending'

Failed

status = 'failed'

Draft

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é.

Nom & origine de la Campaign

Affiche l'objet de la Campaign, la date de création et le tag d'origine (manual, recurring, rss ou resend_unopened).

Destinataires & ratio de livraison

Compte instantané des messages délivrés par rapport aux échecs, ainsi que les pourcentages en direct du taux d'ouverture et de clics.

Lien du rapport analytique

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.5 Bannière d'avertissement de santé de la délivrabilité

Lorsque votre domaine d'expédition ne dispose pas de records SPF, DKIM ou DMARC vérifiés, MarbleSend met en évidence une bannière d'avertissement directement au-dessus des métriques KPI. Cliquer sur Vérifier le DNS du domaine ouvre l'assistant de diagnostic en 4 étapes sous /settings?tab=deliverability, empêchant les utilisateurs d'endommager la réputation de leur domaine avec des boîtes non authentifiées.

Vérification des profils SMTP actifs

Affiche le nombre de relais SMTP configurés dans Settings. MarbleSend prend en charge la rotation multi-SMTP pour une distribution équilibrée de la charge.

Avertissement de relais manquant & Protection Preflight

Si aucun profil SMTP actif n'est détecté, un avertissement rouge s'affiche avant le lancement des Campaigns pour prévenir toute interruption d'envoi.

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.

Module 02

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érationnels
PROGRESS

Moniteur d'Envoi Live

Statistiques et événements en temps réel
AUDIENCE

Sélecteur de Destinataires

Filtrage par tag et sélection globale
COMPOSER

Éditeur Triple Vue

Code, split et aperçu
SAFETY

Moteur de Vérification Preflight

Inspection automatique en 6 points
TESTING

Diagnostic d'Envoi Test

Échantillon direct sans file
ATTRIBUTION

Réécriveur UTM et Liens

Paramètres UTM et suivi 302
PORTFOLIO

Historique des Diffusions

Filtres de status et d'origine
ANALYTICS

Rapport Détaillé Post-Envoi

CTR, MPP et réexpédition auto

Impact sur la base de données :

Astuce de pro pour l'équipe support :

2.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

Sending

74% 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
ana.wijaya@example.com Delivered
budi.santoso@example.org Delivered
chen.li@example.net 550 5.1.1 User unknown
dewi.lestari@example.com Delivered
eko.prasetyo@example.org Envoi en cours
View Full Report

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.

TELEMETRY NOTE

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.

PIPELINE 01

É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.

PIPELINE 02

É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.

PIPELINE 03

É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 :

KPI METRICS

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.

TEMPORAL CLUSTERS

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.

ENGAGEMENT RECOVERY

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.

Module 03

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érationnels
CYCLE DE VIE

Machine à 4 États

active/pending/unsub/supp
FILTRAGE

Moteur de Recherche et Filtres

Tags, statut et debounce
TÉLÉMÉTRIE

Volet d'Audit et Consentement

IP, horodatages et rebonds
INGESTION

Importateur CSV RFC 4180

50k lignes et déduplication
TUNNELS

Pages de Capture Hébergées

Double opt-in et entonnoirs
AUTOMATISATION

Autoresponders par Tag

Règles de goutte-à-goutte par événement
GESTION

Hub de Gestion en Masse

Segmentation multi-pages
CONFORMITÉ

Confidentialité RGPD et Purge

Export JSON et suppression totale

Impact sur la base de données :

Astuce de pro pour l'équipe support :

3.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'.

active

Abonné actif

Opt-in confirmé, e-mail valide. Éligible pour recevoir des Campaigns, des Schedules et des autorépondeurs.

pending

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.

unsubscribed

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.

suppressed

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.

Édition directe

Mettre à jour le nom, les métadonnées personnalisées et les badges de tags en ligne sans rechargement.

Blocage manuel

Bloquer instantanément un contact pour le disqualifier immédiatement de toutes les files d'attente.

Suppression définitive RGPD

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.

Vues Totales des Pages

Surveille le cumul des impressions sur l'ensemble des entonnoirs d'inscription actifs.

Taux de Conversion Moyen

Calcule le ratio soumissions/vues sur l'ensemble des formulaires de capture hébergés.

Pages Actives / Capacité

Indique le nombre de pages d'atterrissage actives par rapport à la capacité maximale de 20 pages.

Inscriptions sur 30 Jours

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.

Moteur de double opt-in

Génère des tokens de confirmation signés par HMAC avec envoi automatique d'un e-mail de confirmation.

Attribution automatique de tags

Attribue des tags désignés dès l'inscription pour déclencher des séquences automatisées ciblées.

Redirection personnalisée

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.

Module 04

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érationnels
SIDEBAR

Bibliothèque de Templates

Recherche instantanée & clés de slug
PRESETS

Dispositions Starter

8 mises en page d'emails basées sur tableaux
ÉDITEUR

Éditeur de Code Brut

Indentation Tab & formateur
APERÇU

Viewport Isolé

Cadre bureau & mobile
TOKENS

Palette de Tokens Dynamiques

Injection de placeholders en 1 clic
DIAGNOSTIC

Expéditeur d'Email de Test

Modal de vérification SMTP en direct
AI COPY

Volet AI Copywriter

Générer & affiner les templates
AUDIT AI

Réviseur d'Objets

Score 1–100 & audit anti-spam
ARTICLES

Articles d'actualité

Articles Markdown pour newsletters

Impact sur la base de données :

Astuce de pro pour l'équipe support :

4.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 :

1. Vierge minimal

Canevas épuré avec pied de page de désinscription obligatoire.

2. Lancement de produit

Bannière principale, proposition de valeur, appel à l'action percutant.

3. Newsletter mensuelle

Éditorial soigné, mise en avant d'articles sur 2 colonnes.

4. Newsletter d'articles d'actualité

Bandeau d'en-tête et bloc {{news_posts}} pour les planifications d'articles d'actualité.

5. Série de bienvenue

Intégration personnalisée, guide de démarrage en 3 étapes.

6. Invitation à un webinaire

Badge date/heure, biographie de l'intervenant, bouton RSVP.

7. Condensé de blog

Articles numérotés, temps de lecture, tags d'auteurs.

8. Offre de reconquête

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é.

{{name}}

Nom complet du destinataire (utilise "there" si non renseigné)

{{email}}

Adresse email du destinataire

{{unsubscribe_link}}

Lien de désinscription obligatoire en 1 clic conforme au RFC 8058

{{confirm_link}}

URL de confirmation double opt-in pour les pages d'inscription

{{posts}}

Boucle d'articles de blog syndiqués pour les newsletters RSS automatisées

{{feed_title}}

Titre du flux de contenu RSS/Atom connecté

{{latest_post_title}}

Titre de l'article de blog le plus récemment publié

{{posts_count}}

Nombre de nouveaux articles du flux inclus dans l'envoi

{{news_posts}}

Bloc d'articles d'actualité pour une planification de Newsletter (couverture, titre, sous-titre, corps)

{{news_posts_count}}

Nombre d'articles d'actualité inclus dans cet envoi

{{news_latest_post_title}}

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 :

6.7 Moteur IA bi-mode: Fournisseurs BYOK & Crédits IA MarbleSend

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émentCe qu'il fait
BibliothèqueListe 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, couvertureLe 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 statutLes 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 MarkdownLes 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 directAffiche 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 marqueurUn 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.

SyntaxRé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
> quoteCitation en bloc
---Ligne de séparation
![alt](https://example.com/a.png)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}}.

MarqueurDevient
{{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 articleLe 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 pasL'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.
Module 05

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

Interactive Inspector
CALENDRIER

Calendrier & Matrice mensuelle

Carte visuelle des plannings & cadences
CADENCE

Moteur de récurrence

Quotidien, hebdomadaire, mensuel & personnalisé
RSS / ATOM

Poller de blog automatisé

Déduplication de hachage & cache
AUDIENCE

Audience dynamique

Requête de tags à la seconde exacte de l'exécution
AUDIT

Logs d'occurrences

Audit d'exécution & prévention des doublons
EXÉCUTION

Exécution immédiate Run Now

Envoi instantané sans décaler la cadence
OPTIMISATION

Optimisation hébergement

8 directives opérationnelles sélectionnées
WORKER

Heartbeat Cron & Verrou

Garde de concurrence non bloquante
ARTICLES

Mode Articles d'actualité

Newsletters façon Substack

Impact sur la base de données :

Astuce de pro pour l'équipe support :

5.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é :

1. Fenêtres optimales d'envoi matinal

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.

2. Précision du worker cron à 1 minute

Exécutez worker.php chaque minute (* * * * *) avec protection flock pour garantir une précision sous la minute sans collision de processus.

3. Réservations atomiques de lots de file

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.

4. Segmentation des abonnés par tag de fuseau horaire

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.

5. Délai de temporisation de publication RSS

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.

6. Purge régulière de l'historique des occurrences

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é.

7. Stratégie de réexpédition aux non-ouverts après 48h

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.

8. Isolation dédiée du routage des profils SMTP

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

  1. 1Ouvrez Modèles → Articles et rédigez votre article en Markdown.
  2. 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à).
  3. 3Ouvrez Planifications → Nouvelle, gardez le type Newsletter et réglez Source du contenu sur « Articles d'actualité ».
  4. 4Choisissez le modèle, l'audience, le profil SMTP, le nombre d'articles par e-mail (1–20) et la cadence.
  5. 5Enregistrez. Seuls les articles qui deviennent Prêts après ce moment peuvent être envoyés par cette planification.
  6. 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.

Exemple : vous enregistrez la planification lundi. Un article devenu Prêt vendredi est ignoré ; un article qui devient Prêt mardi est envoyé à la prochaine occurrence, puis jamais plus par cette planification.

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é unL'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 articleCopiez son texte dans un nouvel article et marquez celui-ci Prêt — une planification n'envoie jamais deux fois le même article.
Module 06

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

Interactive Inspector
SMTP

Profils SMTP

BYO SMTP & Relais SES Géré
WORKER

Worker & Cron

Cadence d'exécution de 1 minute
LOCALES

23 Langues & Thème

Miroir RTL et Mode Sombre/Clair
API KEYS

Clés REST API

Accès développeur avec portée
WEBHOOKS

Webhooks d'Événements

Push d'événements HMAC-SHA256
DELIVERABILITY

Suite de Délivrabilité

SPF, DKIM, DMARC et BIMI
AI BYOK

Fournisseurs d'AI

BYOK & Crédits MarbleSend
LICENSE

Licence Ed25519

Token d'octroi cryptographique

Impact sur la base de données :

Astuce de pro pour l'équipe support :

6.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.

Option 1: BYO SMTP (Infrastructure de relais personnalisée)

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 SMTP

Connectez 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.

Avis Important de Transparence : Limites d'Envoi de l'Hébergement Mutualisé

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.

Host: smtp.hostinger.com | Port 465 (SSL) / 587 (TLS)
Business Email Plans (Per Mailbox)
Free Business Email Rp0 / mo

1 GB storage, 1 forwarding rule, 1 alias, up to 100 mailboxes/domain. Standard webmail & antispam. Strict sending cap (~100-200/day).

Starter Business Email Rp7.900 / mo

5 GB storage, 5 forwarding rules, 5 aliases, expandable mailbox storage. No mailbox limit per domain.

Standard Business Email Rp10.900 / mo

20 GB storage, 20 forwarding rules, 10 aliases, AI Kodee mailbox assistant & smart replies.

Premium Business Email Rp19.900 / mo

50 GB storage, 50 forwarding rules, 30 aliases, full AI suite & priority deliverability.

Hostinger Reach (Email Marketing)
Starter Marketing Rp23.900 / mo

100 recipients, 200 emails / month. Suitable for basic transactional testing.

Grow Marketing Rp36.900 / mo

500 recipients, 500 emails / month, 10 AI credits, remove Reach branding, automations.

Pro Marketing Rp54.900 / mo

1,000 recipients, 7,000 emails / month, 20 AI credits, custom HTML code, send-time optimization.

Namecheap Jellyfish / cPanel

• 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).

View Namecheap Email
Bluehost cPanel / M365

• 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).

View Bluehost Email
SiteGround Site Tools

• 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).

View SiteGround Email
DreamHost Custom Panel

• 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).

View DreamHost Email
HostGator cPanel

• 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).

View HostGator Email
GoDaddy Microsoft 365

• 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).

View GoDaddy Email

Sélectionnez le port et le protocole de sécurité adaptés à votre réseau.

Port 587 (STARTTLS) STANDARD

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.

Port 465 (SSL / SMTPS) ENCRYPTED

Implicit TLS/SSL wrapper connection (RFC 8314). Required by Hostinger, Namecheap cPanel, and selected enterprise relays. Highly reliable when hosting firewalls restrict 587.

Port 25 (Plain / MTA) BLOCKED

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 SES

Infrastructure 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.

Option 2: MarbleSend SMTP via Amazon SES (Relais Géré)

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.

Grand livre de crédits atomique, idempotence & remboursement automatique

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.

Diagnostics de socket TLS en direct & journalisation détaillée
Easy DKIM

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.

Routage par campagne & repli par défaut fluide

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).

Vérification du domaine expéditeur (SPF, DKIM, DMARC)

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.

Identité de l’expéditeur

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é.

Désinscription dans chaque e-mail

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é.

Listes basées sur le consentement

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.

Rebonds et plaintes

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.

Limites et pause automatique

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.

Envoi authentifié

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.

Guide Easy DKIM par hébergeur

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)
RULE 1
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".

RULE 2
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.

RULE 3
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.

Commandes de diagnostic DNS (CLI)
# 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
Hostinger hPanel → Domaines → Sélectionner le domaine → DNS / Serveurs de noms
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)
1

Connectez-vous à votre tableau de bord hPanel Hostinger et accédez à Domaines.

2

Sélectionnez votre domaine et cliquez sur DNS / Serveurs de noms dans la barre latérale.

3

Dans Gérer les enregistrements DNS, sélectionnez CNAME dans le menu déroulant Type.

4

Dans le champ Nom, entrez UNIQUEMENT token._domainkey (hPanel ajoute automatiquement .votredomaine.fr).

5

Dans le champ Cible, entrez token.dkim.amazonses.com et laissez le TTL sur 300 ou 14400.

6

Cliquez sur Ajouter un enregistrement. Répétez pour les 3 jetons générés dans MarbleSend.

hPanel Hostinger affiche votre nom de domaine grisé à côté du champ de saisie. Ne rajoutez pas votre nom de domaine ni de point final dans le champ Nom.
DreamHost (Panneau Web DreamHost)
DreamHost Web Panel
Panneau DreamHost → Sites web → Gérer les sites web → Paramètres DNS (ou Domaines → Gérer les domaines → DNS)
Type d'enregistrement Hôte / Nom Valeur / Cible / Pointe vers TTL
CNAME <token>._domainkey (DreamHost appends .yourdomain.com) <token>.dkim.amazonses.com Default
1

Connectez-vous au panneau Web DreamHost et accédez à Sites web > Gérer les sites web.

2

Localisez votre domaine et cliquez sur Paramètres DNS (ou Domaines > Gérer les domaines > DNS).

3

Faites défiler jusqu'à la section "Ajouter un enregistrement DNS personnalisé" et cliquez sur Ajouter.

4

Dans le champ Nom, saisissez token._domainkey (DreamHost complète .votredomaine.fr automatiquement).

5

Sélectionnez le Type CNAME et saisissez token.dkim.amazonses.com dans le champ Valeur.

6

Cliquez sur Enregistrer / Ajouter. Répétez l'opération pour les 3 jetons.

Les modifications DNS sur DreamHost peuvent prendre 1 à 2 heures pour se propager complètement sur l'ensemble de leurs serveurs.
Namecheap (DNS Avancé)
Advanced DNS
Tableau de bord Namecheap → Domain List → Manage → Onglet 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)
1

Connectez-vous à Namecheap, ouvrez la Domain List et cliquez sur Manage à côté de votre domaine.

2

Basculez sur l'onglet Advanced DNS en haut de la page.

3

Dans la section Host Records, cliquez sur le bouton rouge ADD NEW RECORD.

4

Sélectionnez CNAME Record dans le menu déroulant Type.

5

Dans le champ Host, entrez SEULEMENT token._domainkey (n'incluez jamais votre nom de domaine).

6

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.

Si votre domaine utilise des serveurs de noms externes (Custom DNS), cet onglet sera désactivé ; ajoutez les enregistrements chez votre hébergeur DNS actif.
Bluehost (Gestionnaire de compte / Zone Editor)
Bluehost DNS
Portail Bluehost → Domaines → DNS (ou cPanel → Zone Editor)
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)
1

Connectez-vous à Bluehost, cliquez sur Domaines et choisissez votre nom de domaine.

2

Accédez à l'onglet DNS (ou ouvrez cPanel Zone Editor en hébergement cPanel classique).

3

Faites défiler jusqu'à la section CNAME (Alias) et cliquez sur Add Record.

4

Dans le champ Host Record, saisissez token._domainkey.

5

Dans Points To, collez token.dkim.amazonses.com et sélectionnez le TTL (4 Hours ou Default).

6

Cliquez sur Save. Répétez pour les 2 autres jetons CNAME.

Bluehost gère le suffixe de domaine en arrière-plan. Ne saisissez jamais le nom de domaine complet dans la case Host Record.
SiteGround (Éditeur de zone DNS Site Tools)
Site Tools DNS
Espace client SiteGround → Sites web → Site Tools → Domaine → Éditeur de zone 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)
1

Connectez-vous à SiteGround, allez dans Sites web et ouvrez Site Tools pour votre domaine.

2

Dans le menu latéral, développez Domaine et cliquez sur Éditeur de zone DNS.

3

Sélectionnez l'onglet CNAME sous Créer un nouvel enregistrement.

4

Dans le champ Nom, tapez token._domainkey (Site Tools verrouille .votredomaine.fr à droite).

5

Dans Pointe vers, collez token.dkim.amazonses.com et laissez le TTL sur 1 heure (3600).

6

Cliquez sur Créer. Répétez l'opération pour les 3 jetons.

Les serveurs de noms SiteGround propagent les changements en quelques secondes. Vérifiez l'absence d'anciens enregistrements TXT conflictuels sur le même sélecteur.
HostGator (cPanel Zone Editor)
cPanel Zone Editor
Portail HostGator → cPanel → Domaines → 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)
1

Connectez-vous au portail HostGator et ouvrez cPanel.

2

Dans la section Domaines, cliquez sur Zone Editor.

3

Trouvez votre domaine et cliquez sur + CNAME Record (ou Gérer > Ajouter un enregistrement).

4

Dans Nom, saisissez token._domainkey (cPanel ajoute automatiquement votre domaine et un point).

5

Dans CNAME / Record, saisissez token.dkim.amazonses.com.

6

Cliquez sur Ajouter un enregistrement CNAME. Répétez pour les 3 jetons.

Dans cPanel Zone Editor, vérifiez que le nom de l'enregistrement dans la liste est token._domainkey.votredomaine.fr. sans répétition.
GoDaddy (Portefeuille de domaines DNS)
GoDaddy DNS
Compte GoDaddy → Mes produits → Domaines → DNS (ou Gérer les 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)
1

Connectez-vous à votre compte GoDaddy et ouvrez Mes produits.

2

Sous Domaines, repérez votre domaine et cliquez sur DNS (ou les trois points > Gérer les DNS).

3

Dans la section Enregistrements DNS, cliquez sur Ajouter un nouvel enregistrement.

4

Sélectionnez CNAME dans le menu déroulant Type.

5

Dans le champ Nom, écrivez UNIQUEMENT token._domainkey (ne saisissez pas .votredomaine.fr !).

6

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.

GoDaddy ajoute votre nom de domaine automatiquement. Entrer le domaine complet provoquera une erreur de syntaxe ou créera un enregistrement en double invalide.
Vérification et propagation DNS

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.

Étape 1 : copiez votre ligne cron

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.

Étape 2 : ajoutez-la dans votre panneau d'hébergement

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)
  1. Ouvrez hPanel → Websites → Dashboard pour votre site, puis cliquez sur Cron Jobs dans la barre latérale.
  2. Réglez Type sur Custom. (Le type PHP n'accepte que le chemin d'un file .php ; votre ligne contient aussi la commande PHP.)
  3. Collez la ligne de l'étape 1 dans Command to run.
  4. Réglez la planification sur chaque minute, ou saisissez * * * * *.
  5. 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.

  1. Ouvrez cPanel et, dans la section Advanced, cliquez sur Cron Jobs.
  2. Sous Add New Cron Job, choisissez Once Per Minute (* * * * *) dans Common Settings.
  3. Collez la ligne de l'étape 1 dans Command.
  4. 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
  1. Connectez-vous au Bluehost Portal, cliquez sur Websites, puis sur Manage Site pour votre site.
  2. Ouvrez l'onglet Advanced, repérez Cron Jobs et cliquez sur Manage, puis sur Add Cron.
  3. Choisissez une fréquence dans Common Settings (ou renseignez Minute, Hour, Day, Month et Weekday).
  4. 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.

  1. Ouvrez cPanel et, dans la section Advanced, cliquez sur Cron Jobs.
  2. Sous Add New Cron Job, choisissez Once Per Minute (* * * * *) dans Common Settings.
  3. Collez la ligne de l'étape 1 dans Command.
  4. 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.

  1. Ouvrez cPanel et, dans la section Advanced, cliquez sur Cron Jobs.
  2. Sous Add New Cron Job, choisissez Once Per Minute (* * * * *) dans Common Settings.
  3. Collez la ligne de l'étape 1 dans Command.
  4. 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
  1. Ouvrez le panneau DreamHost, allez dans Cron Jobs et cliquez sur Add New Cron Job.
  2. 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.
  3. 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).
  4. 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
  1. Ouvrez Site Tools → Devs → Cron Jobs.
  2. Choisissez l'intervalle dans la liste (ou réglez minute, heure, jour, mois et jour de la semaine).
  3. Collez la ligne de l'étape 1 dans Command. Une adresse e-mail pour la sortie est facultative.
  4. 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.

Pas d'accès à cron, ou votre hébergeur le limite ? Utilisez Web-Cron
  1. Ouvrez Settings → Système et copiez la Web-Cron URL. Gardez-la privée : elle contient votre jeton secret.
  2. Créez un compte gratuit sur un service cron comme cron-job.org.
  3. Créez une tâche, collez l'URL et réglez-la pour s'exécuter chaque minute. Enregistrez et activez-la.
  4. Utilisez Web-Cron ou une tâche cron de votre hébergeur, pas les deux : une seule suffit.
Étape 3 : vérifiez que cela fonctionne

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.

Affiche toujours Cron non détecté ?
  • 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é.

Crontab CLI Natif (Option A)
* * * * * 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.

Alternative Web-Cron HTTP (Option B)
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é.

Concurrency Guard flock Non Bloquant

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.

Revendications de File d'Attente Atomiques

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é.

23 Langues Natives Sans Dépendance

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.

Miroir de Disposition RTL Bidirectionnel

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.

Moteur de Thème Tri-State Persistant

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.

Sécurité Renforcée Administrateur Unique

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).

Comment ça marche

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.

Activation pas à pas

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.

Le code QR reste sur votre serveur

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.

Se connecter avec un code

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.

Codes de récupération

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.

Téléphone perdu et aucun code de récupération

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.

1 Créer un compte Cloudflare ou s’y connecter

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.

2 Ouvrir Turnstile et ajouter un widget

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.

3 Nommer le widget et lister vos noms d’hôte

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.

4 Choisir le mode du widget

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.

5 Copier les deux clés

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.

6 Les coller dans MarbleSend

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.

7 Tester

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é.

Quand Cloudflare est injoignable

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.

Clés de test pour le développement

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.

Dépannage

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.

Obligatoire tant que vous utilisez le SES Relay

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.

Génération de Tokens & Affichage Unique

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.

Stockage de Hash SHA-256 Unidirectionnel

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.

Portées de Capacité Granulaires

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.

Authentification Bearer & Journaux d'Audit

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.

Abonnements aux Événements du Cycle de Vie

Abonnez-vous aux déclencheurs essentiels : contact.created, contact.unsubscribed, campaign.sent, campaign.bounced et link.clicked avec activation individuelle par webhook.

En-tête de Signature HMAC-SHA256

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é.

Mécanisme de Circuit Breaker et Rejeu

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.

Historique d'Audit des Livraisons & Test Ping

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.

1. SPF (Sender Policy Framework)

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).

2. DKIM (DomainKeys Identified Mail)

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.

3. Stratégie & Alignement DMARC

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.

4. Avatar de Marque BIMI & VMC

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.

BYOK Mode 1: BYOK (Apportez votre propre clé)

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.

METERED Mode 2: Crédits IA MarbleSend (Modèles sélectionnés)

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.

DYNAMIC Dynamic Edge Pricing & Instant Checkout

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.

PRIVACY AES-256-GCM Key Vault & Strict Data Privacy

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.

MarbleSend AI (Relais géré)

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.

BYOK (Vos propres clés API)

Communication directe de serveur à fournisseur sans marge ajoutée. Choisissez un fournisseur configuré et un identifiant de modèle par défaut.

Pipeline de Génération Unifié

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é.

Persistance de l'État Système

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.

Allocation de Crédits de Démarrage Gratuits

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.

Grand Livre Atomique et Idempotence

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.

Tarification Dynamique en Périphérie et Recharge

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.

Solde en Temps Réel et Synchronisation en 1 Clic

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.

Registre Multi-Fournisseurs

Maintenez des liaisons simultanées vers OpenAI, Anthropic Claude, Google Gemini, DeepSeek, Kimi/Moonshot, OpenRouter ou instances privées Ollama.

Protocoles Doubles et URLs de Base Personnalisées

Prend en charge les points de terminaison compatibles OpenAI (/chat/completions) et le format messages d'Anthropic (/v1/messages) avec URLs proxy personnalisées.

Coffre Cryptographique AES-256-GCM

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.

Diagnostic Préliminaire en Direct

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 :

OpenAI GPT-4o / o-series
Format: openai
Base URL: https://api.openai.com/v1
Steps: Connectez-vous sur platform.openai.com → ouvrez Dashboard → choisissez "API keys" dans la barre latérale → cliquez sur "+ Create new secret key" → nommez-la "MarbleSend" → copiez la clé (débute par sk-...). Consultez platform.openai.com/docs/models pour les modèles récents.
Anthropic Claude Claude 3.5 / 3.7 Sonnet
Format: anthropic
Base URL: https://api.anthropic.com/v1
Steps: Connectez-vous sur console.anthropic.com → allez dans Settings → "API Keys" → cliquez sur "Create Key" → nommez-la "MarbleSend" → copiez la clé secrète (débute par sk-ant-...). Consultez docs.anthropic.com/en/docs/about-claude/models pour les IDs Claude.
Google Gemini Gemini 2.0 / 2.5 Flash
Format: gemini
Base URL: https://generativelanguage.googleapis.com/v1beta
Steps: Connectez-vous avec votre compte Google sur aistudio.google.com → cliquez sur "Get API key" → cliquez sur "Create API key" → copiez la clé (débute par AIzaSy...). Explorez ai.google.dev/gemini-api/docs/models/gemini pour les modèles Gemini.
DeepSeek DeepSeek-V3 / R1
Format: openai
Base URL: https://api.deepseek.com
Steps: Connectez-vous sur platform.deepseek.com → sélectionnez "API keys" dans le menu latéral → cliquez sur "Create API key" → saisissez "MarbleSend" → copiez la clé (débute par sk-...). Visitez api-docs.deepseek.com pour les modèles disponibles.
Kimi (Moonshot AI) Kimi k1.5 / Moonshot v1
Format: openai
Base URL: https://api.moonshot.cn/v1
Steps: Connectez-vous sur platform.moonshot.cn → ouvrez Console → sélectionnez "API Key Management" (API Key 管理) → cliquez sur "Create" (新建) → copiez le token secret. Visitez platform.moonshot.cn/docs pour les IDs Moonshot/Kimi.
OpenRouter Aggregator (200+ Models)
Format: openai
Base URL: https://openrouter.ai/api/v1
Steps: Connectez-vous sur openrouter.ai → allez dans Account → "Keys" → cliquez sur "Create Key" → définissez des limites optionnelles → copiez la clé (débute par sk-or-v1-...). Parcourez openrouter.ai/models pour accéder à plus de 100 modèles.
Ollama & Local / Groq Local LLM / Ultra-Fast LPU
Format: openai
Base URL: http://localhost:11434/v1 / https://api.groq.com/openai/v1
Steps:
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 :

1 1. Ouvrez Settings ➔ Onglet AI Providers

Dans le menu latéral, cliquez sur Settings puis ouvrez l'onglet "AI Providers" (accessible directement sur /settings).

2 2. Utilisez Quick Add ou "+ Add Provider"

Cliquez sur un bouton prédéfini Quick Add (OpenAI, DeepSeek, Gemini, Anthropic, etc.) pour un pré-remplissage immédiat ou sur "+ Add Provider".

3 3. Vérifiez le Format et la Base URL

Sélectionnez le format : "OpenAI format" ou "Anthropic format". Confirmez la Base URL correspondante.

4 4. Collez la Clé API en Toute Sécurité

Collez votre clé secrète. MarbleSend la stocke chiffrée en AES-256-GCM via Crypto.php sans aucune exposition en clair.

5 5. Renseignez l'ID du Modèle et Testez la Connexion

Saisissez l'ID de modèle et la limite de context window, puis cliquez sur "Test Connection" pour valider la communication en direct.

6 6. Définissez le Modèle Actif par Défaut

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.

Vérification de Signature Ed25519

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.

Liaison de Domaine & Niveau de Licence

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.

Résilience Hors Ligne de 7 Jours de Grâce

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.

Politique de Soft-Lock

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.

Vérification automatique des mises à jour

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 et e-mails de mise à jour

« 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.

Guide de réduction du support

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 ?

Cause racine :

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.

Diagnostic & mécanisme :

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.

Solution pratique & playbook :

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 ?

Cause racine :

Préchargement Apple Mail Privacy Protection (MPP), mise en cache proxy, blocage des images par le destinataire ou bloqueurs retirant les paramètres UTM.

Diagnostic & mécanisme :

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.

Solution pratique & playbook :

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 ?

Cause racine :

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.

Diagnostic & mécanisme :

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.

Solution pratique & playbook :

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 ?

Cause racine :

Balise obligatoire {{unsubscribe_link}} manquante, objet non valide, aucun destinataire actif sélectionné ou syntax de token non fermée.

Diagnostic & mécanisme :

Le moteur Preflight contrôle 6 vecteurs critiques de conformité et de deliverability avant d'autoriser la transition d'état vers queued ou sending.

Solution pratique & playbook :

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 ?

Cause racine :

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é.

Diagnostic & mécanisme :

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.

Solution pratique & playbook :

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 ?

Cause racine :

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.

Diagnostic & mécanisme :

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.

Solution pratique & playbook :

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) ?

Cause racine :

É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).

Diagnostic & mécanisme :

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.

Solution pratique & playbook :

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 ?

Cause racine :

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.

Diagnostic & mécanisme :

Word MSO ne respecte que les structures traditionnelles à base de tableaux (nested <table>, <tr>, <td>) avec largeurs explicites en pixels et styles inline.

Solution pratique & playbook :

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 ?

Cause racine :

La taille du code HTML brut de l'email excède la limite stricte de 102 Ko (104 448 octets) imposée par Gmail.

Diagnostic & mécanisme :

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.

Solution pratique & playbook :

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 ?

Cause racine :

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.

Diagnostic & mécanisme :

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.

Solution pratique & playbook :

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 ?

Cause racine :

L'URL du flux était inaccessible, la syntax XML était corrompue ou le GUID du dernier article correspondait à cm_schedules.last_rss_item_id.

Diagnostic & mécanisme :

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.

Solution pratique & playbook :

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 ?

Cause racine :

Plusieurs occurrences planifiées se sont accumulées pendant que le processus worker ne pouvait pas tourner.

Diagnostic & mécanisme :

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.

Solution pratique & playbook :

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 ?

Cause racine :

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.

Diagnostic & mécanisme :

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}}.

Solution pratique & playbook :

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 ?

Cause racine :

L'envoi est suivi par planification, pas par article.

Diagnostic & mécanisme :

Chaque planification d'articles d'actualité tient son propre registre des articles remis ; la bibliothèque affiche donc le total « Envoyé N× ».

Solution pratique & playbook :

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" ?

Cause racine :

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.

Diagnostic & mécanisme :

Settings → SMTP comprend un test de socket en direct qui affiche le dialogue brut entre PHPMailer et votre serveur SMTP.

Solution pratique & playbook :

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 ?

Cause racine :

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é.

Diagnostic & mécanisme :

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).

Solution pratique & playbook :

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 ?

Cause racine :

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.

Diagnostic & mécanisme :

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.

Solution pratique & playbook :

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 ?

Cause racine :

Coupures réseau, défaillances de résolution DNS ou maintenance temporaire sur le serveur de licences en amont.

Diagnostic & mécanisme :

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.

Solution pratique & playbook :

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.

Plugin WordPress et REST API

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.

Interactive Inspector
REST API

Pont REST API

Aucune base de données partagée
WP-CRON

File d'envoi

Stockage transient
NATIVE

MarbleSend Form

Shortcode, Block & Widget
WPFORMS

Hook WPForms

wpforms_process_complete
CF7

Hook Contact Form 7

wpcf7_mail_sent
FLUENT

Hook Fluent Forms

submission_inserted
FORMIDABLE

Formidable Forms

frm_after_create_entry
FORMINATOR

Hook Forminator

submit_before_set_fields
AUTOMATION

Autoresponders par tag

Tags et emails de bienvenue

Impact sur la base de données :

Astuce de pro pour l'équipe support :

PRÉREQUIS

Installez 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
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
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
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
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.

Sans le plugin, la page MarbleSend Integrations n'existe pas dans wp-admin, et vos formulaires WordPress ne peuvent pas envoyer leurs soumissions à MarbleSend.

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.

Aucune base de données partagée

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.

API key à portée limitée

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 de connexion

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.

Upsert et fusion des tags

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.

API Ingestion Endpoint (cURL Example)
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.

Rien de lent dans la requête du visiteur

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.

WP-Cron envoie la file

Un événement WP-Cron, marblesend_forms_process_queue, est planifié environ une minute plus tard et transmet les envois en file.

Une tentative par élément de la 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.

Les échecs sont consignés

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.

Transient Queue Enqueuing Snippet
// 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.

Shortcode, bloc ou widget

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"].

Protection contre les bots

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.

Envoyé dès que le visiteur valide

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é.

Noms, tags et confirmation

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.

Shortcode & Gutenberg Block Embed Syntax

[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.

Détection et hook

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.

ID de champ

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.

Configuration

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.

Tag d'origine

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.

WPForms Complete Hook Architecture
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.

Détection et hook

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.

Noms de tag

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.

Lecture de l'envoi

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.

Configuration

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.

Contact Form 7 Mail Sent Hook
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.

Détection et hook

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.

Name Attribute

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.

Liste des formulaires

La page Integrations liste vos formulaires en lisant la table de formulaires de Fluent Forms : inutile de chercher les ID de formulaire.

Configuration

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.

Fluent Forms Insertion Action
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.

Détection et hook

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.

Field 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.

Entrées enregistrées uniquement

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.

Configuration Étape par Étape

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.

Formidable Metas Extraction Hook
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.

Détection et hook

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.

Element ID

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.

Liste des formulaires

La page Integrations liste vos formulaires Forminator par nom, lus avec Forminator_API::get_forms().

Configuration

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.

Forminator Submission Pre-Field Hook
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.

Tags d'origine

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.

Email de bienvenue

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.

Aucun service d'automatisation entre les deux

Le plugin envoie les leads directement à votre propre installation MarbleSend. Un service comme Zapier ou Make ne fait pas partie du trajet.

Double opt-in et consent record

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.

Autoresponder Tag Structure (JSON Payload)
{
  "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 ?

Cause racine :

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é).

Diagnostic & mécanisme :

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.

Solution pratique & playbook :

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 » ?

Cause racine :

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.

Diagnostic & mécanisme :

MarbleSend_Integration_Base::log_skip() écrit une entrée dans marblesend_forms_log chaque fois qu'un formulaire activé ne produit aucun email valide.

Solution pratique & playbook :

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 ?

Cause racine :

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.

Diagnostic & mécanisme :

Test Connection appelle GET /api/verify-key. Une réponse HTTP 401 ou 403 signifie que l'authentification a échoué.

Solution pratique & playbook :

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 ?

Cause racine :

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.

Diagnostic & mécanisme :

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.

Solution pratique & playbook :

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 ?

Cause racine :

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 @.

Diagnostic & mécanisme :

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.

Solution pratique & playbook :

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.