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'
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user