Usability - Productivity - Business - The web - Singapore & Twins

Driving Embedded Experiences Adoption

With the introduction of Connections Mail and IBM Notes 9.0 a brand new productivity feature was made available in eMail: Embedded Experiences (EE). They are defined by the Open Social Foundation and can also be found in IBM Connections or Atlassian's Confluence Wiki.
The use case for embedded experiences in eMail is simple:
" Any application that sends a notification message to your attention and/or action can reduce the time and clicks required for processing by taking advantage of an embedded experience"
Ryan described in detail how to switch on the processing of embedded experiences and the Wiki tells how how to use XPages to send them. The trouble with this: you need to touch every single application that sends out a notification. You might not have time, budget or source code access to them.
So are EE a nice idea, but confined to some niche applications?
Not at all! When peeking under the hood, you can see, that an EE enabled eMail has a HTML and a JSON Mime part. If a client doesn't understand EE (like mobile clients or any other eMail than IBM Notes), then the HTML message is rendered. Important here: even with Notes you must have a HTML part, a plain text message won't do. Using a "when new mail arrives" agent, you can turn an incoming message into an EE.
As long as the target system supports one of the authentications the Account API provides (Basic HTTP, JEE Form, SAML, Spengo, OS Credential, Siteminder, LTPA) this will work. This is Notes client only, for Connections or iNotes you are limited to SAML.
First thought was to use a "Before mail arrives" agent to make sure, that the mail gets delivered fully converted. However such an agent runs in the router context and might be a performance killer - the when new mail arrives option seems a suitable compromise. The approach works with signed eMails too, since signing covers the eMail body, but not headers and mime separators (you can't sign the header since each routing hop adds information there).
As an example I used a plain text eMail, that sends a notification with a number of field/values separated by colon and containing only one URL. For your use cases, you will need to adopt the code (or wait for a future blog, just saying). Since my original message only contained text/plain I had to add text/html and application/json mime parts.The Notes API MimeEntity class makes the code rather simple and does the conversion in less than 100 lines of code. It will work for any notification following this pattern.
Sub ConvertToEE (s As NotesSession, doc As NotesDocument )
    Dim body As NotesMIMEEntity
    Dim parent As NotesMIMEEntity
    Dim header As NotesMIMEHeader
    Dim jsonEE As NotesMIMEEntity
    Dim htmlEE As NotesMIMEEntity
    Dim jsonStream As NotesStream
    Dim htmlStream As NotesStream
    Dim content As NotesStream

    Dim headerName As String
    Dim headerValue As String
    Dim newHeaders List As String
    Set content = s. Createstream ( )
    Set jsonStream = s. Createstream ( )
    Set htmlStream = s. Createstream ( )
    s. Convertmime = False
    Set body = doc. Getmimeentity ( "Body" )
    Call body. Getcontentastext (content, True )
    Set parent = body. Createparententity ( )
    Call addHeader (parent, "Content-Type", "multipart/alternative" )
    Call addHeader (parent, "MIME-Version", "1.0" )
    Call generateEEParts (content,jsonStream,htmlStream )

    jsonStream. position = 0
    Set jsonEE = parent. Createchildentity ( )
    Call jsonEE. Setcontentfromtext (jsonStream, "application/embed+json;charset=UTF-8", ENC_IDENTITY_7BIT )
    htmlStream. position = 0
    Set htmlEE = parent. Createchildentity ( )
    Call htmlEE. Setcontentfromtext (htmlStream, "text/html;charset=UTF-8", ENC_IDENTITY_7BIT )
    Call doc. Replaceitemvalue ( "containsEE", "URL" )
    Call doc. Save ( true, true )
    s. Convertmime = true
End Sub
    Sub generateEEParts
    Description: Creates the body content for

Sub generateEEParts (stream As NotesStream, outJSON As NotesStream, outHTML As NotesStream )
    Dim workstring As String
    Dim url As String
    Dim ParamName As String
    Dim ParamValue As String
    Dim position As Integer
    Dim isFirst As Boolean
    Dim eolChars List As Integer
    Dim eolPos As Integer
    Dim i As Integer
    Dim x As String
    eolChars ( 0 ) = 10
    eolChars ( 1 ) = 13
    eolChars ( 2 ) = 42
    'Create the URL
    Call outHTML. writeText ( |<h1 style="background-color : Yellow; font-family: Verdana, Arial, sans-serif">Workflow notification (URL)</h1>|,EOL_PLATFORM )
    Call outHTML. writeText ( |<table border="0" cellpadding="2" cellspacing="2">|,EOL_PLATFORM )
    Call outHTML. writeText ( |<tr><th style="border : 1px solid gray; font-family: Verdana, Arial, sans-serif">Parameter</th><th style="border: 1px solid gray; font-family: Verdana, Arial, sans-serif">Value</th></tr>|,EOL_PLATFORM )
    'Loop through all the items
    stream. Position = 0
    workstring = stream. Readtext (STMREAD_LINE , EOL_ANY )
    isFirst = true
    Do Until workString = ""
        For eolPos = 1 To Len (workString )
            x = x + CStr ( Asc ( Mid$ (workstring,eolPos, 1 ) ) )+ "-"
        'Cleanup workstring - remove 10/13 combinations
        ForAll curChar In eolChars
            eolPos = InStr (workstring, Chr$ (curChar ) )
            While (eolPos > 0 )
                workstring = Left$ (workstring,eolPos- 1 )
                eolPos = InStr (workstring, Chr$ (curChar ) )
        End ForAll

        position = InStr (workstring, ":" )
        If position > 0 Then
            'We have a line with a Name / Value Pair
            ParamName = Replace ( Trim$ ( Left$ (workstring,position- 1 ) ), |"|, |\"| )
            ParamValue = Replace ( Trim$ ( Mid$ (workstring,position+ 1 ) ), |"|, |\"| )
            If Left$ (ParamValue, 4 ) = "http" Then
                Call outJSON. writeText ( |{ "url"  : "|+ParamValue+ |" }|,EOL_PLATFORM )
            End If
            Call outHTML. writeText ( |<tr><td style="border: 1px solid gray; font-family: Verdana, Arial, sans-serif">|,EOL_PLATFORM )
            Call outHTML. writeText (ParamName,EOL_PLATFORM )
            Call outHTML. writeText ( |</td><td style="border-bottom : 1px solid gray; border-right: 1px solid gray; font-family: Verdana, Arial, sans-serif">|,EOL_PLATFORM )
            Call outHTML. writeText (ParamValue,EOL_PLATFORM )
            Call outHTML. writeText ( |</td></tr>|,EOL_PLATFORM )
        End If
        workstring = stream. Readtext (STMREAD_LINE , EOL_Platform )
    'Write out the closing
    Call outHTML. writeText ( |</table>|,EOL_PLATFORM )
End Sub
Sub addHeader (mime As NotesMIMEEntity, hName As String, value As String )
        Dim header As NotesMIMEHeader
        Set header = mime. CreateHeader (hName )
        If header Is Nothing Then
            Set header = mime. Getnthheader (hname )
        End If
        Call header. SetHeaderVal (value )
End Sub
As usual: YMMV

Posted by on 03 November 2013 | Comments (3) | categories: IBM Notes XPages


  1. posted by Stephan Wissel on Monday 04 November 2013 AD:
    @David, I just checked, and there are Gadgets listed for embedded experiences in a pretty plain Confluence installation, so they are there (just google it). Also the documetation for OpenSocial is in Confluence.

    Emoticon biggrin.gif stw
  2. posted by Robert Ibsen Voith on Monday 04 November 2013 AD:
    Thanks for sharing! Most interesting - and very timely!
  3. posted by David Simpson on Monday 04 November 2013 AD:
    Hi Stephan, thanks for posting this. A minor correction Atlassian Confluence does not have embedded experience inbuilt.

    Emoticon smile.gif