amsom-habitat/mailer-sender

Utilities pour les envoies de mails depuis MailerInterface

Maintainers

Package info

gitlab.com/amsom-package/mailersender

Issues

pkg:composer/amsom-habitat/mailer-sender

Transparency log

Statistics

Installs: 13 081

Dependents: 0

Suggesters: 0

Stars: 0

v3.2.1 2026-07-16 08:52 UTC

This package is auto-updated.

Last update: 2026-07-16 06:54:14 UTC


README

Connecteur PHP pour envoyer des mails via l'API mailing d'AMSOM Habitat. Le connecteur ne fabrique pas les emails : il transmet une description à l'API, qui se charge du rendu (templates MJML/EJS), de l'envoi SMTP, des tentatives de renvoi, du log et de la redirection prod/test.

Comment ça marche

Ton code PHP ──send([...])──▶ mailer-sender ──POST /v2/send (JSON + clé API)──▶ API mailing ──▶ SMTP
  • Tu décris l'email avec un tableau associatif ; le connecteur le poste en JSON sur POST <API_MAIL_URL>/v2/send, avec la clé API dans l'en-tête X-API-Key.
  • L'API valide, rend le template, envoie, journalise (consultable sur son interface /emails) et renvoie un identifiant de suivi.
  • La logique prod/test (rediriger les mails vers une boite de dev hors prod) est gérée par l'API, plus par le connecteur.

Prérequis

  • PHP ≥ 8.1
  • Une API mailing en v4+ joignable (elle expose la route /v2/send).
  • Une clé API valide (fournie par l'équipe qui opère l'API mailing).

Installation

composer require amsom-habitat/mailer-sender

Le service est autowiré par Symfony — injecte simplement AmsomUtilities\MailerSender dans ton contrôleur/service.

Configuration

Deux variables d'environnement suffisent :

API_MAIL_URL=http://api_mailing   # base de l'API mailing (sans /v2)
API_MAIL_KEY=ma_cle_api           # clé API — doit correspondre à une entrée
                                  # de API_KEYS côté API mailing (ex. "metier:ma_cle_api")

Alternative : passer l'URL et la clé au constructeur (prioritaires sur l'env), utile pour les tests :

$mailer = new MailerSender($symfonyMailer, apiUrl: 'http://api_mailing', apiKey: 'ma_cle_api');

Utilisation — send()

Une seule méthode, un tableau. Ajouter une option = ajouter une clé (aucun changement de signature).

use AmsomUtilities\MailerSender;

// $mailer est injecté par Symfony (autowiring)
$res = $mailer->send([
    // 'template' omis → 'default' (le template HTML tout-configurable)
    'to'      => 'locataire@example.com',
    'subject' => 'Information',
    'body'    => ['message' => 'Bonjour, votre demande a été prise en compte.'],
]);

if ($res['success']) {
    $idSuivi = $res['id'];   // hash visible sur l'interface /emails de l'API
} else {
    // $res['httpStatus'], $res['error']
}

Champs disponibles

💡 Découverte : le tableau $mail est décrit en array{...} dans le docblock de send()PhpStorm autocomplète les clés (y compris options et delivery). Liste à l'exécution :

dump(\AmsomUtilities\MailerSender::champsDisponibles()); // clé => description, à date
CléTypeDescription
templatestringDéfaut default (template tout-configurable : message, message+bouton, texte brut, config libre). Sinon un template spécifique (enquete, edl, prestataire…)
tostring | string[]Requis. Destinataire : un email, ou un tableau d'emails
subjectstringRequis. Objet du mail
bodyarrayDonnées injectées dans le template
textstringContenu texte brut (uniquement pour template: 'texte_brut')
fromstringExpéditeur réel. Si fourni, l'envoi passe par le relay interne
replyTostringAdresse de réponse (en-tête Reply-To), distincte de l'expéditeur
cc / ccistring[]Copies / copies cachées
destinatairestringNom affiché du destinataire (utilisé par certains en-têtes de template)
attachmentsarray[]Pièces jointes (voir plus bas)
optionsarrayConfig de template libre (voir plus bas)
deliveryarrayAcheminement (voir plus bas)

options — configuration de template

Toutes optionnelles. Interprétées par le template ; ajouter une nouvelle option ne casse rien.

CléTypeDescription
logostringlogoEspaceClient | logoSyneo | logoNexio
bonjourboolAffiche « Bonjour … »
signaturearrayBloc signature (nom, prenom, fonction, tel, mobile) ; remplace le footer réseaux sociaux
auteurstringAuteur en bas de page
remerciementstringMessage de remerciement
showRemerciementboolAffiche le remerciement
showFooterboolAffiche le footer (mode custom)
footerMiddlePartstringContenu médian du footer
headerTemplateName / bodyTemplateName / footerTemplateNamestringTemplates à utiliser (mode custom)

