Je viens de reconstruire un nouveau système d'envoi d'email pour mes services en ligne. Le système que j'avais développé précédement permettait de faire déjà beaucoup de choses, mais il y avait des problèmes de délivrabilité dans certains cas (= ça tombe dans les spams).

Je ne cherche pas à envoyer des newsletters (Mailchimp ou Snipemal sont très bien pour ça), mais des emails dit "transactionnels".

Premiere solution pour la délivrabilité : utilisez Mailjet et configurer DKIM + SPF.

La fonctionnalité essentielle recherchée est un système de templates. C'est à dire que je veux simplement créer des emails avec mon éditeur habituel et ajouter des variables dedans, et cela en plusieurs langues. En complément, je veux que mes emails soit "multi-part" c'est à dire TXT + HTML.

Je vais utiliser deux librairies assez simples et légères que je vais combiner pour ça :

  • SwiftMailer pour générer les emails et les envoyer.
  • RainTPL  pour le système de template.
Voici le code que j'ai créé pour tester le système. Je vous met le premier jet, pas intégré dans une classe, ni sécurisé. Il faut que vous téléchargiez les classes rain et swift et les installiez au bon endroit, évidement...
<html>
<head>
<title>Test Mailjet avec template</title>
</head><body>
<h2>Test envoi email moderne</h2>
<?php
require_once 'swift/swift_required.php'; // corrigez avec vos chemins
require_once 'rain/rain.tpl.class.php';
$subject = 'Message de '.time(); // j'ai juste mis un time() pour les différenciers dans bal
$emailfrom = array('olivier@test.com' => 'Expéditeur');
$emailto = array( 'abc@xyz.com' => 'Destinataire');
$variables["productname"] = "iPod"; // liste de variable qui seront utilisé dans le templare
$modele = "email"; // ca, c'est le nom de mon template
$lang = 'fr';
// donc vous devrez creer les fichiers suivants :
// - tpl/fr/email.html <- version HTML de l'email
// - tpl/fr/email.txt <- version TXT de l'email
// envoi pas le smtp de mailjet
$transport = Swift_SmtpTransport::newInstance('in.mailjet.com', 465, 'tls'); // pour une raison inconnu, ca ne marchait pas quand je mettait le n° de port indiqué par Mailjet (587)... il faudrait que j'en discute avec eux.
$transport->setUsername('votre clé API'); // mailjet API Key
$transport->setPassword('votre clé secrette'); // mailjet Secret Key
$mailer = Swift_Mailer::newInstance($transport);
//Create the message
$message = Swift_Message::newInstance();
$message->setSubject($subject);
$message->setFrom($emailfrom);
$message->setTo($emailto);
//initialize a Rain TPL object
$tpl = new RainTPL;
$tpl->configure( "base_url", null );
$tpl->configure( "tpl_dir", "tpl/".$lang.'/' );
$tpl->configure( "cache_dir", "tmp/" );
$tpl->configure( "black_list", array("_SESSION") );
//initialisation des variables
$tpl->assign($variables);
//génération des messages à partir du TPL
$msg_html = $tpl->draw( $modele, $return_string = true );
$tpl->configure("tpl_ext", "txt" );
$msg_txt  = $tpl->draw( $modele, $return_string = true );
//assignation des message
$message->setBody($msg_txt);
$message->addPart($msg_html, 'text/html');
// envoi de l'email
if (!$mailer->send($message)) {
echo "<p>Erreur à l'envoi de l'email</p>";
}
  
?>
</body></html>

Les fichiers templates email.html et email.txt pourait ressemble à ca :

email.html

<html>

<head></head>

<body>

<p>Bonjour,</p>

<p>Merci d'avoir acheté le <strong>produit <a href="http://www.42stores.com">{$productname}</a></strong></p>

<p>A bientot,</p>

Olivier

</body></html>

email.txt

Bonjour,

Merci d'avoir acheté le produit {$productname}

A bientot,

Olivier

Et voilà une premiere approche du problème, à vous de continuer après. Mais cette petite description m'aurait été utilise alors je vous la partage !

PS : il y a mieux que d'envoyer les emails via SwitfMailer à Mailjet. Mailjet préconise l'utilisation du SMTP local qui redirige vers leur serveur (ça permet de gérer une file d'attente locale, et ca va donc plus vite au niveau du PHP). Mais pour des raisons de flexibilité ça ne m'arrange pas pour le moment.