Skip to Content
Author's profile photo Chris Paine

Sending formatted email with inline images from #sapnwcloud (part two, the fixes)

Hello again, just a short post this time. I picked up on some of the feedback from my first post about sending emails from NetWeaver Cloud, and have made a couple of enhancements to the solution that I thought I’d share.

Users will be users, and networks will be networks.

One of the fun things about using a RESTful design is there is no guarantee of the order in which entries will be processed. A user might submit a time sheet entry for 5 Feb 2013 and then 1 Feb 2013 and then 3 Feb 2013, or they might submit them in order but a network routing bug means the second gets processed before the first – yet they get confused if you present them the entries in that muddled order in the email that they get back.

So I implemented a very simple sorting routine to allow the entries to always be sorted in date order in the output:

public void sendMail() {
                           MailEventSender mailer = new MailEventSender();
                                // sort the entries by date first!
                                Comparator<TimeSheetEntry> comparator = new Comparator<TimeSheetEntry>() {
                                                public int compare(TimeSheetEntry c1, TimeSheetEntry c2) {
                                                                SimpleDateFormat formatter = new SimpleDateFormat("yyyymmdd");
                                                                try {
                                                                                Date d1 = formatter.parse(c1.getAssociatedDay().getDay());
                                                                                Date d2 = formatter.parse(c2.getAssociatedDay().getDay());
                                                                                return d1.compareTo(d2);
                                                                } catch (ParseException e) {
                                                                                return 0;
                                Collections.sort(entries, comparator);
                                mailer.sendEmail(userId, entries, context, rootURL);

Pretty simple, but a huge impact on user satisfaction 🙂 .

It’s probably worth avoiding legal complications

I found out that in Australia it’s kinda illegal to email out in an automated message (especially one with a “please contact us further about this …” text) unless you have a working unsubscribe function. (I’m no lawyer, but I think an email where we throw in our URL and telephone number, probably counts as “commercial”).

Part 2Rules about sending commercial electronic messages

15  Simplified outline

                   The following is a simplified outline of this Part:

•      Unsolicited commercial electronic messages must not be sent.

•      Commercial electronic messages must include information about the individual or organisation who authorised the sending of the message.

•      Commercial electronic messages must contain a functional unsubscribe facility.

(source Spam Act 2003 – Part 2, section 15 – )

So given my emails kinda fall under that legislation (I think), we thought be better do something.

I added a new database field (and had to drop the db again 😈 – which made my testers really happy – NOT!) to store a unsubscribe key.

When sending out an email I now add this key as part of a web link:

    if (user.getUnsubscribeKey() == null || user.getUnsubscribeKey().equals(""))
                                           // if a user has not had an email sent yet, they cannot be unsubscribed
                                           user.setUnsubscribeKey( UUID.randomUUID().toString());
          String unsubscribeURL = rootURL + "Unsubscribe.html";

and a new method to get the link

public String getUnsubscribeHtml(String rootUrl) {
        return String
            .format("<p style=\"font-size:xx-small;\"><i>"
                           + "You have been sent this email because your email address was "
                           + "entered in the Discovery Consulting demonstration mobile application. If "
                           + "you no longer wish to receive emails from this application, please click "
                           + "<a href =\""
                           + rootUrl + "?unsubscribeKey=" + id + "-" + unsubscribeKey
                           + "\">unsubscribe from time sheet emails</a></i></p>");

As you can see the link contains both the user id that is being unsubscribed plus a key that is generated just for that user (this is to stop you from unsubscribing someone else by fiddling with the link address.)

The email now looks like:


with teeny tiny small print making me legally compliant.(I hope!)  🙂

Having a nicely formatted response

By redirecting to a web page and using AJAX calls to actually de-register the user, I could manage to make my resulting unsubscribe page as nice looking as the others in my application.


I’m sure my testing team will have me re-writing the text here, but I thought it was nice of me not to put in big letters “YOU’VE ALREADY DE-REGISTERED! FOOL” 😉

A little JavaScript helped:

$(document).ready(function() {
          var key = getURLParameter("unsubscribeKey");
          var unsubscribeURI = "unsubscribe" + "/" + key;
          var jsonData = $.parseJSON($.ajax({
                    url : unsubscribeURI,
                    dataType : "json",
                    async : false
          if (jsonData.unsubscribed == true) {
                    $("#unsubscribe_success").css('visibility', 'visible');
                    if (jsonData.alreadyUnsubscribed == true) {
                              $("#unsubscribe_success_again").css('visibility', 'visible');
          } else {
                    $("#unsubscribe_fail").css('visibility', 'visible');
function getURLParameter(name) {
          return decodeURIComponent((new RegExp('[?|&]' + name + '='
                              + '([^&;]+?)(&|#|;|$)').exec( || [ , "" ])[1]
                              .replace(/\+/g, '%20'))
                              || null;

I found the get parameter code from stackoverflow – amazing how useful that site is!

and a little css hides the various messages in the page on load:

                    visibility: hidden;
          visibility: hidden;
          visibility: hidden;

I know it’s not as RESTful as the other bits of my build. I suppose I could have built a servlet that accepted a DELETE and used the key as part of the resource URL. But it was at this point, more important to get it working.


As usual, there is the disclaimer, you’re free to try to reuse any of this code, but don’t expect it to work, that’s up to you to get it working! If you do reuse, some kind of acknowledgement is always appreciated. Hope you found this post useful, it’s not really a full blog, but I thought it was just a little too much to add into the comments of the previous blog (which was already stupidly long.) 🙂 Thanks for reading!

Assigned Tags

      You must be Logged on to comment or reply to a post.
      Author's profile photo Susan Keohan
      Susan Keohan

      Chris, I've been keeping track of your blogs and I am blown away by the amount of great stuff you are sharing. 
      Did you know you and Joanna Chan were going to create these blogs at the beginning of your project? 

      Thanks so much!


      Author's profile photo Chris Paine
      Chris Paine

      Hi Sue,

      yes when we sat down to plan our build, we actually set aside one day per "section" to blog about it. For the reasons that I shared in my other blog Should I really be sharing all this? plus, it means that if we have to explain it, we should hopefully understand it a bit better.

      As it turns out, I've probably spent more than a day per blog, but that's mainly because I've had fun with the videos, which are slowly getting better 😉 . So I've been using a bit of my "own" time too.

      Glad you're enjoying them!