convert plain text newsletter email content to html using markdown-to-html and save it if html is not available
This commit is contained in:
@ -24,6 +24,7 @@
|
||||
"@types/json-bigint": "^1.0.1",
|
||||
"@types/node": "^14.11.2",
|
||||
"@types/rfc2047": "^2.0.1",
|
||||
"@types/showdown": "^2.0.1",
|
||||
"chai": "^4.3.6",
|
||||
"eslint-plugin-prettier": "^4.0.0",
|
||||
"mocha": "^10.0.0"
|
||||
@ -39,6 +40,7 @@
|
||||
"jsonwebtoken": "^8.5.1",
|
||||
"parse-headers": "^2.0.4",
|
||||
"parse-multipart-data": "^1.2.1",
|
||||
"rfc2047": "^4.0.1"
|
||||
"rfc2047": "^4.0.1",
|
||||
"showdown": "^2.1.0"
|
||||
}
|
||||
}
|
||||
|
||||
@ -12,6 +12,7 @@ import * as jwt from 'jsonwebtoken'
|
||||
import parseHeaders from 'parse-headers'
|
||||
import * as multipart from 'parse-multipart-data'
|
||||
import rfc2047 from 'rfc2047'
|
||||
import { Converter } from 'showdown'
|
||||
import { promisify } from 'util'
|
||||
import { Attachment, handleAttachments, isAttachment } from './attachment'
|
||||
import {
|
||||
@ -36,6 +37,11 @@ const signToken = promisify(jwt.sign)
|
||||
const NEWSLETTER_EMAIL_RECEIVED_TOPIC = 'newsletterEmailReceived'
|
||||
const NON_NEWSLETTER_EMAIL_TOPIC = 'nonNewsletterEmailReceived'
|
||||
const pubsub = new PubSub()
|
||||
const converter = new Converter()
|
||||
|
||||
export const plainTextToHtml = (text: string): string => {
|
||||
return converter.makeHtml(text)
|
||||
}
|
||||
|
||||
export const publishMessage = async (
|
||||
topic: string,
|
||||
@ -163,19 +169,24 @@ export const inboundEmailHandler = Sentry.GCPFunction.wrapHttpFunction(
|
||||
await handleAttachments(to, subject, attachments, receivedEmailId)
|
||||
return res.send('ok')
|
||||
}
|
||||
|
||||
// convert text to html if html is not available
|
||||
const content = html || plainTextToHtml(text)
|
||||
|
||||
// all other emails are considered newsletters
|
||||
const newsletterMessage = await handleNewsletter({
|
||||
from,
|
||||
to,
|
||||
subject,
|
||||
html,
|
||||
html: content,
|
||||
headers,
|
||||
})
|
||||
|
||||
// queue newsletter emails
|
||||
await pubsub.topic(NEWSLETTER_EMAIL_RECEIVED_TOPIC).publishMessage({
|
||||
json: {
|
||||
email: to,
|
||||
content: html || text, // html is preferred
|
||||
content,
|
||||
url: generateUniqueUrl(),
|
||||
title: subject,
|
||||
author: parseAuthor(from),
|
||||
|
||||
@ -2,7 +2,7 @@ import { expect } from 'chai'
|
||||
import 'mocha'
|
||||
import parseHeaders from 'parse-headers'
|
||||
import rfc2047 from 'rfc2047'
|
||||
import { parsedTo } from '../src'
|
||||
import { parsedTo, plainTextToHtml } from '../src'
|
||||
import {
|
||||
getConfirmationCode,
|
||||
isGoogleConfirmationEmail,
|
||||
@ -138,3 +138,29 @@ describe('decode and parse headers', () => {
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('plainTextToHtml', () => {
|
||||
it('converts text to html', () => {
|
||||
const text =
|
||||
'DEVOPS WEEKLY\r\n' +
|
||||
'ISSUE #665 - 24th September 2023\r\n' +
|
||||
'\r\n' +
|
||||
'A few posts on CI tooling this week, along with a good introduction to developer portals/platforms and other topics.\r\n' +
|
||||
'\r\n' +
|
||||
'StackHawk sponsors Devops Weekly\r\n' +
|
||||
'============================\r\n' +
|
||||
'\r\n' +
|
||||
'Experience automated security testing without the hassle of connecting your own app or configuring an environment! Follow the Tutorial to try out StackHawk and explore a world where security becomes an accelerator, not a blocker\r\n' +
|
||||
'\r\n' +
|
||||
'https://sthwk.com/tutorial\r\n' +
|
||||
'\r\n'
|
||||
expect(plainTextToHtml(text)).to.eql(
|
||||
`<p>DEVOPS WEEKLY
|
||||
ISSUE #665 - 24th September 2023</p>
|
||||
<p>A few posts on CI tooling this week, along with a good introduction to developer portals/platforms and other topics.</p>
|
||||
<h1 id="stackhawksponsorsdevopsweekly">StackHawk sponsors Devops Weekly</h1>
|
||||
<p>Experience automated security testing without the hassle of connecting your own app or configuring an environment! Follow the Tutorial to try out StackHawk and explore a world where security becomes an accelerator, not a blocker</p>
|
||||
<p>https://sthwk.com/tutorial</p>`
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
14
yarn.lock
14
yarn.lock
@ -7985,6 +7985,11 @@
|
||||
"@types/mime" "^1"
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/showdown@^2.0.1":
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/showdown/-/showdown-2.0.1.tgz#24134738ba3107237d6a783e054a54773e739f81"
|
||||
integrity sha512-xdnAw2nFqomkaL0QdtEk0t7yz26UkaVPl4v1pYJvtE1T0fmfQEH3JaxErEhGByEAl3zUZrkNBlneuJp0WJGqEA==
|
||||
|
||||
"@types/sinon-chai@^3.2.8":
|
||||
version "3.2.8"
|
||||
resolved "https://registry.yarnpkg.com/@types/sinon-chai/-/sinon-chai-3.2.8.tgz#5871d09ab50d671d8e6dd72e9073f8e738ac61dc"
|
||||
@ -11214,7 +11219,7 @@ commander@^8.3.0:
|
||||
resolved "https://registry.yarnpkg.com/commander/-/commander-8.3.0.tgz#4837ea1b2da67b9c616a67afbb0fafee567bca66"
|
||||
integrity sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==
|
||||
|
||||
commander@^9.1.0:
|
||||
commander@^9.0.0, commander@^9.1.0:
|
||||
version "9.5.0"
|
||||
resolved "https://registry.yarnpkg.com/commander/-/commander-9.5.0.tgz#bc08d1eb5cedf7ccb797a96199d41c7bc3e60d30"
|
||||
integrity sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==
|
||||
@ -24526,6 +24531,13 @@ shimmer@^1.2.1:
|
||||
resolved "https://registry.yarnpkg.com/shimmer/-/shimmer-1.2.1.tgz#610859f7de327b587efebf501fb43117f9aff337"
|
||||
integrity sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==
|
||||
|
||||
showdown@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/showdown/-/showdown-2.1.0.tgz#1251f5ed8f773f0c0c7bfc8e6fd23581f9e545c5"
|
||||
integrity sha512-/6NVYu4U819R2pUIk79n67SYgJHWCce0a5xTP979WbNp0FL9MN1I1QK662IDU1b6JzKTvmhgI7T7JYIxBi3kMQ==
|
||||
dependencies:
|
||||
commander "^9.0.0"
|
||||
|
||||
side-channel@^1.0.4:
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf"
|
||||
|
||||
Reference in New Issue
Block a user