Save url if the email subject is a parsable url

This commit is contained in:
Hongbo Wu 2023-04-24 12:54:23 +08:00
parent bce7afde50
commit 69968e5288
4 changed files with 76 additions and 26 deletions

View file

@ -1,14 +1,19 @@
import express from 'express'
import { readPushSubscription } from '../../datalayer/pubsub'
import {
createPubSubClient,
readPushSubscription,
} from '../../datalayer/pubsub'
import {
getNewsletterEmail,
updateConfirmationCode,
} from '../../services/newsletters'
import { updateReceivedEmail } from '../../services/received_emails'
import {
NewsletterMessage,
saveNewsletterEmail,
} from '../../services/save_newsletter_email'
import { updateReceivedEmail } from '../../services/received_emails'
import { saveUrlFromEmail } from '../../services/save_url'
import { isUrl } from '../../utils/helpers'
interface SetConfirmationCodeMessage {
emailAddress: string
@ -102,27 +107,41 @@ export function newsletterServiceRouter() {
const newsletterEmail = await getNewsletterEmail(data.email)
if (!newsletterEmail) {
console.log('newsletter email not found', data.email)
return false
return res.status(200).send('Not Found')
}
const result = await saveNewsletterEmail(data, newsletterEmail)
if (!result) {
console.log(
'Error creating newsletter link from data',
data.email,
const saveCtx = {
pubsub: createPubSubClient(),
uid: newsletterEmail.user.id,
}
if (isUrl(data.title)) {
// save url if the title is a parsable url
const result = await saveUrlFromEmail(
saveCtx,
data.title,
data.author
data.receivedEmailId
)
if (!result) {
return res.status(500).send('Error saving url from email')
}
} else {
// save newsletter instead
const result = await saveNewsletterEmail(data, newsletterEmail, saveCtx)
if (!result) {
console.log(
'Error creating newsletter link from data',
data.email,
data.title,
data.author
)
res.status(500).send('Error creating newsletter link')
return
return res.status(500).send('Error creating newsletter link')
}
}
// update received email type
await updateReceivedEmail(data.receivedEmailId, 'article')
// We always send 200 if it was a valid message
// because we don't want the
res.status(200).send('newsletter created')
} catch (e) {
console.log(e)

View file

@ -10,7 +10,6 @@ import { analytics } from '../utils/analytics'
import { isBase64Image } from '../utils/helpers'
import { fetchFavicon } from '../utils/parser'
import { addLabelToPage } from './labels'
import { updateReceivedEmail } from './received_emails'
import { SaveContext, saveEmail, SaveEmailInput } from './save_email'
import { saveSubscription } from './subscriptions'
@ -63,9 +62,6 @@ export const saveNewsletterEmail = async (
return false
}
// update received email type
await updateReceivedEmail(data.receivedEmailId, 'article')
if (!page.siteIcon || isBase64Image(page.siteIcon)) {
// fetch favicon if not already set or is a base64 image
const favicon = await fetchFavicon(page.url)

View file

@ -1,20 +1,20 @@
import { PubsubClient } from '../datalayer/pubsub'
import { UserData } from '../datalayer/user/model'
import { ArticleSavingRequestStatus } from '../elastic/types'
import { User } from '../entity/user'
import { getRepository } from '../entity/utils'
import { homePageURL } from '../env'
import { SaveErrorCode, SaveResult, SaveUrlInput } from '../generated/graphql'
import { DataModels } from '../resolvers/types'
import { createPageSaveRequest } from './create_page_save_request'
import { ArticleSavingRequestStatus } from '../elastic/types'
import { createLabels } from './labels'
type SaveContext = {
interface SaveContext {
pubsub: PubsubClient
models: DataModels
uid: string
}
export const saveUrl = async (
ctx: SaveContext,
saver: UserData,
user: User,
input: SaveUrlInput
): Promise<SaveResult> => {
try {
@ -23,28 +23,54 @@ export const saveUrl = async (
input.state === ArticleSavingRequestStatus.Archived ? new Date() : null
// add labels to page
const labels = input.labels
? await createLabels({ ...ctx, uid: saver.id }, input.labels)
? await createLabels({ ...ctx, uid: ctx.uid }, input.labels)
: undefined
const pageSaveRequest = await createPageSaveRequest({
userId: saver.id,
userId: ctx.uid,
url: input.url,
pubsub: ctx.pubsub,
articleSavingRequestId: input.clientRequestId,
archivedAt,
labels,
user,
})
return {
clientRequestId: pageSaveRequest.id,
url: `${homePageURL()}/${saver.profile.username}/links/${
url: `${homePageURL()}/${user.profile.username}/links/${
pageSaveRequest.id
}`,
}
} catch (error) {
console.log('error enqueuing request', error)
return {
__typename: 'SaveError',
errorCodes: [SaveErrorCode.Unknown],
}
}
}
export const saveUrlFromEmail = async (
ctx: SaveContext,
url: string,
clientRequestId: string
): Promise<boolean> => {
const user = await getRepository(User).findOneBy({
id: ctx.uid,
})
if (!user) {
return false
}
const result = await saveUrl(ctx, user, {
url,
clientRequestId,
source: 'email',
})
if (result.__typename === 'SaveError') {
return false
}
return true
}

View file

@ -289,3 +289,12 @@ export const generateRandomColor = (): string => {
export const unescapeHtml = (html: string): string => {
return _.unescape(html)
}
export const isUrl = (str: string): boolean => {
try {
new URL(str)
return true
} catch {
return false
}
}