mirror of
https://github.com/omnivore-app/omnivore.git
synced 2026-03-11 08:54:26 +00:00
Forward subscription confirmation email
This commit is contained in:
parent
ce4e078754
commit
f7d46752e1
2 changed files with 32 additions and 15 deletions
|
|
@ -13,8 +13,9 @@ import parseHeaders from 'parse-headers'
|
|||
import * as multipart from 'parse-multipart-data'
|
||||
import { promisify } from 'util'
|
||||
import {
|
||||
handleConfirmation,
|
||||
isConfirmationEmail,
|
||||
handleGoogleConfirmationEmail,
|
||||
isGoogleConfirmationEmail,
|
||||
isSubscriptionConfirmationEmail,
|
||||
parseUnsubscribe,
|
||||
} from './newsletter'
|
||||
import { handlePdfAttachment } from './pdf'
|
||||
|
|
@ -132,10 +133,13 @@ export const inboundEmailHandler = Sentry.GCPFunction.wrapHttpFunction(
|
|||
})
|
||||
|
||||
try {
|
||||
// check if it is a confirmation email or forwarding newsletter
|
||||
if (isConfirmationEmail(from, subject)) {
|
||||
console.log('handleConfirmation', from)
|
||||
await handleConfirmation(to, subject)
|
||||
// check if it is a subscription google confirmation email
|
||||
const isGoogleConfirmation = isGoogleConfirmationEmail(from, subject)
|
||||
if (isGoogleConfirmation || isSubscriptionConfirmationEmail(subject)) {
|
||||
console.debug('handleConfirmation', from, subject)
|
||||
// we need to parse the confirmation code from the email
|
||||
isGoogleConfirmation &&
|
||||
(await handleGoogleConfirmationEmail(to, subject))
|
||||
// queue non-newsletter emails
|
||||
await pubsub.topic(NON_NEWSLETTER_EMAIL_TOPIC).publishMessage({
|
||||
json: {
|
||||
|
|
@ -163,6 +167,7 @@ export const inboundEmailHandler = Sentry.GCPFunction.wrapHttpFunction(
|
|||
)
|
||||
return res.send('ok')
|
||||
}
|
||||
// all other emails are considered newsletters
|
||||
const newsletterMessage = await handleNewsletter({
|
||||
from,
|
||||
to,
|
||||
|
|
|
|||
|
|
@ -7,12 +7,14 @@ interface Unsubscribe {
|
|||
httpUrl?: string
|
||||
}
|
||||
|
||||
const EMAIL_CONFIRMATION_CODE_RECEIVED_TOPIC = 'emailConfirmationCodeReceived'
|
||||
const CONFIRMATION_EMAIL_SENDER_ADDRESS = 'forwarding-noreply@google.com'
|
||||
const GOOGLE_CONFIRMATION_CODE_RECEIVED_TOPIC = 'emailConfirmationCodeReceived'
|
||||
const GOOGLE_CONFIRMATION_EMAIL_SENDER_ADDRESS = 'forwarding-noreply@google.com'
|
||||
// check unicode parentheses too
|
||||
const CONFIRMATION_CODE_PATTERN = /\d+/u
|
||||
const GOOGLE_CONFIRMATION_CODE_PATTERN = /\d+/u
|
||||
const UNSUBSCRIBE_HTTP_URL_PATTERN = /<(https?:\/\/[^>]*)>/
|
||||
const UNSUBSCRIBE_MAIL_TO_PATTERN = /<mailto:([^>]*)>/
|
||||
const CONFIRMATION_EMAIL_SUBJECT_PATTERN =
|
||||
/(confirm|verify).*(newsletter(s)*|subscription(s)*|sign\s*up)/i
|
||||
|
||||
export const parseUnsubscribe = (unSubHeader: string): Unsubscribe => {
|
||||
// parse list-unsubscribe header
|
||||
|
|
@ -32,7 +34,10 @@ const parseAddress = (address: string): string => {
|
|||
return ''
|
||||
}
|
||||
|
||||
export const handleConfirmation = async (email: string, subject: string) => {
|
||||
export const handleGoogleConfirmationEmail = async (
|
||||
email: string,
|
||||
subject: string
|
||||
) => {
|
||||
console.log('confirmation email', email, subject)
|
||||
|
||||
const confirmationCode = getConfirmationCode(subject)
|
||||
|
|
@ -47,11 +52,11 @@ export const handleConfirmation = async (email: string, subject: string) => {
|
|||
}
|
||||
|
||||
const message = { emailAddress: email, confirmationCode: confirmationCode }
|
||||
return publishMessage(EMAIL_CONFIRMATION_CODE_RECEIVED_TOPIC, message)
|
||||
return publishMessage(GOOGLE_CONFIRMATION_CODE_RECEIVED_TOPIC, message)
|
||||
}
|
||||
|
||||
export const getConfirmationCode = (subject: string): string | undefined => {
|
||||
const matches = subject.match(CONFIRMATION_CODE_PATTERN)
|
||||
const matches = subject.match(GOOGLE_CONFIRMATION_CODE_PATTERN)
|
||||
if (matches) {
|
||||
// get the number code only
|
||||
// e.g. (#123456) => 123456
|
||||
|
|
@ -60,9 +65,16 @@ export const getConfirmationCode = (subject: string): string | undefined => {
|
|||
return undefined
|
||||
}
|
||||
|
||||
export const isConfirmationEmail = (from: string, subject: string): boolean => {
|
||||
export const isGoogleConfirmationEmail = (
|
||||
from: string,
|
||||
subject: string
|
||||
): boolean => {
|
||||
return (
|
||||
parseAddress(from) === CONFIRMATION_EMAIL_SENDER_ADDRESS &&
|
||||
CONFIRMATION_CODE_PATTERN.test(subject)
|
||||
parseAddress(from) === GOOGLE_CONFIRMATION_EMAIL_SENDER_ADDRESS &&
|
||||
GOOGLE_CONFIRMATION_CODE_PATTERN.test(subject)
|
||||
)
|
||||
}
|
||||
|
||||
export const isSubscriptionConfirmationEmail = (subject: string): boolean => {
|
||||
return CONFIRMATION_EMAIL_SUBJECT_PATTERN.test(subject)
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue