Avec un modèle
Le plus propre : le contenu vit dans Lekalao, l’application n’envoie que les données. Créez un modèle nomméconfirmation-commande (Modèles transactionnels), puis :
Sans modèle
Envoyez le HTML tel quel :Les champs
Chaque adresse compte dans le quota du mois, copies comprises : un e-mail à une personne en
to et deux en cc compte pour trois. Un e-mail transactionnel s’écrit à quelqu’un, il ne se diffuse pas : plus de 50 adresses répondent 422 too_many_recipients.
En plusieurs langues
Un modèle peut avoir une version par langue (Langues).locale choisit :
Passez la langue de votre client telle que votre application la connaît : Lekalao se rabat tout seul.
La réponse
L’appel reçoit sa réponse dès que l’e-mail est écrit. Il part d’une file d’attente un instant plus tard.
Un refus est une erreur comme une autre —
message, code, doc_url — avec l’e-mail journalisé sous data quand il y en a un :
429 Too Many Requests
202 Accepted
201 et 202 de la même façon : Lekalao a l’e-mail. Gardez son id ; status dit s’il est déjà parti.
Les adresses de la liste de suppression sont retirées de to, cc et bcc sans erreur. L’e-mail part aux autres, et n’échoue que s’il ne reste aucun to.
Ensuite, dans la file
Lekalao remet l’e-mail au fournisseur. Quand le fournisseur échoue (délai dépassé, erreur, refus), Lekalao réessaie après 5 secondes, puis 30 secondes, 2 minutes, 10 minutes et 30 minutes. Il abandonne après le sixième essai raté, et de toute façon six heures après l’appel.status passe alors à failed, avec failure_code: provider_error et la dernière erreur du fournisseur dans failure_reason.
Un e-mail dont la tâche s’est perdue en route — un worker arrêté, une file vidée — ne reste pas pending pour toujours : sept heures après l’appel, il passe failed avec failure_code: lost. Son contenu n’a peut-être pas été gardé, il n’est donc pas renvoyé dans votre dos : renvoyez-le vous-même.
Les e-mails transactionnels ont leur propre file : ils n’attendent jamais derrière une campagne. La limite de débit du fournisseur s’applique toujours.
Le suivre par les webhooks
Plutôt que de relire l’e-mail encore et encore, laissez Lekalao vous prévenir. Abonnez une adresse aux événementstransactional.* (Webhooks) :
Chacun porte l’e-mail tel que l’API le montre : gardez son
id avec votre commande, et faites le lien par lui.
sent veut dire que le fournisseur l’a, pas qu’il est arrivé. delivered_at est rempli quand le fournisseur signale une remise, bounced_at quand l’adresse a rebondi définitivement, complained_at quand un lecteur l’a signalé comme spam ; status reste sent, et après un rebond failure_reason prend la raison du fournisseur. L’adresse part dans la liste de suppression après un rebond dur ou une plainte : le prochain e-mail vers elle ne partira pas. La même nouvelle arrive aussi par mail.bounced et mail.complaint, avec transactional_mail égal à l’id de l’e-mail.
Ou le relire
Sans adresse de webhook, relisez l’e-mail avecGET /v1/transactional-mails/{id} jusqu’à ce que status ne soit plus pending. Le jeton doit pouvoir Lecture, ce que fait un jeton Lecture et écriture.
Quand l’appel lui-même échoue
Un délai dépassé ou un5xx vous laisse sans savoir si Lekalao a l’e-mail. Renvoyez le même appel avec la même Idempotency-Key :
- si Lekalao avait répondu la première fois, vous recevez cette première réponse, avec
Idempotent-Replay: true, et aucun second e-mail ne part. C’est la réponse telle qu’elle était,pendingcompris : lisez l’e-mail pour savoir où il en est. Un422ou un429est gardé aussi : la même clé donne le même refus ; - un
502n’est pas retenu : la même clé envoie de nouveau.
Suivre et renvoyer
Un renvoi reprend les mêmes destinataires, variables, langue, objet et adresse d’expéditeur (
from_email), et le même fournisseur. Il ne reprend pas les pièces jointes, qui ne sont jamais gardées, ni un from_name ou un reply_to donnés au premier appel : ceux du modèle, ou de l’équipe, sont utilisés. Un e-mail de test renvoyé reste un e-mail de test.
Sans rien envoyer
Une clé de test n’envoie rien : l’e-mail est vérifié, rendu et journalisé, marquésent avec "sandbox": true, et compté dans aucun quota. Écrit à delivered@sink.lekalao.dev, bounced@sink.lekalao.dev et leurs voisines, il reçoit la réponse du fournisseur et ses webhooks, pour essayer vos gestionnaires de bout en bout.
Autres chemins
- Une application Laravel peut garder
Mail::to()->send(): voir Transport Laravel. - Un logiciel qui ne sait parler que SMTP : voir Relais SMTP.