if the feed has never been fetched, save the last valid item

This commit is contained in:
Hongbo Wu 2023-07-19 13:44:29 +08:00
parent ea849da805
commit 834c4ec2bd

View file

@ -12,6 +12,11 @@ interface RssFeedRequest {
lastFetchedAt: string
}
interface ValidRssFeedItem {
link: string
isoDate: string
}
function isRssFeedRequest(body: any): body is RssFeedRequest {
return (
'subscriptionId' in body && 'feedUrl' in body && 'lastFetchedAt' in body
@ -78,6 +83,35 @@ const sendUpdateSubscriptionMutation = async (
}
}
const createSavingItemTask = async (
userId: string,
feedUrl: string,
item: ValidRssFeedItem
) => {
const input = {
userId,
source: 'rss-feeder',
url: item.link,
saveRequestId: '',
labels: [{ name: 'RSS', color: '#f26522' }],
rssFeedUrl: feedUrl,
savedAt: item.isoDate,
publishedAt: item.isoDate,
}
try {
console.log('Creating task', input.url)
// save page
const task = await createCloudTask(CONTENT_FETCH_URL, input)
console.log('Created task', task)
return !!task
} catch (error) {
console.error('Error while creating task', error)
return false
}
}
dotenv.config()
Sentry.GCPFunction.init({
dsn: process.env.SENTRY_DSN,
@ -121,13 +155,15 @@ export const rssHandler = Sentry.GCPFunction.wrapHttpFunction(
const { feedUrl, subscriptionId, lastFetchedAt } = req.body
console.log('Processing feed', feedUrl, lastFetchedAt)
let lastItemFetchedAt: Date | null = null
let lastValidItem: ValidRssFeedItem | null = null
// fetch feed
const feed = await parser.parseURL(feedUrl)
const newFetchedAt = new Date()
console.log('Fetched feed', feed.title, newFetchedAt)
console.log('Fetched feed', feed.title, new Date())
// save each item in the feed
for await (const item of feed.items) {
for (const item of feed.items) {
console.log('Processing feed item', item.link, item.isoDate)
if (!item.link || !item.isoDate) {
@ -135,6 +171,12 @@ export const rssHandler = Sentry.GCPFunction.wrapHttpFunction(
continue
}
// remember the last valid item
lastValidItem = {
link: item.link,
isoDate: item.isoDate,
}
// skip old items and items that were published before 24h
const publishedAt = new Date(item.isoDate)
if (
@ -145,32 +187,52 @@ export const rssHandler = Sentry.GCPFunction.wrapHttpFunction(
continue
}
const input = {
const created = await createSavingItemTask(
userId,
source: 'rss-feeder',
url: item.link,
saveRequestId: '',
labels: [{ name: 'RSS', color: '#f26522' }],
rssFeedUrl: feedUrl,
savedAt: publishedAt,
publishedAt,
feedUrl,
lastValidItem
)
if (!created) {
console.error('Failed to create task for feed item', item.link)
continue
}
try {
console.log('Creating task', input.url)
// save page
const task = await createCloudTask(CONTENT_FETCH_URL, input)
console.log('Created task', task)
} catch (error) {
console.error('Error while creating task', error)
// remember the last item fetched at
if (!lastItemFetchedAt || publishedAt > lastItemFetchedAt) {
lastItemFetchedAt = publishedAt
}
}
// no items saved
if (!lastItemFetchedAt) {
// the feed has been fetched before, no new valid items found
if (lastFetchedAt || !lastValidItem) {
console.log('No new valid items found')
return res.send('ok')
}
// the feed has never been fetched, save the last valid item
const created = await createSavingItemTask(
userId,
feedUrl,
lastValidItem
)
if (!created) {
console.error(
'Failed to create task for feed item',
lastValidItem.link
)
return res.status(500).send('INTERNAL_SERVER_ERROR')
}
lastItemFetchedAt = new Date(lastValidItem.isoDate)
}
// update subscription lastFetchedAt
const updatedSubscription = await sendUpdateSubscriptionMutation(
userId,
subscriptionId,
newFetchedAt
lastItemFetchedAt
)
console.log('Updated subscription', updatedSubscription)