Le Touilleur Express

  • Accueil
  • A propos de l’auteur
  • A propos du Touilleur Express

Play! Framework : envoyer un email

4 septembre, 2010

L’envoi d’un email est simple avec le framework Web Play! Framework.
Vous pouvez envoyer un email directement en une ligne :

Mail.send("sender@express-board.fr","candidat@hotmail.fr","Subject","Test de message");

Cependant la façon la plus pratique est d’utiliser une partie du framework et des entités. Lorsque vous vous inscrivez comme candidat sur mon site express-board.fr, vous recevez un email afin de vous souhaiter la bienvenue. Voyons comment cela fonctionne.

Dans le répertoire appsnotifiers j’ai créé une classe Mails qui étend la classe Mailer de Play!

package notifiers;

import models.*;
import play.*;
import play.mvc.*;

import java.util.*;

public class Mails extends Mailer {

    public static void welcome(User user) {
        setSubject("Bienvenue sur eXpress Board");
        addRecipient(user.email);
        setFrom("contact@express-board.fr");
        send(user);
    }

}

La méthode welcome reçoit en argument une entité User et appelle la méthode send de Mailer. Celle-ci recherche alors un template HTML et un template TXT afin d’envoyer l’email. Il suffit donc de créer 2 fichiers portant exactement le même nom que la méthode dans le répertoire viewsMails.

Voici le fichier viewsMailswelcome.txt pour l’envoi en text/plain de l’email :

Bienvenue sur eXpress Board !
=============================

Votre compte a été activé.

Votre nom d'utilisateur est votre adresse email : ${user.email}
Votre mot de passe : ${user.password}

En cas de soucis techniques, n'hésitez pas à nous contacter par email : contact@express-board.fr

A bientôt !

L'équipe eXpress Board

Comme vous pouvez le constater, je peux utiliser le moteur Groovy de Play! pour récupérer et afficher l’email et le mot de passe de l’utilisateur. La syntaxe ${…} n’est que du Groovy, le meilleur langage de script pour la plate-forme Java.

Voici le fichier viewsMailswelcome.html :

<table width="650" align="center" style="font-size: 14px;" cellpadding="0" cellspacing="0">
    <tr id="topshadow">
        <td height="10" width="10" background="http://www.express-board.fr/public/images/email/shadow_tl.gif" bgcolor="#ffffff"></td> 
        <td height="10" background="http://www.express-board.fr/public/images/email/shadow_top.gif" bgcolor="#ffffff"> </td>
        <td height="10" width="10" background="http://www.express-board.fr/public/images/email/shadow_tr.gif" bgcolor="#ffffff"> </td>
    </tr>

    <tr id="header">
        <td width="10" background="http://www.express-board.fr/public/images/email/shadow_left.gif" bgcolor="#ffffff" rowspan="2"></td>
        <td height="102" background="http://www.express-board.fr/public/images/email/header_bg.gif" bgcolor="#e6f1fb" align="center">
            <table width="95%"><tr><td align="left"><img src="http://www.express-board.fr/public/images/email/email_logo.gif" /></td></tr></table>
        </td>
        <td width="10" background="http://www.express-board.fr/public/images/email/shadow_right.gif" bgcolor="#ffffff" rowspan="2"> </td>
    </tr>

    <tr id="content">
        <td bgcolor="#f4faff" align="center">
            <table width="95%" cellpadding="30">
                <tr>
                    <td align="left">
                        <font face="Lucida Grande, Segoe UI, Arial, Verdana, Lucida Sans Unicode, Tahoma, Sans Serif">
<h3>Bienvenue sur l'eXpress-Board !</h3>

<p>Votre compte a été activé.</p>
<hr>
<p>Votre nom d'utilisateur est votre adresse email : ${user.email}</p>
<p>Votre mot de passe : ${user.password}</p>
<hr>
<p>Vous pouvez maintenant <a href="http://www.express-board.fr/administration/login">vous authentifier</a> et poster votre première annonce ! </p>
<p>En cas de soucis techniques, n'hésitez pas à nous contacter par email : contact@express-board.fr</p>

<br/>
<br/>
A bientôt !
<br/>
<br/>
<br/>
<br/>
L'équipe express-Board<br/><br/>
P.S. Suivez-nous sur notre compte <a href="http://twitter.com/expressboard">Twitter</a>
                        </font>
                    </td>
                </tr>
            </table>
        </td>
    </tr>

    <tr id="bottomshadow">
        <td height="10" width="10" background="http://www.express-board.fr/public/images/email/shadow_bl.gif" bgcolor="#ffffff"></td>
        <td height="10" background="http://www.express-board.fr/public/images/email/shadow_bottom.gif" bgcolor="#ffffff"> </td>
        <td height="10" width="10" background="http://www.express-board.fr/public/images/email/shadow_br.gif" bgcolor="#ffffff"> </td>
    </tr>

    <tr id="copyright">
        <td></td>
        <td align="right">
            <span style="font-size: 12px; color: #888;"> © 2010 eXpress-Board.fr par Innoteria SARL</span>
        </td>
        <td></td>
    </tr>
