Skip to content

Commit

Permalink
Renders email action message text as html from markdown (#41006)
Browse files Browse the repository at this point in the history
* uses `message` passed to action as text/plain message, and renders `message` as markdown to html as the text/html message

* fix jest test
  • Loading branch information
pmuellr authored Jul 15, 2019
1 parent 58a319d commit f4d8f5c
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -188,9 +188,7 @@ describe('execute()', () => {
const executorOptions: ActionTypeExecutorOptions = { config, params, services };
sendEmailMock.mockReset();
await actionType.executor(executorOptions);
expect(sendEmailMock.mock.calls).toMatchInlineSnapshot(`
Array [
Array [
expect(sendEmailMock.mock.calls[0][1]).toMatchInlineSnapshot(`
Object {
"content": Object {
"message": "a message to you",
Expand All @@ -213,9 +211,7 @@ Array [
"service": "__json",
"user": "bob",
},
},
],
]
}
`);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ async function executor(execOptions: ActionTypeExecutorOptions): Promise<any> {
},
};

return await sendEmail(sendEmailOptions);
return await sendEmail(services, sendEmailOptions);
}

// utilities
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@
// info on nodemailer: https://nodemailer.com/about/
import nodemailer from 'nodemailer';

import { default as MarkdownIt } from 'markdown-it';

import { Services } from '../../types';

// an email "service" which doesn't actually send, just returns what it would send
export const JSON_TRANSPORT_SERVICE = '__json';

Expand Down Expand Up @@ -39,7 +43,7 @@ interface Content {
}

// send an email
export async function sendEmail(options: SendEmailOptions): Promise<any> {
export async function sendEmail(services: Services, options: SendEmailOptions): Promise<any> {
const { transport, routing, content } = options;
const { service, host, port, secure, user, password } = transport;
const { from, to, cc, bcc } = routing;
Expand All @@ -64,6 +68,7 @@ export async function sendEmail(options: SendEmailOptions): Promise<any> {
}

const nodemailerTransport = nodemailer.createTransport(transportConfig);
const messageHTML = htmlFromMarkdown(services, message);

const email = {
// email routing
Expand All @@ -73,7 +78,7 @@ export async function sendEmail(options: SendEmailOptions): Promise<any> {
bcc,
// email content
subject,
html: message,
html: messageHTML,
text: message,
};

Expand All @@ -89,3 +94,18 @@ export async function sendEmail(options: SendEmailOptions): Promise<any> {

return result;
}

// try rendering markdown to html, return markdown on any kind of error
function htmlFromMarkdown(services: Services, markdown: string) {
try {
const md = MarkdownIt({
linkify: true,
});

return md.render(markdown);
} catch (err) {
services.log(['debug', 'actions'], `error rendering markdown to html: ${err.message}`);

return markdown;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -102,14 +102,35 @@ export default function emailTest({ getService }: KibanaFunctionalTestDefaultPro
cc: null,
bcc: null,
subject: 'email-subject',
html: 'email-message',
html: '<p>email-message</p>\n',
text: 'email-message',
headers: {},
},
});
});
});

it('should render html from markdown', async () => {
await supertest
.post(`/api/action/${createdActionId}/_fire`)
.set('kbn-xsrf', 'foo')
.send({
params: {
to: ['[email protected]'],
subject: 'message with markdown',
message: '_italic_ **bold** https://elastic.co link',
},
})
.expect(200)
.then((resp: any) => {
const { text, html } = resp.body.message;
expect(text).to.eql('_italic_ **bold** https://elastic.co link');
expect(html).to.eql(
'<p><em>italic</em> <strong>bold</strong> <a href="https://elastic.co">https://elastic.co</a> link</p>\n'
);
});
});

it('should respond with a 400 Bad Request when creating an email action with an invalid config', async () => {
await supertest
.post('/api/action')
Expand All @@ -132,7 +153,4 @@ export default function emailTest({ getService }: KibanaFunctionalTestDefaultPro
});
});
});

// TODO: once we have the HTTP API fire action, test that with a webhook url pointing
// back to the Kibana server
}

0 comments on commit f4d8f5c

Please sign in to comment.