Mails dont le corps est vide quand on les envoie avec curl

Envoyer des mails avec curl est trivial. Les recevoir vides, mais avec malgré tout le bon sujet, sans erreur nulle part ni accès aux logs du serveur de mails1, beaucoup moins.

Le pire ? C’était un bête problème de sauts de ligne : il faut des CRLF, pas juste des LF.

En complément de cette note rapide, un exemple complet minimal pour scripter ses envois de mails comme un vrai poète de la ligne de commande.

cat << EOF > email.eml
From: "Nom expéditeur" <bot@domaine.fr>
To: "Personne Receveuse" <personne.receveuse@domaine.fr>
Subject: Ceci est un mail envoyé via curl
Content-Type: text/html; charset="utf8"
Content-Transfert-Encoding: quoted-printable
Mime-version: 1.0

EOF

# la ligne vide en dessous de Mime-version est là exprès pour séparer les en-têtes du corps du mail.

python -m quopri << EOF >> email.eml
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
    Ici, le beau contenu de votre mail
</body>
</html>
EOF

# Et là, on convertit les sauts de ligne pour que ce soit accepté par le serveur.
sed -i 's/$/\r/' email.eml

# Puis, on envoie !
curl -s smtp://mon.serveur.domaine.fr --mail-from bot@domaine.fr --mail-rcpt personne.receveuse@domaine.fr --upload-file email.eml

Si vous n’avez pas la version GNU de sed, il faudra passer par un fichier temporaire. Et si vous préférez envoyer en texte brut, ça devient vachement plus simple car Content-Type devient text/plain. Gardez tout de même l’encodage en fin de ligne. Puis ensuite vous pouvez virer tout le bazar html !

Vous trouverez plus d’infos pour des échanges en SSL avec le serveur de mails dans les liens ci-dessous.

Quelques détails en plus : Python et quopri

La bibliothèque quopri de Python est pratique pour échapper les caractères, afin qu’ils soient correctement interprétés et que le mail soit bien restitué.

Elle est même utilisable dans un script, afin de préparer les chaines de caractères qu’on enverrait sur la sortie standard (avec redirection depuis le script appelant) ou dans un fichier :

import quopri

# ... bla bla des traitements du script ...
# je fais un print() pour la simplicité de l'exemple

print(quopri.encodestring("Une chaîne de caractères à encoder"))

Pensez-y si vous utilisez le squelette donné en haut de cet article, mais que vous déléguez la création du html. Avec le Content-Transfert-Encoding: quoted-printable, vous pourriez avoir de mauvaises surprises sur toutes les séquences de caractères de type =AB. Oui, je parle bien de n’importe quelle balise html avec attributs, ou bien simplement des liens contenant des variables.

Et pour de multiples destinataires ?

Facile.

Dans l’en-tête To: du mail, rajoutez les adresses comme bon vous semble, en séparant par une virgule. Puis en appel à curl, rajoutez autant de --mail-rcpt que nécessaire.

Liens


  1. Dans mon cas, un serveur Microsoft Exchange. ↩︎