Mobile tag

About Me

I am the "IBM Collaboration & Productivity Advisor" for IBM Asia Pacific. I'm based in Singapore.
Reach out to me via:
Follow notessensei on Twitter
Amazon Store
Amazon Kindle


Domino Upgrade

VersionSupport end
Upgrade to 9.x now!
(see the full Lotus lifcyle) To make your upgrade a success use the Upgrade Cheat Sheet.
Contemplating to replace Notes? You have to read this! (also available on Slideshare)


Other languages on request.


Useful Tools

Get Firefox
Use OpenDNS
The support for Windows XP has come to an end . Time to consider an alternative to move on.

« Aggregating view data for use in d3js graphics | Main| iOS vs Android »

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


Gravatar Image1 - Hi Stephan, thanks for posting this. A minor correction Atlassian Confluence does not have embedded experience inbuilt.


Gravatar Image2 - @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 stw

Gravatar Image3 - Thanks for sharing! Most interesting - and very timely!

Post A Comment

Please note: Comments without a valid and working eMail address will be removed. This is my site, so I decide what stays here and what goes.



This site is in no way affiliated, endorsed, sanctioned, supported, nor enlightened by Lotus Software nor IBM Corporation. I may be an employee, but the opinions, theories, facts, etc. presented here are my own and are in now way given in any official capacity. In short, these are my words and this is my site, not IBM's - and don't even begin to think otherwise. (Disclaimer shamelessly plugged from Rocky Oliver)
© 2003 - 2014 Stephan H. Wissel - some rights reserved as listed here: Creative Commons License
Unless otherwise labeled by its originating author, the content found on this site is made available under the terms of an Attribution/NonCommercial/ShareAlike Creative Commons License, with the exception that no rights are granted -- since they are not mine to grant -- in any logo, graphic design, trademarks or trade names of any type. Code samples and code downloads on this site are, unless otherwise labeled, made available under an Apache 2.0 license. Other license models are available on written request and written confirmation.