chore: normalize formatting for workers
This commit is contained in:
parent
2f6cfbe7ae
commit
2cd835d31b
14 changed files with 879 additions and 604 deletions
|
@ -1,138 +1,161 @@
|
|||
import { XMLParser } from 'fast-xml-parser'
|
||||
import { convert } from 'html-to-text'
|
||||
import { createClient } from '@supabase/supabase-js'
|
||||
import { XMLParser } from "fast-xml-parser";
|
||||
import { convert } from "html-to-text";
|
||||
import { createClient } from "@supabase/supabase-js";
|
||||
|
||||
const BASE_URL = 'https://coryd.dev'
|
||||
const BASE_URL = "https://coryd.dev";
|
||||
|
||||
export default {
|
||||
async scheduled(event, env, ctx) {
|
||||
await handleMastodonPost(env)
|
||||
await handleMastodonPost(env);
|
||||
},
|
||||
|
||||
async fetch(request, env, ctx) {
|
||||
if (request.method !== 'POST') return new Response('Method Not Allowed', { status: 405 })
|
||||
if (request.headers.get('x-webhook-token') !== env.WEBHOOK_SECRET) return new Response('Unauthorized', { status: 401 })
|
||||
if (request.method !== "POST")
|
||||
return new Response("Method Not Allowed", { status: 405 });
|
||||
if (request.headers.get("x-webhook-token") !== env.WEBHOOK_SECRET)
|
||||
return new Response("Unauthorized", { status: 401 });
|
||||
|
||||
await handleMastodonPost(env)
|
||||
await handleMastodonPost(env);
|
||||
|
||||
return new Response('Worker triggered by successful build.', { status: 200 })
|
||||
}
|
||||
}
|
||||
return new Response("Worker triggered by successful build.", {
|
||||
status: 200,
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
async function handleMastodonPost(env) {
|
||||
const mastodonApiUrl = 'https://follow.coryd.dev/api/v1/statuses'
|
||||
const accessToken = env.MASTODON_ACCESS_TOKEN
|
||||
const rssFeedUrl = 'https://coryd.dev/feeds/syndication'
|
||||
const supabaseUrl = env.SUPABASE_URL || process.env.SUPABASE_URL
|
||||
const supabaseKey = env.SUPABASE_KEY || process.env.SUPABASE_KEY
|
||||
const supabase = createClient(supabaseUrl, supabaseKey)
|
||||
const mastodonApiUrl = "https://follow.coryd.dev/api/v1/statuses";
|
||||
const accessToken = env.MASTODON_ACCESS_TOKEN;
|
||||
const rssFeedUrl = "https://coryd.dev/feeds/syndication";
|
||||
const supabaseUrl = env.SUPABASE_URL || process.env.SUPABASE_URL;
|
||||
const supabaseKey = env.SUPABASE_KEY || process.env.SUPABASE_KEY;
|
||||
const supabase = createClient(supabaseUrl, supabaseKey);
|
||||
|
||||
try {
|
||||
const latestItems = await fetchRSSFeed(rssFeedUrl)
|
||||
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)
|
||||
const item = latestItems[i];
|
||||
const existingPost = await env.RSS_TO_MASTODON_NAMESPACE.get(item.link);
|
||||
|
||||
if (existingPost) continue
|
||||
if (existingPost) continue;
|
||||
|
||||
const title = item.title
|
||||
const link = item.link
|
||||
const maxLength = 500
|
||||
const title = item.title;
|
||||
const link = item.link;
|
||||
const maxLength = 500;
|
||||
const plainTextDescription = convert(item.description, {
|
||||
wordwrap: false,
|
||||
selectors: [
|
||||
{ selector: 'a', options: { ignoreHref: true } },
|
||||
{ selector: 'h1', options: { uppercase: false } },
|
||||
{ selector: 'h2', options: { uppercase: false } },
|
||||
{ selector: 'h3', options: { uppercase: false } },
|
||||
{ selector: '*', format: 'block' }
|
||||
]
|
||||
})
|
||||
{ selector: "a", options: { ignoreHref: true } },
|
||||
{ selector: "h1", options: { uppercase: false } },
|
||||
{ selector: "h2", options: { uppercase: false } },
|
||||
{ selector: "h3", options: { uppercase: false } },
|
||||
{ selector: "*", format: "block" },
|
||||
],
|
||||
});
|
||||
|
||||
const cleanedDescription = plainTextDescription.replace(/\s+/g, ' ').trim()
|
||||
const content = truncateContent(title, cleanedDescription, link, maxLength)
|
||||
const cleanedDescription = plainTextDescription
|
||||
.replace(/\s+/g, " ")
|
||||
.trim();
|
||||
const content = truncateContent(
|
||||
title,
|
||||
cleanedDescription,
|
||||
link,
|
||||
maxLength
|
||||
);
|
||||
|
||||
const mastodonPostUrl = await postToMastodon(mastodonApiUrl, accessToken, content)
|
||||
const mastodonPostUrl = await postToMastodon(
|
||||
mastodonApiUrl,
|
||||
accessToken,
|
||||
content
|
||||
);
|
||||
|
||||
const timestamp = new Date().toISOString()
|
||||
const timestamp = new Date().toISOString();
|
||||
|
||||
await env.RSS_TO_MASTODON_NAMESPACE.put(link, timestamp)
|
||||
await env.RSS_TO_MASTODON_NAMESPACE.put(link, timestamp);
|
||||
|
||||
if (link.includes('coryd.dev/posts')) {
|
||||
const slug = link.replace(BASE_URL, '')
|
||||
await addMastodonUrlToPost(supabase, slug, mastodonPostUrl)
|
||||
if (link.includes("coryd.dev/posts")) {
|
||||
const slug = link.replace(BASE_URL, "");
|
||||
await addMastodonUrlToPost(supabase, slug, mastodonPostUrl);
|
||||
}
|
||||
|
||||
console.log(`Posted stored URL: ${link}`)
|
||||
console.log(`Posted stored URL: ${link}`);
|
||||
}
|
||||
|
||||
console.log('RSS processed successfully')
|
||||
console.log("RSS processed successfully");
|
||||
} catch (error) {
|
||||
console.error('Error in scheduled event:', error)
|
||||
console.error("Error in scheduled event:", error);
|
||||
}
|
||||
}
|
||||
|
||||
async function addMastodonUrlToPost(supabase, slug, mastodonPostUrl) {
|
||||
const { data, error } = await supabase
|
||||
.from('posts')
|
||||
.from("posts")
|
||||
.update({ mastodon_url: mastodonPostUrl })
|
||||
.eq('slug', slug)
|
||||
.eq("slug", slug);
|
||||
|
||||
if (error) {
|
||||
console.error('Error updating post:', error)
|
||||
console.error("Error updating post:", error);
|
||||
} else {
|
||||
console.log(`Updated post with Mastodon URL: ${mastodonPostUrl}`)
|
||||
console.log(`Updated post with Mastodon URL: ${mastodonPostUrl}`);
|
||||
}
|
||||
}
|
||||
|
||||
function truncateContent(title, description, link, maxLength) {
|
||||
const baseLength = `${title}\n\n${link}`.length
|
||||
const availableSpace = maxLength - baseLength - 4
|
||||
let truncatedDescription = description
|
||||
const baseLength = `${title}\n\n${link}`.length;
|
||||
const availableSpace = maxLength - baseLength - 4;
|
||||
let truncatedDescription = description;
|
||||
|
||||
if (description.length > availableSpace) truncatedDescription = description.substring(0, availableSpace).split(' ').slice(0, -1).join(' ') + '...'
|
||||
if (description.length > availableSpace)
|
||||
truncatedDescription =
|
||||
description
|
||||
.substring(0, availableSpace)
|
||||
.split(" ")
|
||||
.slice(0, -1)
|
||||
.join(" ") + "...";
|
||||
|
||||
return `${title}\n\n${truncatedDescription}\n\n${link}`
|
||||
return `${title}\n\n${truncatedDescription}\n\n${link}`;
|
||||
}
|
||||
|
||||
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
|
||||
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 = []
|
||||
let latestItems = [];
|
||||
|
||||
items.forEach(item => {
|
||||
const title = item.title
|
||||
const link = item.link
|
||||
const description = item.description
|
||||
latestItems.push({ title, link, description })
|
||||
})
|
||||
items.forEach((item) => {
|
||||
const title = item.title;
|
||||
const link = item.link;
|
||||
const description = item.description;
|
||||
latestItems.push({ title, link, description });
|
||||
});
|
||||
|
||||
return latestItems
|
||||
return latestItems;
|
||||
}
|
||||
|
||||
async function postToMastodon(apiUrl, accessToken, content) {
|
||||
const response = await fetch(apiUrl, {
|
||||
method: 'POST',
|
||||
method: "POST",
|
||||
headers: {
|
||||
'Authorization': `Bearer ${accessToken}`,
|
||||
'Content-Type': 'application/json',
|
||||
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}`)
|
||||
const errorText = await response.text();
|
||||
throw new Error(
|
||||
`Error posting to Mastodon: ${response.statusText} - ${errorText}`
|
||||
);
|
||||
}
|
||||
|
||||
const responseData = await response.json()
|
||||
const responseData = await response.json();
|
||||
|
||||
console.log('Posted to Mastodon successfully.')
|
||||
console.log("Posted to Mastodon successfully.");
|
||||
|
||||
return responseData.url
|
||||
}
|
||||
return responseData.url;
|
||||
}
|
||||
|
|
Reference in a new issue