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-SetLocal.pyBody = .pyBody
<java step code - see below>
Property-Set .pyBodyLocal.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;
        StringBuilderdebugTags=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 July 14, 2018 — Updated December 9, 2018

Have a question? Get answers now.

Visit the Pega Support Community to ask questions, engage in discussions, and help others.