</table>

Lorsque vous envoyez des emails au format HTML, il faut que les URLs des images soient absolues. Sans quoi, les navigateurs ou les lecteurs de mails refusent de les charger.

Et comment envoyer cet email ?

Voici un exemple de méthode. Un formulaire permet de saisir le nom, l’email et un texte de présentation. Au passage, notez comment Play! permet de gérer les arguments obligatoires d’un formulaire et de valider le champ email. Il y a différentes façons de faire, je vous proposerai un article séparé pour vous en parler.


     public static void saveNewUser(@Required String fullname, 
                                                     @Required String email,
                                                     @MaxSize(message = "Le contenu du champ présentation est trop long", value = 1000) String presentation) {
      
        validation.email(email).message("Email invalide, merci de saisir un email correct pour continuer.");
       
        if (validation.hasErrors()) {
            params.flash(); // add http parameters to the flash scope
            render("/Administration/createAccount.html");
            return;
        }
 
        // verification si user existe deja..
        ... 
        ...

        // creation de l'utilisateur
        User user = new User();
        user.email = email;
        user.fullname = fullname;
        user.presentation = presentation.trim();

        user.password = RandomStringUtils.randomAlphanumeric(9);
        user.active = Boolean.TRUE;
        user.validateAndSave();

        // Envoi de l'email 
        Mails.welcome(user);
 
       render(user);
    }
 

Configuration d’un compte Gmail

Pour l’eXpress-Board, j’ai fait simple : j’utilise une boite email hébergé sur Gandi.net. J’ai ensuite configuré mon compte GMail afin de l’autoriser à aller chercher les emails via POP/IMAP sur ce serveur. Et le tour est joué… je reçois mes emails de l’express-board sur ma boite GMail.

Pour configurer un compte Gandi avec Play! afin de pouvoir envoyer un email, voici ma configuration (avec le mot de passe modifié bien entendu)

%playapps.application.mode=prod
%playapps.db=mysql:play:play@play
%playapps.mail.smtp.host=mail.gandi.net
%playapps.mail.smtp.user=contact@express-board.fr
%playapps.mail.smtp.pass=MOT DE PASSE EN CLAIR
%playapps.mail.smtp.channel=ssl
%playapps.mail.smtp.port=465
%playapps.mail.debug=false

J’utilise l’hébergement PlayApps.net, la plateforme de cloud de Zenexity. C’est l’hébergeur du site l’express-board. Cela fonctionne vraiment bien, c’est gratuit pour l’instant, et j’en suis vraiment très content.

Allez, à vous de jouer maintenant !

Update

Suite aux 2 remarques de Benoit et Tartur, je précise quelques points qui peuvent surprendre lorsque l’on découvre Play! L’entité User n’a pas attributs statiques. Il n’y a pas d’encapsulation, les propriétés sont publiques tout simplement.

package models;

import javax.persistence.*;

import org.hibernate.annotations.GenericGenerator;
import play.db.jpa.*;
import play.data.validation.*;

import java.util.List;

@Entity
public class User extends Model {
    @Email
    @Required
    public String email;

    @Required
    public String password;

    @Lob
    @MaxSize(1000)
    public String presentation;

    public Boolean active;

    public User() {
    }

    public static User connect(String email, String password) {
        return find("byEmailAndPassword", email, password).first();
    }

    public static User findByEmail(String email) {
        return find("byEmail", email).first();
    }

    @Override
    public String toString() {
        return fullname;
    }

    public static List findAllActives() {
        return find("active", Boolean.TRUE).fetch();
    }

}

La classe User étend Model, une classe de base de Play! Celle-ci me fournit quelques services. Elle étend elle-même la classe JPASupport de Play, qui donne un ensemble de méthode type crud directement à mon entité. C’est une approche différente de ce que l’on voit classiquement en Java. Bien entendu vous pouvez écrire du code JPA classique, mettre des services et des DAO, cela fonctionne aussi. Mais j’apprécie de gagner du temps en utilisant ce système de Play! qui est plutôt bien pensé.

Articles similaires:

