Sending e-mails in HTML format in WSO2 ESB

Enabling mail transport sender and configuring message builder and message formatter. 


1. Uncomment the mail transport sender configuration in the <ESB_HOME>/repository/conf/axis2/axis2.xml file and make sure it points to a valid SMTP configuration for an actual scenario [1]


<transportSender name="mailto" class="org.apache.synapse.transport.mail.MailTransportSender">
    <parameter name="mail.smtp.host">smtp.gmail.com</parameter>
    <parameter name="mail.smtp.port">587</parameter>
    <parameter name="mail.smtp.starttls.enable">true</parameter>
    <parameter name="mail.smtp.auth">true</parameter>
    <parameter name="mail.smtp.user">synapse.demo.0</parameter>
    <parameter name="mail.smtp.password">mailpassword</parameter>
    <parameter name="mail.smtp.from">synapse.demo.0@gmail.com</parameter>
</transportSender>

2. Next configure the following builder and formatter in axis2 configuration for given content-type (text/html).

<messageBuilder contentType="text/html" class="org.apache.axis2.builder.ApplicationXMLBuilder"/> 
<messageFormatter contentType="text/html" class="org.apache.axis2.transport.http.ApplicationXMLFormatter"/>

However if you include special html tags to the email content like

<DOCTYPE> , <!-- Comment --> <?xml - xml declaration tags for rich content validating and rendering purposes you cannot use above mentioned XML builder and formatter and you will get errors while passing the mail message through ESB [2]

In that case you'll have to use BinaryRelayBuilder & ExpandingMessageFormatter. [2]

<messageBuilder contentType="text/html" class="org.wso2.carbon.relay.BinaryRelayBuilder"/>
<messageFormatter contentType="text/html" class="org.wso2.carbon.relay.ExpandingMessageFormatter"/> 

You can use following two options of using PayloadFactory mediator or using XSLT mediator to transform request payload into html.

Option 1: HTML template given as a local entry and map the request payload values into the place holders in html (Using PayloadFactory mediator)


Let's take a simple scenario of sending a simple email with adding the symbol taken from the request payload.

html email template as a local entry


<localEntry key="email_template_01">
<html>
    <body>
        <h2 style="color:green">$1</h2>
        <p>email template 01</p>
    </body>
</html>
<description/>
</localEntry>

Synapse configuration

MailTestProxy sets the property "SYMBOL" from the request payload and map the "symbol" value to the template.

<proxy name="MailTestProxy" 
       transports="https http"
       startOnLoad="true"
       trace="disable">
    <description/>
    <target>
        <inSequence>
            <property name="Subject" value="Testing email template" scope="transport"/>
            <property name="SYMBOL" expression="$body//symbol"/>
            <payloadFactory media-type="xml">
                <format key="email_template_01"/>
                <args>
                    <arg evaluator="xml" expression="get-property('SYMBOL')"/>
                </args>
            </payloadFactory>
            <property name="OUT_ONLY" value="true"/>
            <property name="FORCE_SC_ACCEPTED" value="true" scope="axis2"/>
            <send>
                <endpoint>
                    <address uri="mailto:xxx@xxx.com"/>
                </endpoint>
            </send>
            <drop/>
        </inSequence>
    </target> 
<proxy>

SOAP request

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<soapenv:Body>
    <symbol>WSO2</symbol>
</soapenv:Body>
</soapenv:Envelope>


Option 2: HTML template given as a xsl style sheet and using xslt mediator to transform the request payload values to the html tag values.


Let's take a simple scenario transforming Order details (which contains several items) into a simple email

Transforming the following request payload 


<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/> 
  <soapenv:Body> 
    <order id="54"> 
      <items> 
        <item> 
          <name>Cap</name> 
          <price>10.90</price> 
        </item> 
        <item> 
          <name>Hat</name> 
          <price>12.90</price> 
        </item> 
      </items> 
    </order> 
  </soapenv:Body> 
</soapenv:Envelope>

Into email body of 

<html xmlns=3D"http://ws.apache.org/ns/synapse"> 
   <body> 
      <h2>My Order</h2> 
      <h3>54</h3> 
      <table border=3D"1"> 
         <tr bgcolor=3D"#9acd32"> 
            <th>Item</th> 
            <th>Price</th> 
         </tr> 
         <tr> 
            <td>Cap</td> 
            <td>10.90</td> 
         </tr> 
         <tr> 
            <td>Hat</td> 
            <td>12.90</td> 
         </tr> 
      </table> 
   </body> 
</html>

Synapse configuration

<proxy name="MailTestProxy"
             transports="https http"
             startOnLoad="true"
             trace="disable">
    <description/>
    <target>
        <inSequence>
            <property name="Subject" value="My Orders" scope="transport"/> 
            <xslt key="html_transform"/> <property name="OUT_ONLY" value="true"/> 
            <property name="FORCE_SC_ACCEPTED" value="true" scope="axis2"/>
            <send>
                <endpoint>
                    <address uri="mailto:xxx@xxx.com"/>
                </endpoint>
            </send>
            <drop/>
        </inSequence>
    </target>
</proxy>


xsl style sheet as a local entry (e-mail template)


<localEntry key="html_transform"> 
      <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"> 
         <xsl:output indent="yes" method="xml" omit-xml-declaration="yes"/> 
         <xsl:template match="/"> 
            <html> 
               <body> 
                  <h2>My Order</h2> 
                  <h3> 
                     <xsl:value-of select="order/@id"/> 
                  </h3> 
                  <table border="1"> 
                     <tr bgcolor="#9acd32"> 
                        <th>Item</th> 
                        <th>Price</th> 
                     </tr> 
                     <xsl:for-each select="order/items/item"> 
                        <tr> 
                           <td> 
                              <xsl:value-of select="name"/> 
                           </td> 
                           <td> 
                              <xsl:value-of select="price"/> 
                           </td> 
                        </tr> 
                     </xsl:for-each> 
                  </table> 
               </body> 
            </html> 
         </xsl:template> 
      </xsl:stylesheet> 
      <description/> 
</localEntry>

If you want to take the email address also from the request payload then add the following part to synapse configuration


<header name="To" expression="fn:contact('mailto:',[This can be //Xpath or if comes from transport $trp:header] )"/> 
<send> 
    <endpoint> 
        <default/>
    </endpoint> 
</send>

and remove following part from the synapse configuration

<send>
    <endpoint>
        <address uri="mailto:xxx@xxx.com"/>
    </endpoint>
</send>


Comments

Popular Posts