feat: rss to mastodon worker
modified: src/includes/base.liquid
This commit is contained in:
parent
a80d5897e2
commit
9f90a264be
8 changed files with 313 additions and 297 deletions
82
workers/mastodon/index.js
Normal file
82
workers/mastodon/index.js
Normal file
|
@ -0,0 +1,82 @@
|
|||
import { XMLParser } from 'fast-xml-parser'
|
||||
import { convert } from 'html-to-text'
|
||||
|
||||
export default {
|
||||
async scheduled(event, env, ctx) {
|
||||
await handleScheduledEvent(env)
|
||||
},
|
||||
|
||||
async fetch(request, env, ctx) {
|
||||
return Response.redirect('https://coryd.dev/feeds', 301)
|
||||
}
|
||||
}
|
||||
|
||||
async function handleScheduledEvent(env) {
|
||||
const mastodonApiUrl = 'https://social.lol/api/v1/statuses'
|
||||
const accessToken = env.MASTODON_ACCESS_TOKEN
|
||||
const rssFeedUrl = 'https://coryd.dev/feeds/all'
|
||||
|
||||
try {
|
||||
const latestItems = await fetchRSSFeed(rssFeedUrl)
|
||||
|
||||
for (let i = latestItems.length - 1; i >= 0; i--) {
|
||||
const item = latestItems[i]
|
||||
const existingPost = await env.RSS_TO_MASTODON_NAMESPACE.get(item.link)
|
||||
|
||||
if (existingPost) continue
|
||||
|
||||
const plainTextDescription = convert(item.description, {
|
||||
wordwrap: 150,
|
||||
})
|
||||
|
||||
const content = `${item.title}\n\n${plainTextDescription}\n\n${item.link}`
|
||||
await postToMastodon(mastodonApiUrl, accessToken, content)
|
||||
|
||||
const timestamp = new Date().toISOString()
|
||||
await env.RSS_TO_MASTODON_NAMESPACE.put(item.link, timestamp)
|
||||
|
||||
console.log(`Posted and stored URL: ${item.link}`)
|
||||
}
|
||||
|
||||
console.log('RSS feed processed successfully')
|
||||
} catch (error) {
|
||||
console.error('Error in scheduled event:', error)
|
||||
}
|
||||
}
|
||||
|
||||
async function fetchRSSFeed(rssFeedUrl) {
|
||||
const response = await fetch(rssFeedUrl)
|
||||
const rssText = await response.text()
|
||||
const parser = new XMLParser()
|
||||
const rssData = parser.parse(rssText)
|
||||
const items = rssData.rss.channel.item
|
||||
|
||||
let latestItems = []
|
||||
|
||||
items.forEach(item => {
|
||||
const title = item.title
|
||||
const link = item.link
|
||||
const description = item.description
|
||||
latestItems.push({ title, link, description })
|
||||
})
|
||||
|
||||
return latestItems
|
||||
}
|
||||
|
||||
async function postToMastodon(apiUrl, accessToken, content) {
|
||||
const response = await fetch(apiUrl, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Authorization': `Bearer ${accessToken}`,
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({ status: content })
|
||||
})
|
||||
|
||||
if (!response.ok) {
|
||||
const errorText = await response.text()
|
||||
throw new Error(`Error posting to Mastodon: ${response.statusText} - ${errorText}`)
|
||||
}
|
||||
|
||||
console.log('Posted to Mastodon successfully!')
|
||||
}
|
21
workers/mastodon/wrangler.template.toml
Normal file
21
workers/mastodon/wrangler.template.toml
Normal file
|
@ -0,0 +1,21 @@
|
|||
name = "rss-to-mastodon-worker"
|
||||
main = "./index.js"
|
||||
compatibility_date = "2023-01-01"
|
||||
|
||||
account_id = "${CF_ACCOUNT_ID}"
|
||||
workers_dev = true
|
||||
|
||||
[observability]
|
||||
enabled = true
|
||||
|
||||
[[kv_namespaces]]
|
||||
binding = "RSS_TO_MASTODON_NAMESPACE"
|
||||
id = "${RSS_TO_MASTODON_KV_NAMESPACE_ID}"
|
||||
|
||||
[env.production]
|
||||
name = "rss-to-mastodon-worker-production"
|
||||
triggers = { crons = ["0 * * * *"] }
|
||||
|
||||
[[env.production.kv_namespaces]]
|
||||
binding = "RSS_TO_MASTODON_NAMESPACE"
|
||||
id = "${RSS_TO_MASTODON_KV_NAMESPACE_ID}"
|
Reference in a new issue