Thanks everybody for the answers!
Below the solution - got the answer via email as apparently Partho didn't manage to post on Communities.
This is the final result:
Thanks again!
Stefania
---
From: Partho Garg <partho.garg@pemari.com>
Sent: 10 June 2021 15:53
Subject: RE: Clarity Digest for Wednesday June 9, 2021
Can't post to community and it does not show my response.
The issue was use of CDATA while setting variables - v_mail_row and v_mail_content. These should not be there.
Amended script below.
--------------------
<gel:script xmlns:core="jelly:core" xmlns:gel="jelly:com.niku.union.gel.GELTagLibrary" xmlns:xog="http://www.niku.com/xog" xmlns:soap="jelly:com.niku.union.gel.SOAPTagLibrary" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:sql="jelly:sql">
<!-- Initialize Variables -->
<gel:parameter default="xxxxx" var="XOGUsername"/>
<gel:parameter secure="true" default="xxxxxx" var="XOGPassword"/>
<gel:parameter default="/opt/apps/clarity/logs" var="LogFileDirectory"/>
<gel:parameter default="${LogFileDirectory}/ResInfile.xml" var="Infile"/>
<gel:parameter default="${LogFileDirectory}/ResOutfile.xml" var="Outfile"/>
<gel:formatDate format="yyyy-MM-dd HH:MM:S" stringVar="today"/>
<!-- Server Variable Testing -->
<core:invokeStatic className="com.niku.union.config.ConfigurationManager" method="getInstance" var="config"/>
<core:set var="v_IsLocal">0</core:set>
<core:set value="${config.getProperties().getWebServer().getWebServerInstance(0).getId()}" var="WebServerid"/>
<core:if test="${WebServerid == 'app'}">
<core:set value="${config.getProperties().getWebServer().getWebServerInstance(0).getAddress()}" var="AddressIp"/>
<core:set value="${config.getProperties().getWebServer().getWebServerInstance(0).getEntryUrl()}" var="EntryURL"/>
<core:set value="${config.getProperties().getWebServer().getWebServerInstance(1).getEntryUrl()}" var="NSAEntryURL"/>
<core:set value="${config.getProperties().getWebServer().getWebServerInstance(0).getEntryUrl()}" var="XOGURL"/>
<core:set value="${config.getProperties().getWebServer().getWebServerInstance(0).getPort()}" var="Port"/>
<core:if test="${EntryURL == 'http://localhost' }">
<gel:log level="info" message="NULL ADDRESS IS LOCAL... "/>
<core:set var="v_IsLocal">1</core:set>
<core:set var="AddressIp">${EntryURL}</core:set>
</core:if>
<!--<gel:log level="error" message="WebServerid. : ${WebServerid}"/> -->
<!--<gel:log level="error" message="AddressIp... : ${AddressIp}"/> -->
<!--<gel:log level="error" message="EntryURL.... : ${EntryURL}"/> -->
<!--<gel:log level="error" message="NSAEntryURL..: ${NSAEntryURL}"/> -->
<!--<gel:log level="error" message="Port........ : ${Port}"/> -->
<!--<gel:log level="error" message="CP Version 1.0"/> -->
<!--<gel:log level="error" message="ObjectInstanceID: ${gel_objectInstanceId}"/> -->
</core:if>
<!-- Get a DB Connection to Clarity -->
<gel:setDataSource dbId="Niku" var="clarityDS"/>
<gel:out trim="false"> [Query 1] Get Resources </gel:out>
<sql:query var="cresult" dataSource="${clarityDS}" escapeText="false"><![CDATA[
SELECT
r.USER_ID,
r.FULL_NAME,
r.EMAIL
FROM PRTEAM p
INNER JOIN INV_INVESTMENTS i
ON i.ID=p.PRPROJECTID
INNER JOIN SRM_RESOURCES r
ON p.PRRESOURCEID=r.ID
WHERE i.ODF_OBJECT_CODE = 'f_attivita'
]]></sql:query>
<gel:out trim="false"> [Query 1] End querying resources data.</gel:out>
<core:forEach trim="true" items="${cresult.rowsByIndex}" var="crow">
<core:set value="${crow[0]}" var="resource_id"/>
<core:set value="${crow[1]}" var="resource_name"/>
<core:set value="${crow[2]}" var="resource_email"/>
<gel:out trim="false"> [Resource Info] Internal Resource User ID: ${resource_id} </gel:out>
<gel:out trim="false"> [Resource Info] Resource Full Name: ${resource_name} </gel:out>
<gel:out trim="false"> [Resource Info] Resource Email: ${resource_email} </gel:out>
<gel:out trim="false"> [Query 2] Start Querying Conversation Data.</gel:out>
<sql:query var="dresult" dataSource="${clarityDS}" escapeText="false"><![CDATA[
SELECT
c.ID,
i.NAME,
t.PRNAME,
r.FULL_NAME,
CONCAT(CONCAT(CONCAT(CONCAT('http\://cappm15-na02/pm/#/investments/cust',REPLACE(INITCAP(i.ODF_OBJECT_CODE),'_','')),'s/'),TO_CHAR(i.ID)),'/tasks'),
c2.MESSAGE,
r2.FULL_NAME,
c.MESSAGE,
c.LAST_UPDATED_DATE
FROM NMC_CONVERSATIONS c
INNER JOIN SRM_RESOURCES r
ON r.USER_ID = c.CREATED_BY
INNER JOIN PRTASK t
ON c.RESOURCE_ID = t.PRID
INNER JOIN INV_INVESTMENTS i
ON t.PRPROJECTID = i.ID
LEFT OUTER JOIN NMC_CONVERSATIONS c2
ON c.PARENT_ID = c2.ID
LEFT OUTER JOIN SRM_RESOURCES r2
ON r2.USER_ID = c2.CREATED_BY
WHERE c.RESOURCE_NAME = 'tasks'
AND i.ODF_OBJECT_CODE IN ('f_attivita', 'f_assenze')
AND r.IS_ACTIVE = 1
AND c.LAST_UPDATED_DATE >= SYSDATE - 1
AND ( r2.USER_ID = ${resource_id}
OR
( SELECT COUNT(*)
FROM NMC_CONV_REFERENCES m
WHERE m.DATA_ID = ${resource_id}
AND m.CONVERSATION_ID = c.ID) != 0
)
]]></sql:query>
<gel:out trim="false"> [Query 2] End Querying Conversation Data.</gel:out>
<core:set escapeText = "false" var="v_mail_content">
<tr>
<td align="left"><b>Investimento</b> </td>
<td align="left"><b>Attivita'</b> </td>
<td align="left"><b>Autore messaggio</b></td>
<td align="left"><b>Link</b> </td>
<td align="left"><b>In risposta a</b> </td>
<td align="left"><b>Scritto da</b> </td>
<td align="left"><b>Messaggio</b> </td>
<td align="left"><b>Ultima modifica</b> </td>
</tr></core:set>
<core:forEach trim="true" items="${dresult.rowsByIndex}" var="drow">
<core:set value="${drow[0]}" var="conversation_id"/>
<core:set value="${drow[1]}" var="investment_name"/>
<core:set value="${drow[2]}" var="task_name"/>
<core:set value="${drow[3]}" var="author"/>
<core:set value="${drow[4]}" var="link"/>
<core:set value="${drow[5]}" var="in_response_to"/>
<core:set value="${drow[6]}" var="written_by"/>
<core:set value="${drow[7]}" var="conversation_body"/>
<core:set value="${drow[8]}" var="conversation_last_updated_date"/>
<gel:out trim="false"> [Conversation Info] Conversation ID: ${conversation_id} </gel:out>
<gel:out trim="false"> [Conversation Info] Investment Name: ${investment_name} </gel:out>
<gel:out trim="false"> [Conversation Info] Task Name: ${task_name} </gel:out>
<gel:out trim="false"> [Conversation Info] Conversation Author: ${author} </gel:out>
<gel:out trim="false"> [Conversation Info] Link: ${link} </gel:out>
<gel:out trim="false"> [Conversation Info] In Response To: ${in_response_to} </gel:out>
<gel:out trim="false"> [Conversation Info] Written By: ${written_by} </gel:out>
<gel:out trim="false"> [Conversation Info] Conversation Body: ${conversation_body} </gel:out>
<gel:out trim="false"> [Conversation Info] Conversation Last Updated Date: ${conversation_last_updated_date} </gel:out>
<core:set escapeText = "false" var="v_mail_row">
<tr>
<td align="left">${investment_name} </td>
<td align="left">${task_name} </td>
<td align="left">${author} </td>
<td align="left"><a href="${link}"></a> </td>
<td align="left">${in_response_to} </td>
<td align="left">${written_by} </td>
<td align="left">${conversation_body} </td>
<td align="left">${conversation_last_updated_date} </td>
</tr></core:set>
<core:set escapeText = "false" var="v_mail_content" value="${v_mail_content},${v_mail_row}" />
</core:forEach>
<gel:out trim="false"> [Data for HTML table] ${v_mail_content} </gel:out>
<gel:email from="stefania.dalessandro@broadcom.com" fromName="Clarity Admin" to="${resource_email}" subject="Conversations Of The Day"><![CDATA[<html>
Ciao ${resource_name}, <br/>
<br/>
eccoti l'elenco delle conversazioni in cui sei stato taggato e delle risposte ai tuoi post nelle ultime 24 ore: <br/>
<br/>
<table>
${v_mail_content}
</table></br>
</br>
Si prega di non rispondere direttamente a questo messaggio, in quanto la casella email non e' monitorata.
</html>]]></gel:email>
</core:forEach>
</gel:script>
------------------------------
Stefania D'Alessandro
Client Services Consultant, Clarity PPM
Broadcom ESD
------------------------------
Original Message:
Sent: 06-09-2021 11:26 AM
From: Stefania D'Alessandro
Subject: Help with HTML Formatting in GEL
Hello,
I created a script to send a daily notification email to all the users allocated to a certain custom investment (ID=f_attivita) in the Modern UX.
For every user X, the notification email contains the list of the conversations (timestamp in the past 24 hours) satisfying the following conditions: either X is tagged in the conversation or the message is a response to a conversation posted by X.
The queries included in the GEL script I wrote return the correct data - however, I have a problem with the HTML formatting of the email, as currently this is what I am getting:
Example (X = Dana):
This is the query result:
And this is the script:
<!-- 28.5.2021 SDA Conversation Notification Email - User gets notified when mentioned and when somebody replies to their posts (regardless of being mentioned) -->
<gel:script xmlns:core="jelly:core" xmlns:gel="jelly:com.niku.union.gel.GELTagLibrary" xmlns:xog="http://www.niku.com/xog" xmlns:soap="jelly:com.niku.union.gel.SOAPTagLibrary" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:sql="jelly:sql">
<!-- Initialize Variables -->
<gel:parameter default="xxxxx" var="XOGUsername"/>
<gel:parameter secure="true" default="xxxxxx" var="XOGPassword"/>
<gel:parameter default="/opt/apps/clarity/logs" var="LogFileDirectory"/>
<gel:parameter default="${LogFileDirectory}/ResInfile.xml" var="Infile"/>
<gel:parameter default="${LogFileDirectory}/ResOutfile.xml" var="Outfile"/>
<gel:formatDate format="yyyy-MM-dd HH:MM:S" stringVar="today"/>
<!-- Server Variable Testing -->
<core:invokeStatic className="com.niku.union.config.ConfigurationManager" method="getInstance" var="config"/>
<core:set var="v_IsLocal">0</core:set>
<core:set value="${config.getProperties().getWebServer().getWebServerInstance(0).getId()}" var="WebServerid"/>
<core:if test="${WebServerid == 'app'}">
<core:set value="${config.getProperties().getWebServer().getWebServerInstance(0).getAddress()}" var="AddressIp"/>
<core:set value="${config.getProperties().getWebServer().getWebServerInstance(0).getEntryUrl()}" var="EntryURL"/>
<core:set value="${config.getProperties().getWebServer().getWebServerInstance(1).getEntryUrl()}" var="NSAEntryURL"/>
<core:set value="${config.getProperties().getWebServer().getWebServerInstance(0).getEntryUrl()}" var="XOGURL"/>
<core:set value="${config.getProperties().getWebServer().getWebServerInstance(0).getPort()}" var="Port"/>
<core:if test="${EntryURL == 'http://localhost' }">
<gel:log level="info" message="NULL ADDRESS IS LOCAL... "/>
<core:set var="v_IsLocal">1</core:set>
<core:set var="AddressIp">${EntryURL}</core:set>
</core:if>
<!--<gel:log level="error" message="WebServerid. : ${WebServerid}"/> -->
<!--<gel:log level="error" message="AddressIp... : ${AddressIp}"/> -->
<!--<gel:log level="error" message="EntryURL.... : ${EntryURL}"/> -->
<!--<gel:log level="error" message="NSAEntryURL..: ${NSAEntryURL}"/> -->
<!--<gel:log level="error" message="Port........ : ${Port}"/> -->
<!--<gel:log level="error" message="CP Version 1.0"/> -->
<!--<gel:log level="error" message="ObjectInstanceID: ${gel_objectInstanceId}"/> -->
</core:if>
<!-- Get a DB Connection to Clarity -->
<gel:setDataSource dbId="Niku" var="clarityDS"/>
<gel:out trim="false"> [Query 1] Get Resources </gel:out>
<sql:query var="cresult" dataSource="${clarityDS}" escapeText="false"><![CDATA[
SELECT
r.USER_ID,
r.FULL_NAME,
r.EMAIL
FROM PRTEAM p
INNER JOIN INV_INVESTMENTS i
ON i.ID=p.PRPROJECTID
INNER JOIN SRM_RESOURCES r
ON p.PRRESOURCEID=r.ID
WHERE i.ODF_OBJECT_CODE = 'f_attivita'
]]></sql:query>
<gel:out trim="false"> [Query 1] End querying resources data.</gel:out>
<core:forEach trim="true" items="${cresult.rowsByIndex}" var="crow">
<core:set value="${crow[0]}" var="resource_id"/>
<core:set value="${crow[1]}" var="resource_name"/>
<core:set value="${crow[2]}" var="resource_email"/>
<gel:out trim="false"> [Resource Info] Internal Resource User ID: ${resource_id} </gel:out>
<gel:out trim="false"> [Resource Info] Resource Full Name: ${resource_name} </gel:out>
<gel:out trim="false"> [Resource Info] Resource Email: ${resource_email} </gel:out>
<gel:out trim="false"> [Query 2] Start Querying Conversation Data.</gel:out>
<sql:query var="dresult" dataSource="${clarityDS}" escapeText="false"><![CDATA[
SELECT
c.ID,
i.NAME,
t.PRNAME,
r.FULL_NAME,
CONCAT(CONCAT(CONCAT(CONCAT('http\://cappm15-na02/pm/#/investments/cust',REPLACE(INITCAP(i.ODF_OBJECT_CODE),'_','')),'s/'),TO_CHAR(i.ID)),'/tasks'),
c2.MESSAGE,
r2.FULL_NAME,
c.MESSAGE,
c.LAST_UPDATED_DATE
FROM NMC_CONVERSATIONS c
INNER JOIN SRM_RESOURCES r
ON r.USER_ID = c.CREATED_BY
INNER JOIN PRTASK t
ON c.RESOURCE_ID = t.PRID
INNER JOIN INV_INVESTMENTS i
ON t.PRPROJECTID = i.ID
LEFT OUTER JOIN NMC_CONVERSATIONS c2
ON c.PARENT_ID = c2.ID
LEFT OUTER JOIN SRM_RESOURCES r2
ON r2.USER_ID = c2.CREATED_BY
WHERE c.RESOURCE_NAME = 'tasks'
AND i.ODF_OBJECT_CODE IN ('f_attivita', 'f_assenze')
AND r.IS_ACTIVE = 1
AND c.LAST_UPDATED_DATE >= SYSDATE - 1
AND ( r2.USER_ID = ${resource_id}
OR
( SELECT COUNT(*)
FROM NMC_CONV_REFERENCES m
WHERE m.DATA_ID = ${resource_id}
AND m.CONVERSATION_ID = c.ID) != 0
)
]]></sql:query>
<gel:out trim="false"> [Query 2] End Querying Conversation Data.</gel:out>
<core:set escapeText = "false" var="v_mail_content"><![CDATA[
<tr>
<td align="left"><b>Investimento</b> </td>
<td align="left"><b>Attivita'</b> </td>
<td align="left"><b>Autore messaggio</b></td>
<td align="left"><b>Link</b> </td>
<td align="left"><b>In risposta a</b> </td>
<td align="left"><b>Scritto da</b> </td>
<td align="left"><b>Messaggio</b> </td>
<td align="left"><b>Ultima modifica</b> </td>
</tr>]]></core:set>
<core:forEach trim="true" items="${dresult.rowsByIndex}" var="drow">
<core:set value="${drow[0]}" var="conversation_id"/>
<core:set value="${drow[1]}" var="investment_name"/>
<core:set value="${drow[2]}" var="task_name"/>
<core:set value="${drow[3]}" var="author"/>
<core:set value="${drow[4]}" var="link"/>
<core:set value="${drow[5]}" var="in_response_to"/>
<core:set value="${drow[6]}" var="written_by"/>
<core:set value="${drow[7]}" var="conversation_body"/>
<core:set value="${drow[8]}" var="conversation_last_updated_date"/>
<gel:out trim="false"> [Conversation Info] Conversation ID: ${conversation_id} </gel:out>
<gel:out trim="false"> [Conversation Info] Investment Name: ${investment_name} </gel:out>
<gel:out trim="false"> [Conversation Info] Task Name: ${task_name} </gel:out>
<gel:out trim="false"> [Conversation Info] Conversation Author: ${author} </gel:out>
<gel:out trim="false"> [Conversation Info] Link: ${link} </gel:out>
<gel:out trim="false"> [Conversation Info] In Response To: ${in_response_to} </gel:out>
<gel:out trim="false"> [Conversation Info] Written By: ${written_by} </gel:out>
<gel:out trim="false"> [Conversation Info] Conversation Body: ${conversation_body} </gel:out>
<gel:out trim="false"> [Conversation Info] Conversation Last Updated Date: ${conversation_last_updated_date} </gel:out>
<core:set escapeText = "false" var="v_mail_row"><![CDATA[
<tr>
<td align="left">${investment_name} </td>
<td align="left">${task_name} </td>
<td align="left">${author} </td>
<td align="left"><a href="${link}"></a> </td>
<td align="left">${in_response_to} </td>
<td align="left">${written_by} </td>
<td align="left">${conversation_body} </td>
<td align="left">${conversation_last_updated_date} </td>
</tr>]]></core:set>
<core:set escapeText = "false" var="v_mail_content" value="${v_mail_content},${v_mail_row}" />
</core:forEach>
<gel:out trim="false"> [Data for HTML table] ${v_mail_content} </gel:out>
<gel:email from="stefania.dalessandro@broadcom.com" fromName="Clarity Admin" to="${resource_email}" subject="XXX: conversazioni delle ultime 24 ore"><![CDATA[<html>
<head>
<style>
table, th, td {
border: 1px solid black;
border-collapse: collapse;
}
th, td {
padding: 5px;
}
th {
text-align: center;
}
</style>
</head>
<body>
Ciao ${resource_name}, <br/>
<br/>
eccoti l'elenco delle conversazioni in cui sei stato taggato e delle risposte ai tuoi post nelle ultime 24 ore: <br/>
<br/>
<table>
${v_mail_content}
</table></br>
</br>
<br> Clicca <a href="XXX">qui</a> per accedere a XXX. </br>
</br>
<br> Si prega di non rispondere direttamente a questo messaggio, in quanto la casella email non e' monitorata.</br>
</body>
</html>]]></gel:email>
</core:forEach>
</gel:script>
Can somebody help me understand how to fix the HTML formatting so that the notification email includes a table and not the HTML syntax as a string?
Thanks in advance.
Stefania
------------------------------
Stefania D'Alessandro
Client Services Consultant, Clarity PPM
Broadcom ESD
------------------------------