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.
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
%REM
Sub generateEEParts
Description: Creates the body content for
%END REM
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 ) ) )+ "-"
Next
'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 ) )
Wend
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 )
Loop
'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: YMMVDim 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
%REM
Sub generateEEParts
Description: Creates the body content for
%END REM
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 ) ) )+ "-"
Next
'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 ) )
Wend
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 )
Loop
'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
Posted by Stephan H Wissel on 03 November 2013 | Comments (3) | categories: IBM Notes XPages