Default ThumbnailPlay! Framework : Uploader une image Default ThumbnailPlay! Framework : la claque Default ThumbnailFramework Play! à découvrir le jeudi 17 décembre Default ThumbnailGit et Play! Framework
  • Benoît Courtine 4 septembre 2010 at 16 h 42 min

    Article très intéressant, comme d’habitude.

    N’étant pas encore familier de Play!, je trouve le fonctionnement de la classe Mails curieuse…

    Raisonnement Javaïste pas encore habitué à Play! : la méthode « welcome » est statique et appelle des setters (de la classe mère), qui sont donc à priori eux aussi statiques. Du coup, si plusieurs utilisateurs s’enregistrent exactement en même temps (ça serait vraimant pas de chance, mais imaginons…), n’y-a-t’il pas un risque de d’envoyer un mail à la mauvaise personne en environnement multi-threads ?

  • tartur 4 septembre 2010 at 17 h 31 min

    @Benoit Il n’y a pas de risque car la classe Mailer utilise des attributs ThreadLocal 🙂

  • Nicolas Martignole 4 septembre 2010 at 19 h 57 min

    @Benoit : Dans la classe play.mvc.Mailer, tu as une Hashmap de String et Object qui est stockée dans une ThreadLocal. C’est le moyen de s’assurer qu’en effet, tu ne reçois pas le mail destiné à ton voisin.

    Concernant la classe User, j’ai complété l’article afin de montrer la tête qu’elle a. Il n’y a pas d’attributs static.

    Nicolas

  • Benoît Courtine 4 septembre 2010 at 21 h 58 min

    Merci pour toutes ces précisions ! C’est très enrichissant (et ça donne de plus en plus envie de se mettre à Play! : dès que j’aurai un moment de libre, je mets ça en tête de ma TODO)

  • meissa 6 septembre 2010 at 11 h 19 min

    J’ai été voir la plateform de cloud il y à juste 10 minutes. C’est pas gratuit (ça démarre à 10 €).
    C’est dommage si on veut essayer pour voir ce que ça donne.
    merci pour l’article.
    Meissa

  • Moulay Semlali 6 septembre 2010 at 11 h 55 min

    Je passe de temps en temps lire le touilleur et c’est plutôt agréable de voir des gens partager.

    Je vais donc essayer de rester dans cet esprit en indiquant que pour les mails et les images, on n’est pas obligés de mettre le lien absolu vers les images.
    On peut – avec les content-id – embarquer directement les images dans le mail (cf ici avec les commons apache).

    Après, il faut bien sur que le client mail accepte les content-id … :p

    Merci Nicolas et continue comme ça !! 🙂

  • Nicolas Martignole 6 septembre 2010 at 19 h 47 min

    @meissa : en fait c’est gratuit pour l’instant. Les prix sont précisés à titre indicatif. Les équipes de Zenexity acceptent les projets un par un. Il faut donc que tu proposes un projet solide, et ils te laissent alors tester librement la plateforme.

  • Stephane Epardaud 7 septembre 2010 at 11 h 39 min

    Mais la vraie question est : comment on reçoit un mail en Play! 😉 (seul moyen par exemple pour envoyer une photo vers un site web à partir d’un smartphone bridé comme les iPhones)

Derniers articles

  • Vis ma vie de Staff/Principal Engineer

    Suite de l’article précédent sur le Staff Engineer. Aujourd’hui, voyons un peu

    20 juillet, 2022
  • Inari

    Devenir Staff Engineer : comment et pourquoi ?

    Après une dizaine d’années en tant que développeur, vous serez un jour

    17 juillet, 2022
  • WeAreDevelopers 2022, conférence à Berlin – jour 1

    Il est 8h40, 19 degrés, vous êtes à Berlin. La queue dehors

    24 juin, 2022

Tweets @nmartignole

  • Je découvre qu’ils apprennent le SQL en Terminal, très intéressant https://t.co/MrfcHve9wo

    12 hours ago
  • RT  @AmelieBenoit33 : Je m’essaye à de nouveaux formats ! Un premier sketch qui me trottait en tête depuis le sketchnote précédent; la techn…

    21 hours ago
  • RT  @ShirleyAlmCh : Je recrute un profil de Solution Architect (H/F) pour le compte de la Casden. J'ai adoré discuté avec eux, super ambiance…

    2 days ago

Mots clés

Apple (32) Architecture (13) Big Data (5) Conference (8) Devoxx (55) Dev Web (37) Doctolib (2) geekevent (1) groovy (2) Innoteria (11) Java (517) Linux (10) Non classé (14) Perso (266) Recrutement (3) Scala (30) scrum (43) Société (3) Startup (20) Web 2.0 (67)

Le Touilleur Express

Blog par Nicolas Martignole

Contactez-moi : nicolas@touilleur-express.fr

Suivez-moi sur Twitter : @nmartignole

Copyright© 2008 - 2020 Nicolas Martignole | Tous droits réservés
  • A propos de l’auteur
  • A propos du Touilleur Express
  • Log In
  • My Account
  • My Profile
  • Reset Password

Le Touilleur Express