Login required
Download

Email Confirmation

(2)
Author(s): Marc Palmer
Current Release: 1.0.3
Grails Version: 1.1 > *
Tags confirmation license-apache2 mail

Email Confirmation Plugin

Overview

This plugin will let you send an email to a user, including a link to your website for them to click so that you can confirm that they are able to receive that email at the address you have given them. You call a single method, passing in among other things the target email address and an optional unique ID your application can use to track the success or failure of the confirmation (often the email address itself, the default if left blank)

It handles:

  • the sending of the mail including the unique link
  • tracking pending confirmations and their unique tokens
  • the expiration of stale (old) confirmations from the database
  • sending different confirmations to the same address, for different reasons (you supply different "user tokens"), and you can differentiate these when confirmed or timed out
  • Short base62 encoded unique confirmation URLs
Interaction with your application is performed using callback event hooks, with a single method to call when you want to request a confirmation.

Since version 1.0.3 this plugin has required Grails 1.2. You can back-port to older versions of Grails if you like, by grabbing Grails 1.2's HexCodec implementation and adding it to your pre-1.2 project.

Getting started

1) For Grails 1.2.x - Install the plugin:

grails install-plugin email-confirmation

For older versions of grails you will need to install the mail plugin and the quartz plugin first - 1.1 will automatically do this.

2) Setup your callback event handling, adding code like this to BootStrap.groovy class:

def emailConfirmationService

def init = { servletContext -> emailConfirmationService.onConfirmation = { email, uid -> log.info("User with id $uid has confirmed their email address $email") // now do something… // Then return a map which will redirect the user to this destination return [controller:'userProfile', action:'welcome'] } emailConfirmationService.onInvalid = { uid -> log.warn("User with id $uid failed to confirm email address after 30 days") } emailConfirmationService.onTimeout = { email, uid -> log.warn("User with id $uid failed to confirm email address after 30 days") } }

If you are using Grails 1.0.x the above will not work, you will need to get to the confirmation service via the application context, as dependency injection in bootstrap is 1.1 and higher only

3) Make sure you have set your SMTP server host in Config.groovy for the grails-mail plugin:

grails.mail.host = 'mail.yourdomain.com' // Duh, don't try this at home!

Full details of configuration options for grails-mail plugin can be found in the docs for it: http://grails.org/plugin/mail

4) Now request a confirmation somewhere in your code, for example in a controller:

class YourController {
  def emailConfirmationService

def checkEmail = { // Only do this if not confirmed already! emailConfirmationService.sendConfirmation(params.emailAddress, "Please confirm", [from:"server@yourdomain.com"]) } }

Reference

Setting event hooks and properties

The EmailConfirmationService provides the public API for the plugin. There are the following properties:

  • maxAge - the number of milliseconds beyond which a pending confirmation is considered stale eg 3 days = 3 x 24 x 60 x 60 x 1000 (the default is 30 days)
  • onConfirmation - a closure accepting two parameters, called when a confirmation is completed (the link clicked), supplying the email address and the original user token string you passed in when requesting confirmation. If you return a Map value from this closure, it will be passed to the confirmation controller's redirect() method, so that you can have a custom page rendered or perform some action after the user confirms. New in 1.0.4 If you return a Closure this will be executed in the context of the confirmation controller, so you can use any controller methods you like. This is useful say for setting a cookie at the same time as redirecting the user.
  • onInvalid - a closure taking a single parameter (the bad user token) called when a click-through occurs for an unrecognized confirmation token. If you return a Map value from this closure, it will be passed to the confirmation controller's redirect() method, so that you can have a custom page rendered or perform some action after the user confirms. New in 1.0.4 If you return a Closure this will be executed in the context of the confirmation controller, so you can use any controller methods you like. This is useful say for setting a cookie at the same time as redirecting the user.
  • onTimeout - a closure taking a two parameters, called when the maximum age is exceeded on a confirmation. Typically called en masse once per day, when the cull job runs. The parameters are the email address and the application-supplied user token

Sending a confirmation email

The only method on EmailConfirmationService intended for application use is:

def sendConfirmation(String emailAddress, String theSubject,  
  Map model = null, String userToken = null)
You typically call this on the emailConfirmationService that you have injected into your code. The parameters are:
  • emailAddress - the email address to confirm (email will be sent to this address)
  • theSubject - the subject/title to put in the email headers eg "Please confirm your address for debuggr.com"
  • model - a Map containing any data you wish the email GSP to be able to use as its model, for example you may pass in the user's full name or account ID so that the email can show this. If a "from" is supplied in this binding, it will be used as the FROM address of the email. If this is not set, the Config variable "emailConfirmation.from" will be used.
  • userToken - a string that your application can use to tie up this request to your own data. This is passed back to your application in onConfirmation and onTimeout events, along with the email address. Typically you will use a unique site visitor ID, or some string identifying an action to be performed after confirmation. If you pass null the email address will be used.

Customizing the confirmation email text

The email GSP will be loaded from grails-app/views/emailconfirmation/mail/confirmationRequest.gsp by default and the mobel will have the variable "uri" containing the absolute link the user can click to confirm their email address. The "locale" passed in to the method will be available as "locale" in the GSP also.

Example of a mail template GSP…

Please click the link below to confirm your email address:

${uri}

You can also change the view used when requesting the confirmation, by specifying a value for "view" in the model passed to sendConfirmation:

emailConfirmationService.sendConfirmation(params.emailAddress, "Confirm!",  
  [view:'/myemailtemplates/genericConfirm'])
Note that unless you are sure there is an active controller, the template path must be prefixed with a /

Setting the "from" address of the message

You can pass in a "from" value in the binding when calling the sendConfirmation method, or you can set a value for "emailConfirmation.from" in your Config.groovy file.

Customizing the confirmation web page

The EmailConfirmationController that handles incoming confirmation requests has a single view it uses to tell the user what is happening. The default content is:

<html>
<body>
<g:if test="${success}">
	Thank you for confirming your email address.
</g:if>
<g:else>
	Sorry but we have been unable to confirm your email address. Please check the link
	in the email you received is correct.
</g:else>
</body>
</html>

You can see that ${success} is true if the confirmation completed successfully. If your onConfirmation/onInvalid returns a map the controller will redirect using those arguments, and the success and email properties will be set in flash scope.