Merge pull request #1009 from omnivore-app/fix/unsubscribe
fix not getting unsubscribe email address from beehiv newsletter by decoding the list-unsubscribe header
This commit is contained in:
@ -23,6 +23,7 @@
|
||||
"@types/addressparser": "^1.0.1",
|
||||
"@types/json-bigint": "^1.0.1",
|
||||
"@types/node": "^14.11.2",
|
||||
"@types/rfc2047": "^2.0.1",
|
||||
"eslint-plugin-prettier": "^4.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
@ -34,6 +35,7 @@
|
||||
"axios": "^0.27.2",
|
||||
"jsonwebtoken": "^8.5.1",
|
||||
"parse-headers": "^2.0.4",
|
||||
"parse-multipart-data": "^1.2.1"
|
||||
"parse-multipart-data": "^1.2.1",
|
||||
"rfc2047": "^4.0.1"
|
||||
}
|
||||
}
|
||||
|
||||
@ -65,29 +65,24 @@ export const inboundEmailHandler = Sentry.GCPFunction.wrapHttpFunction(
|
||||
console.log('headers: ', headers)
|
||||
|
||||
try {
|
||||
const from = parsed.from.toString()
|
||||
const from = parsed.from
|
||||
const subject = parsed.subject
|
||||
const html = parsed.html
|
||||
const text = parsed.text
|
||||
|
||||
const forwardedAddress = headers['x-forwarded-to']
|
||||
const recipientAddress = forwardedAddress
|
||||
? forwardedAddress.toString()
|
||||
: parsed.to
|
||||
const postHeader = headers['list-post']
|
||||
? headers['list-post'].toString()
|
||||
: ''
|
||||
const unSubHeader = headers['list-unsubscribe']
|
||||
? headers['list-unsubscribe'].toString()
|
||||
: ''
|
||||
const recipientAddress = forwardedAddress?.toString() || parsed.to
|
||||
const postHeader = headers['list-post']?.toString()
|
||||
const unSubHeader = headers['list-unsubscribe'].toString()
|
||||
|
||||
// check if it is a forwarding confirmation email or newsletter
|
||||
const newsletterHandler = getNewsletterHandler(
|
||||
postHeader,
|
||||
from,
|
||||
unSubHeader
|
||||
)
|
||||
try {
|
||||
// check if it is a forwarding confirmation email or newsletter
|
||||
const newsletterHandler = getNewsletterHandler(
|
||||
postHeader,
|
||||
from,
|
||||
unSubHeader
|
||||
)
|
||||
|
||||
if (newsletterHandler) {
|
||||
console.log('handleNewsletter', from, recipientAddress)
|
||||
await newsletterHandler.handleNewsletter(
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import { PubSub } from '@google-cloud/pubsub'
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
import addressparser from 'addressparser'
|
||||
import rfc2047 from 'rfc2047'
|
||||
|
||||
interface Unsubscribe {
|
||||
mailTo?: string
|
||||
@ -20,9 +21,10 @@ const UNSUBSCRIBE_MAIL_TO_PATTERN = /<mailto:([^>]*)>/
|
||||
export const parseUnsubscribe = (unSubHeader: string): Unsubscribe => {
|
||||
// parse list-unsubscribe header
|
||||
// e.g. List-Unsubscribe: <https://omnivore.com/unsub>, <mailto:unsub@omnivore.com>
|
||||
const decoded = rfc2047.decode(unSubHeader)
|
||||
return {
|
||||
mailTo: unSubHeader.match(UNSUBSCRIBE_MAIL_TO_PATTERN)?.[1],
|
||||
httpUrl: unSubHeader.match(UNSUBSCRIBE_HTTP_URL_PATTERN)?.[1],
|
||||
mailTo: decoded.match(UNSUBSCRIBE_MAIL_TO_PATTERN)?.[1],
|
||||
httpUrl: decoded.match(UNSUBSCRIBE_HTTP_URL_PATTERN)?.[1],
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -167,5 +167,15 @@ describe('Newsletter email test', () => {
|
||||
|
||||
expect(parseUnsubscribe(header).httpUrl).to.equal(httpUrl)
|
||||
})
|
||||
|
||||
context('when unsubscribe header rfc2047 encoded', () => {
|
||||
it('returns mail to address if exists', () => {
|
||||
const header = `=?us-ascii?Q?=3Cmailto=3A654e9594-184c-4884-8e02-e6e58a3a6871+87e39b3d-c3ca-4be?= =?us-ascii?Q?b-ba4d-977cc2ba61e7+067a353f-f775-4f2c-?= =?us-ascii?Q?a5cc-978df38deeca=40unsub=2Ebeehiiv=2Ecom=3E=2C?= =?us-ascii?Q?_=3Chttps=3A=2F=2Fwww=2Emilkroad=2Ecom=2Fsubscribe=2F87e39b3d-c3ca-4beb-ba4d-97?= =?us-ascii?Q?7cc2ba61e7=2Fmanage=3Fpost=5Fid=3D067a353f-f775?= =?us-ascii?Q?-4f2c-a5cc-978df38deeca=3E?=',`
|
||||
|
||||
expect(parseUnsubscribe(header).mailTo).to.equal(
|
||||
'654e9594-184c-4884-8e02-e6e58a3a6871+87e39b3d-c3ca-4beb-ba4d-977cc2ba61e7+067a353f-f775-4f2c-a5cc-978df38deeca@unsub.beehiiv.com'
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
17
yarn.lock
17
yarn.lock
@ -7947,6 +7947,11 @@
|
||||
resolved "https://registry.yarnpkg.com/@types/retry/-/retry-0.12.1.tgz#d8f1c0d0dc23afad6dc16a9e993a0865774b4065"
|
||||
integrity sha512-xoDlM2S4ortawSWORYqsdU+2rxdh4LRW9ytc3zmT37RIKQh6IHyKwwtKhKis9ah8ol07DCkZxPt8BBvPjC6v4g==
|
||||
|
||||
"@types/rfc2047@^2.0.1":
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/rfc2047/-/rfc2047-2.0.1.tgz#42eb43c161a52fd404a935f032360880ec84d400"
|
||||
integrity sha512-slgtykv+XXME7EperkdqfdBBUGcs28ru+a21BK0zOQY4IoxE7tEqvIcvAFAz5DJVxyOmoAUXo30Oxpm3KS+TBQ==
|
||||
|
||||
"@types/sanitize-html@^1.27.1":
|
||||
version "1.27.2"
|
||||
resolved "https://registry.yarnpkg.com/@types/sanitize-html/-/sanitize-html-1.27.2.tgz#f7bf16ca4b1408278f97ae737f0377a08a10b35c"
|
||||
@ -15257,6 +15262,11 @@ iconv-lite@0.4.24, iconv-lite@^0.4.24:
|
||||
dependencies:
|
||||
safer-buffer ">= 2.1.2 < 3"
|
||||
|
||||
iconv-lite@0.4.5:
|
||||
version "0.4.5"
|
||||
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.5.tgz#9c574b70c30d615859f2064d2be4335ad6b1a8d6"
|
||||
integrity sha512-LQ4GtDkFagYaac8u4rE73zWu7h0OUUmR0qVBOgzLyFSoJhoDG2xV9PZJWWyVVcYha/9/RZzQHUinFMbNKiOoAA==
|
||||
|
||||
iconv-lite@^0.6.2:
|
||||
version "0.6.2"
|
||||
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.2.tgz#ce13d1875b0c3a674bd6a04b7f76b01b1b6ded01"
|
||||
@ -21872,6 +21882,13 @@ reusify@^1.0.4:
|
||||
resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76"
|
||||
integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==
|
||||
|
||||
rfc2047@^4.0.1:
|
||||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/rfc2047/-/rfc2047-4.0.1.tgz#4e1cc217654728f09bc818b53a67d1d9c9d5067c"
|
||||
integrity sha512-x5zHBAZtSSZDuBNAqGEAVpsQFV+YUluIkMWVaYRMEeGoLPxNVMmg67TxRnXwmRmCB7QaneyrkWXeKqbjfcK6RA==
|
||||
dependencies:
|
||||
iconv-lite "0.4.5"
|
||||
|
||||
rfdc@^1.3.0:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.3.0.tgz#d0b7c441ab2720d05dc4cf26e01c89631d9da08b"
|
||||
|
||||
Reference in New Issue
Block a user