delivery — acheminement

CléTypeDéfautDescription
mode'sync' | 'async'syncsync = attend l'envoi réel, success reflète le résultat. async = réponse immédiate (202), envoi + retries en tâche de fond côté API
retriesint7Nombre de tentatives de renvoi
delayMsint1000Délai initial entre tentatives (× 3 à chaque échec)
timeToKeepint30Jours de conservation du log (-1 = illimité)
testModestring""En prod, redirige vers la boite de dev et préfixe le sujet

Par défaut l'envoi est synchrone : send() attend le résultat et success est fiable. Passe delivery.mode = 'async' seulement si tu veux du « fire-and-forget » (utile pour des envois en masse), en sachant que success ne reflétera alors que l'acceptation, pas la réussite d'envoi.

Pièces jointes

'attachments' => [
    // contenu déjà en base64
    ['filename' => 'facture.pdf', 'content' => $base64],
    // OU un fichier / une URL — le connecteur le convertit en base64 (l'API ne fait aucun fetch)
    ['filename' => 'photo.jpg', 'content' => '/tmp/photo.jpg', 'type' => 'path'],
    ['filename' => 'image',     'content' => 'https://…',      'type' => 'url'],
]

Valeur de retour

send() renvoie un tableau :

CléTypeDescription
successbooltrue si HTTP 200 (sync) ou 202 (async)
httpStatusintCode HTTP renvoyé par l'API
idstringHash de suivi (identifie le mail dans /emails ou /emails/failed)
statusstringsent / queued / rejected / failed
errorstringPrésent en cas d'échec

Lève \RuntimeException si la config manque (API_MAIL_URL / API_MAIL_KEY) ou si l'appel réseau échoue (aucune réponse). Une réponse HTTP d'erreur (4xx/5xx), elle, revient dans success = false sans exception.

Exemples

Message avec bouton, expéditeur, réponse et pièce jointe (template default) :

$mailer->send([
    // template omis → 'default'
    'to'          => 'locataire@example.com',
    'subject'     => 'Votre dossier',
    'from'        => 'service-client@amsom-habitat.fr',
    'replyTo'     => 'contact@amsom-habitat.fr',
    'body'        => [
        'message' => 'Veuillez trouver le document ci-joint.',
        'btnUrl'  => 'https://espace.amsom-habitat.fr',
        'btnText' => 'Accéder à mon espace',
    ],
    'options'     => ['logo' => 'logoSyneo', 'signature' => ['nom' => 'Martin', 'prenom' => 'Claire']],
    'attachments' => [['filename' => 'dossier.pdf', 'content' => '/tmp/dossier.pdf', 'type' => 'path']],
]);

Multi-destinataires + copie :

$mailer->send([
    'to'      => ['a@ista.com', 'b@ista.com'],
    'cc'      => ['superviseur@amsom-habitat.fr'],
    'subject' => "Demande d'intervention",
    'body'    => ['message' => '…'],
    'options' => ['logo' => 'logoSyneo'],
]);

Asynchrone (fire-and-forget) :

$mailer->send([
    'to'       => 'locataire@example.com',
    'subject'  => 'Newsletter',
    'body'     => ['message' => '…'],
    'delivery' => ['mode' => 'async'],   // → 202, envoi en tâche de fond
]);

Templates disponibles

  • default (défaut) — template HTML tout-configurable : message, message + bouton (btnUrl/btnText), et config via options. À utiliser pour tout mail générique.
  • texte_brut — texte brut (champ text, sans HTML).
  • templates spécifiques (enquete, prestataire, edl, invit_hesta…) — définis et documentés côté API mailing (voir son README / V2.md), avec leurs champs body.

Anciennes méthodes (dépréciées)

sendMail(), apiSendMail() et apiSendMailCustom() restent disponibles à l'identique pour compatibilité (elles tapent les anciennes routes non authentifiées), mais ne sont plus recommandées : préférez send().

Dépannage

SymptômeCause probable
RuntimeException: API_MAIL_URL et API_MAIL_KEY doivent être configurésVariables d'env manquantes
RuntimeException: Appel à l'API mailing échoué : …API injoignable (réseau/DNS/URL)
success = false, httpStatus = 401Clé API invalide / absente de API_KEYS côté API
success = false, httpStatus = 404L'API cible n'est pas en v4 (route /v2/send absente)
success = false, httpStatus = 422Payload invalide (email mal formé, champ requis manquant, template inconnu)