Support Article
HTML on Pulse sometimes not rendered
SA-61219
Summary
When processing incoming emails using the Email Listener, the extracted text (pyBody) is posted to Pulse. However, some emails are posted as HTML source.
Error Messages
Not Applicable
Steps to Reproduce
Use Email Listener to process emails.
Root Cause
This issue was determined to be a product enhancement request.
The email listener can be configured to prefer 'plaintext' or 'HTML'. If 'plaintext' is selected, and the incoming email lacks any plaintext content, then it falls back to using the HTML instead. Processing of the HTML part is not done to convert to text. The source of the HTML is what is extracted.
When using the Email Listener in conjunction with Pega Pulse, the raw or source HTML text is posted on screen instead of human-readable text content.
The email client must be set to send emails which contain text/plain or both HTML and text/plain.
Resolution
Perform the following local-change:
The .pyInboundEmail.pyBody property (which contains the content of the incoming email's body) can be post-processed using Custom Java. It must be noted that stripping text from HTML is a destructive process and loses formatting information (such as Fonts, Tables, Image references).
However, under some circumstances, stripping just the text content is recommended than manage incoming emails without plain text content.
In Pega 7.3 and Pega 7.3.1, 'Tag Soup' the third-party library is shipped with the out-of-the-box product.
The implementation (an Activity) example is as follows:
Define two Local variables for the Activity (on the Parameters Tab). pyBody (String)
bodyTextSB (StringBuffer)
This requires two PROPERTY-SET steps; one before and after the Java Step.
Property-Set Local.pyBody = .pyBody
<java step code - see below>
Property-Set .pyBody Local.pyBody
The Activity must have the '.pyInBoundEmail' set Step Page (Note: this is an Embedded Page and must be prefixed with '.').
Set up the 'Rule-Service-Email' to point to the Activity above.
Service > Service activity > Activity name
On the same 'Rule-Service-Email' > Request.
Ensure that Rule-Service-Email > Message data > Handle HTML content is set to 'inline - prefer text'.
The Email Listener will fall-back on using the HTML part. Then user can 'strip it' as required using the Activity.
--- START: java step code: cut here ---
// See end of this Java Step for call to inner class.
// This is NOT a fully tested solution; this is provided as an example starting point only.
// "Strips" text from Body of HTML document
// Relies on Third Party Library "Tag Soup" (org.ccil.cowan.tagsoup), which is included in PEGA7.3
//
java.io.InputStream is = new org.apache.commons.io.input.ReaderInputStream(new java.io.StringReader( pyBody ), java.nio.charset.StandardCharsets.UTF_8);
bodyTextSB=new StringBuffer();
class myHandler extends org.xml.sax.helpers.DefaultHandler {
final String NL="\r\n";
String[] tags= { "body", "script" , "style" };
java.util.Map<String, Boolean> tagsOfInterest=new java.util.HashMap<>();
{
for (String tag: tags) {
tagsOfInterest.put(tag, false);
}
}
@Override
public void characters(char ch[], int start, int length) {
if ( tagsOfInterest.get( "body" ) ) {
boolean dontWrite=false;
StringBuilder debugTags=new StringBuilder();
for (String tag: tagsOfInterest.keySet() ) {
if (!tag.equals("body")) {
dontWrite=dontWrite | tagsOfInterest.get(tag);
}
if (oLog.isDebugEnabled()) {
debugTags.append( tag+"="+tagsOfInterest.get(tag)+" " );
}
}
oLog.debug( debugTags );
if (oLog.isDebugEnabled()) {
oLog.debug("dontwrite="+dontWrite);
}
if (dontWrite) {
return;
}
else {
String tempString = new String(ch, start, length);
bodyTextSB.append( tempString );
}
}
}
@Override
public void startElement(String uri, String localName,
String name, org.xml.sax.Attributes a) {
String lc=localName.toLowerCase();
if (tagsOfInterest.containsKey( lc )) {
tagsOfInterest.put(lc, true);
if (oLog.isDebugEnabled()) {
oLog.debug("Start Tag Detected for:"+lc);
}
}
if (lc.equals("p") || lc.equals("br") || lc.equals("div") ) { bodyTextSB.append(NL); } // Not strictly necessarily (and might be wrong sometimes):attempt to preserve newlines.
}
@Override
public void endElement(String namespaceURI, String localName, String qName) {
String lc=localName.toLowerCase();
if (tagsOfInterest.containsKey( lc )) {
tagsOfInterest.put(lc, false);
if (oLog.isDebugEnabled()) {
oLog.debug("End Tag Detected for:"+lc);
}
}
}
}
try {
org.ccil.cowan.tagsoup.jaxp.SAXParserImpl.newInstance(null).parse( is , new myHandler() );
String tempString=bodyTextSB.toString();
if (oLog.isDebugEnabled()) {
oLog.debug("Original .pyBody: "+ pyBody);
oLog.debug("Modified .pyBody:" + tempString);
}
if (tempString.length() > 0) {
pyBody=tempString;
}
else { oLog.info("Zero Length String returned when parsing input; returning original .pyBody"); }
}
catch(Exception e) { if (oLog.isDebugEnabled()) { oLog.error(e);}
oLog.info("Error Parsing Input: pyBody is unaltered.");
}
--- END: java step code: cut here ---
Published December 9, 2018 - Updated October 8, 2020
Have a question? Get answers now.
Visit the Collaboration Center to ask questions, engage in discussions, share ideas, and help others.