fedimbed: forgot regex

This commit is contained in:
Cynthia Foxwell 2024-11-08 23:59:29 -07:00
parent ef9d4b4d0e
commit e66ce49da3

View file

@ -17,6 +17,8 @@ const FRIENDLY_USERAGENT = "HiddenPhox/fedimbed (https://gitdab.com/Cynosphere/H
const URLS_REGEX = /(?:\s|^|\]\()(\|\|\s*)?(https?:\/\/[^\s<]+[^<.,:;"'\]|)\s])(\s*\)?\|\||\s*[\S]*?\))?/g; const URLS_REGEX = /(?:\s|^|\]\()(\|\|\s*)?(https?:\/\/[^\s<]+[^<.,:;"'\]|)\s])(\s*\)?\|\||\s*[\S]*?\))?/g;
const SPOILER_REGEX = /(?:\s|^)\|\|([\s\S]+?)\|\|/; const SPOILER_REGEX = /(?:\s|^)\|\|([\s\S]+?)\|\|/;
const BSKY_POST_REGEX = /^\/profile\/([a-z0-9][a-z0-9.-]+[a-z0-9]*)\/post\/([a-z0-9]+)\/?$/i;
const PATH_REGEX = { const PATH_REGEX = {
mastodon: /^\/@(.+?)\/(\d+)\/?/, mastodon: /^\/@(.+?)\/(\d+)\/?/,
mastodon2: /^\/(.+?)\/statuses\/\d+\/?/, mastodon2: /^\/(.+?)\/statuses\/\d+\/?/,
@ -27,6 +29,7 @@ const PATH_REGEX = {
lemmy: /^\/post\/\d+\/?/, lemmy: /^\/post\/\d+\/?/,
honk: /^\/u\/(.+?)\/h\/(.+?)\/?/, honk: /^\/u\/(.+?)\/h\/(.+?)\/?/,
cohost: /^\/[A-Za-z0-9]+\/post\/\d+-[A-Za-z0-9-]+\/?/, cohost: /^\/[A-Za-z0-9]+\/post\/\d+-[A-Za-z0-9-]+\/?/,
bluesky: BSKY_POST_REGEX,
}; };
const PLATFORM_COLORS = { const PLATFORM_COLORS = {
@ -109,7 +112,7 @@ async function signedFetch(url, options) {
key: privKey, key: privKey,
headers: headerNames, headers: headerNames,
authorizationHeaderName: "signature", authorizationHeaderName: "signature",
}, }
); );
options.headers = Object.assign(headers, options.headers ?? {}); options.headers = Object.assign(headers, options.headers ?? {});
@ -117,8 +120,6 @@ async function signedFetch(url, options) {
return await fetch(url, options); return await fetch(url, options);
} }
const BSKY_POST_REGEX = /^\/profile\/([a-z0-9][a-z0-9.\-]+[a-z0-9]*)\/post\/([a-z0-9]+)\/?$/i;
async function blueskyQuoteEmbed(quote, videos) { async function blueskyQuoteEmbed(quote, videos) {
const embeds = []; const embeds = [];
@ -142,9 +143,12 @@ async function blueskyQuoteEmbed(quote, videos) {
switch (embed.$type) { switch (embed.$type) {
case "app.bsky.embed.images#view": { case "app.bsky.embed.images#view": {
embeds.push(...embed.images.map((image) => ({...mainEmbed, image: {url: image.fullsize}}))); embeds.push(...embed.images.map((image) => ({...mainEmbed, image: {url: image.fullsize}})));
break;
} }
case "app.bsky.embed.video#view": { case "app.bsky.embed.video#view": {
const videoUrl = `https://bsky.social/xrpc/com.atproto.sync.getBlob?did=${encodeURIComponent(quote.author.did)}&cid=${embed.cid}`; const videoUrl = `https://bsky.social/xrpc/com.atproto.sync.getBlob?did=${encodeURIComponent(
quote.author.did
)}&cid=${embed.cid}`;
const contentType = await fetch(videoUrl, { const contentType = await fetch(videoUrl, {
method: "HEAD", method: "HEAD",
}).then((res) => res.headers.get("Content-Type")); }).then((res) => res.headers.get("Content-Type"));
@ -152,6 +156,7 @@ async function blueskyQuoteEmbed(quote, videos) {
videos.push({url: videoUrl, desc: embed.alt, type: contentType}); videos.push({url: videoUrl, desc: embed.alt, type: contentType});
embeds.push({...mainEmbed, fields: [{name: "\u200b", value: `[Video Link](${videoUrl})`}]}); embeds.push({...mainEmbed, fields: [{name: "\u200b", value: `[Video Link](${videoUrl})`}]});
break;
} }
default: { default: {
embeds.push(mainEmbed); embeds.push(mainEmbed);
@ -183,7 +188,7 @@ async function bluesky(msg, url, spoiler = false) {
"User-Agent": FRIENDLY_USERAGENT, "User-Agent": FRIENDLY_USERAGENT,
Accept: "application/json", Accept: "application/json",
}, },
}, }
); );
if (!res.ok) throw new Error(`Got non-OK status: ${res.status}`); if (!res.ok) throw new Error(`Got non-OK status: ${res.status}`);
@ -217,9 +222,12 @@ async function bluesky(msg, url, spoiler = false) {
switch (post.embed.$type) { switch (post.embed.$type) {
case "app.bsky.embed.images#view": { case "app.bsky.embed.images#view": {
embeds.push(...post.embed.images.map((image) => ({...mainEmbed, image: {url: image.fullsize}}))); embeds.push(...post.embed.images.map((image) => ({...mainEmbed, image: {url: image.fullsize}})));
break;
} }
case "app.bsky.embed.video#view": { case "app.bsky.embed.video#view": {
const videoUrl = `https://bsky.social/xrpc/com.atproto.sync.getBlob?did=${encodeURIComponent(post.author.did)}&cid=${post.embed.cid}`; const videoUrl = `https://bsky.social/xrpc/com.atproto.sync.getBlob?did=${encodeURIComponent(
post.author.did
)}&cid=${post.embed.cid}`;
const contentType = await fetch(videoUrl, { const contentType = await fetch(videoUrl, {
method: "HEAD", method: "HEAD",
}).then((res) => res.headers.get("Content-Type")); }).then((res) => res.headers.get("Content-Type"));
@ -227,16 +235,20 @@ async function bluesky(msg, url, spoiler = false) {
videos.push({url: videoUrl, desc: post.embed.alt, type: contentType}); videos.push({url: videoUrl, desc: post.embed.alt, type: contentType});
embeds.push({...mainEmbed, fields: [{name: "\u200b", value: `[Video Link](${videoUrl})`}]}); embeds.push({...mainEmbed, fields: [{name: "\u200b", value: `[Video Link](${videoUrl})`}]});
break;
} }
case "app.bsky.embed.record#view": { case "app.bsky.embed.record#view": {
const quote = post.embed.record; const quote = post.embed.record;
embeds.push(mainEmbed, ...(await blueskyQuoteEmbed(quote, videos))); embeds.push(mainEmbed, ...(await blueskyQuoteEmbed(quote, videos)));
break;
} }
case "app.bsky.embed.recordWithMedia#view": { case "app.bsky.embed.recordWithMedia#view": {
if (post.embed.media.$type === "app.bsky.embed.images#view") { if (post.embed.media.$type === "app.bsky.embed.images#view") {
embeds.push(...post.embed.media.images.map((image) => ({...mainEmbed, image: {url: image.fullsize}}))); embeds.push(...post.embed.media.images.map((image) => ({...mainEmbed, image: {url: image.fullsize}})));
} else if (post.embed.media.$type === "app.bsky.embed.video#view") { } else if (post.embed.media.$type === "app.bsky.embed.video#view") {
const videoUrl = `https://bsky.social/xrpc/com.atproto.sync.getBlob?did=${encodeURIComponent(post.author.did)}&cid=${post.embed.media.cid}`; const videoUrl = `https://bsky.social/xrpc/com.atproto.sync.getBlob?did=${encodeURIComponent(
post.author.did
)}&cid=${post.embed.media.cid}`;
const contentType = await fetch(videoUrl, { const contentType = await fetch(videoUrl, {
method: "HEAD", method: "HEAD",
}).then((res) => res.headers.get("Content-Type")); }).then((res) => res.headers.get("Content-Type"));
@ -247,6 +259,7 @@ async function bluesky(msg, url, spoiler = false) {
} }
embeds.push(...(await blueskyQuoteEmbed(post.embed.record.record, videos))); embeds.push(...(await blueskyQuoteEmbed(post.embed.record.record, videos)));
break;
} }
default: { default: {
embeds.push(mainEmbed); embeds.push(mainEmbed);
@ -440,7 +453,7 @@ async function processUrl(msg, url, spoiler = false) {
if (redirUrl) { if (redirUrl) {
logger.verbose( logger.verbose(
"fedimbed", "fedimbed",
`Redirecting "${url}" to "${redirUrl}": ${JSON.stringify(options)}, ${JSON.stringify(headers)}`, `Redirecting "${url}" to "${redirUrl}": ${JSON.stringify(options)}, ${JSON.stringify(headers)}`
); );
let rawPostData2; let rawPostData2;
try { try {
@ -450,7 +463,7 @@ async function processUrl(msg, url, spoiler = false) {
headers: Object.assign(headers, { headers: Object.assign(headers, {
"User-Agent": FRIENDLY_USERAGENT, "User-Agent": FRIENDLY_USERAGENT,
}), }),
}), })
).then((res) => res.text()); ).then((res) => res.text());
} catch (err) { } catch (err) {
logger.error("fedimbed", `Failed to signed fetch "${url}" via MastoAPI, retrying unsigned: ${err}`); logger.error("fedimbed", `Failed to signed fetch "${url}" via MastoAPI, retrying unsigned: ${err}`);
@ -463,7 +476,7 @@ async function processUrl(msg, url, spoiler = false) {
headers: Object.assign(headers, { headers: Object.assign(headers, {
"User-Agent": FRIENDLY_USERAGENT, "User-Agent": FRIENDLY_USERAGENT,
}), }),
}), })
).then((res) => res.text()); ).then((res) => res.text());
} catch (err) { } catch (err) {
logger.error("fedimbed", `Failed to fetch "${url}" via MastoAPI: ${err}`); logger.error("fedimbed", `Failed to fetch "${url}" via MastoAPI: ${err}`);
@ -482,7 +495,7 @@ async function processUrl(msg, url, spoiler = false) {
} else if (postData2.error) { } else if (postData2.error) {
logger.error( logger.error(
"fedimbed", "fedimbed",
`Bailing trying to re-embed "${url}", MastoAPI gave us error: ${JSON.stringify(postData2.error)}`, `Bailing trying to re-embed "${url}", MastoAPI gave us error: ${JSON.stringify(postData2.error)}`
); );
} else { } else {
cw = postData2.spoiler_warning ?? postData2.spoiler_text ?? postData2.cw; cw = postData2.spoiler_warning ?? postData2.spoiler_text ?? postData2.cw;
@ -537,15 +550,15 @@ async function processUrl(msg, url, spoiler = false) {
const type = attachment.type?.toLowerCase(); const type = attachment.type?.toLowerCase();
const fileType = const fileType =
(attachment.pleroma?.mime_type ?? type.indexOf("/") > -1) attachment.pleroma?.mime_type ?? type.indexOf("/") > -1
? type ? type
: type + : type +
"/" + "/" +
((url.match(/\.([a-z0-9]{3,4})$/)?.[0] ?? type == "image") (url.match(/\.([a-z0-9]{3,4})$/)?.[0] ?? type == "image"
? "png" ? "png"
: type == "video" : type == "video"
? "mp4" ? "mp4"
: "mpeg"); : "mpeg");
if (type.startsWith("image")) { if (type.startsWith("image")) {
images.push({ images.push({
url: attachment.url, url: attachment.url,
@ -663,7 +676,7 @@ async function processUrl(msg, url, spoiler = false) {
? type ? type
: type + : type +
"/" + "/" +
((url.match(/\.([a-z0-9]{3,4})$/)?.[0] ?? type == "image") ? "png" : type == "video" ? "mp4" : "mpeg"); (url.match(/\.([a-z0-9]{3,4})$/)?.[0] ?? type == "image" ? "png" : type == "video" ? "mp4" : "mpeg");
if (type.startsWith("image")) { if (type.startsWith("image")) {
images.push({ images.push({
url: attachment.url, url: attachment.url,
@ -876,7 +889,7 @@ async function processUrl(msg, url, spoiler = false) {
const bar = Math.round(percent * 30); const bar = Math.round(percent * 30);
return `**${o.name}** (${o.count}, ${Math.round(percent * 100)}%)\n\`[${"=".repeat(bar)}${" ".repeat( return `**${o.name}** (${o.count}, ${Math.round(percent * 100)}%)\n\`[${"=".repeat(bar)}${" ".repeat(
30 - bar, 30 - bar
)}]\``; )}]\``;
}) })
.join("\n\n") + `\n\n${poll.total} votes \u2022 Ends <t:${Math.floor(poll.end.getTime() / 1000)}:R>`, .join("\n\n") + `\n\n${poll.total} votes \u2022 Ends <t:${Math.floor(poll.end.getTime() / 1000)}:R>`,
@ -1071,8 +1084,8 @@ async function processUrl(msg, url, spoiler = false) {
cw != "" && (images.length > 0 || videos.length > 0 || audios.length > 0) cw != "" && (images.length > 0 || videos.length > 0 || audios.length > 0)
? `:warning: ${cw} || ${url} ||` ? `:warning: ${cw} || ${url} ||`
: spoiler : spoiler
? `|| ${url} ||` ? `|| ${url} ||`
: "", : "",
embeds, embeds,
attachments: files, attachments: files,
allowedMentions: { allowedMentions: {