Watcher Email has Incorrect Format Using Mustache Template



I have recently created a watch that is supposed to send a formatted email with details about the query to the recipients. As a test to get the format of an html table correct I have the email body setup like this:

"body" : {
    "html" : "<head> <h1>Long Running Processes</h1> </head> <body> <table> <th>Number
     1</th> <th>Number 2</th> {{#ctx.payload.hits.hits}} <tr><td>1</td> <td>2</td> </tr>
     {{/ctx.payload.hits.hits}}   </table> </body>"

Basically I am attempting to make a table that contains a two headers "Number 1" and "Number 2" and then for each hit in ctx.payload.hits.hits create a row with 1 and 2 as the values in the table. This is strictly a placeholder as I have been unable to get the formatting correct. When looking at the .watch_history index I noticed that the output looked like:

"body": {
       "html": "<head></head><h1>Long Running Processes</h1><body> <table></table>
       </body>Number 1 Number 2  <tr><td>1</td><td>2</td></tr>  <tr><td>1</td><td>2</td>
       </tr>  <tr><td>1</td><td>2</td></tr>  <tr><td>1</td><td>2</td></tr>  <tr><td>1</td>
       <td>2</td></tr>  <tr><td>1</td><td>2</td></tr>  <tr><td>1</td><td>2</td></tr>  <tr>
       <td>1</td><td>2</td></tr>  <tr><td>1</td><td>2</td></tr>  <tr><td>1</td><td>2</td>
       </tr>  <tr><td>1</td><td>2</td></tr>  <tr><td>1</td><td>2</td></tr>  <tr><td>1</td>
       <td>2</td></tr>  <tr><td>1</td><td>2</td></tr>  <tr><td>1</td><td>2</td></tr>  <tr>
       <td>1</td><td>2</td></tr>  <tr><td>1</td><td>2</td></tr>  <tr><td>1</td><td>2</td>
       </tr>  <tr><td>1</td><td>2</td></tr>  "

Can someone explain to me why it appears the head, body, and table tags were moved and the row/data tags were pushed to the end? Is this expected behavior or a bug?


(Uri Boness) #2


The email html body goes through a sanitization process before it's fully rendered. And so there are two problems that you're facing:

  1. The html you defined is illegal. The <th> elements should be defined within a <tr> element.
  2. By default, the html sanitizer disallows the <th> elements, so these will be stripped.

Luckily, there is a way out:

it is possible to configure the sanitization by defining what html elements are allowed. Here is a setting that extends the default list of tags by adding the <th> to the list (place this setting in the elasticsearch.yml file... requires node restart): body, head, _tables, _links, _blocks, _formatting, img:embedded, th

Note that all the _* tags above are aliases to group of tags (e.g. _tables is an alias for <table>, <hr>, <tr> and <td> tags.

Now that the <th> tag is allowed, changing the html body to the following should do the trick:

<head> <h1>Long Running Processes</h1> </head> <body> <table> <tr><th>Number
     1</th> <th>Number 2</th> </tr>{{#ctx.payload.hits.hits}} <tr><td>1</td> <td>2</td> </tr>
     {{/ctx.payload.hits.hits}}</table> </body>


Thank you for the reply Uri. It appears that my dumb html screw up was the only issue. By fixing that the output shows up as expected. As an aside I would expect the watcher service to report an issue with the html in the .watch_history instead of moving things around.

Also it shows in the documentation that _tables is allowed by default:

By default, Watcher allows the following features: body, head, _tables, _links, _blocks, _formatting and img:embedded.


(Uri Boness) #4

glad things are working now.

By default, Watcher allows the following features: body, head, _tables, _links, _blocks, _formatting and img:embedded.

yes, _tables are enabled by default, but unfortunately there's a bug. The <th> tag is not supported by default - it's not part of the _tables element group even though it's documented as such. We'll make sure to fix this bug in 2.0. This effectively means that right now, with default settings the <th> tags are stripped. If you want to keep them, you'll need to apply the setting above.

(system) #5