fedimbed: attempt to components v2 fedi posts
This commit is contained in:
parent
15f709ed13
commit
fd98ba3667
1 changed files with 184 additions and 444 deletions
|
@ -1,5 +1,3 @@
|
|||
const {Message} = require("@projectdysnomia/dysnomia");
|
||||
|
||||
const fs = require("node:fs");
|
||||
const httpSignature = require("@peertube/http-signature");
|
||||
const {XMLParser} = require("fast-xml-parser");
|
||||
|
@ -11,7 +9,6 @@ const InteractionCommand = require("#lib/interactionCommand.js");
|
|||
|
||||
const {Icons} = require("#util/constants.js");
|
||||
const {MessageFlags, ApplicationCommandOptionTypes, Permissions} = require("#util/dconstants.js");
|
||||
const {getUploadLimit} = require("#util/misc.js");
|
||||
const {htmlToMarkdown} = require("#util/html.js");
|
||||
|
||||
const FRIENDLY_USERAGENT =
|
||||
|
@ -715,7 +712,7 @@ async function bluesky(msg, url, spoiler = false) {
|
|||
return {
|
||||
response: {
|
||||
flags: 1 << 15,
|
||||
components: [warnings.length > 0 ? warningText : false, container].filter((x) => !!x),
|
||||
components: [warnings.length > 0 && warningText, container].filter((x) => !!x),
|
||||
allowedMentions: {
|
||||
repliedUser: false,
|
||||
},
|
||||
|
@ -910,18 +907,20 @@ async function getStatsAS(post) {
|
|||
}
|
||||
|
||||
const stats = [];
|
||||
if (replyCount > 0) stats.push(`\u21a9 ${statsFormatter.format(replyCount)}`);
|
||||
if (post.shares?.totalItems ?? 0 > 0) stats.push(`\ud83d\udd01 ${statsFormatter.format(post.shares.totalItems)}`);
|
||||
if (post.likes?.totalItems ?? 0 > 0) stats.push(`\u2665 ${statsFormatter.format(post.likes.totalItems)}`);
|
||||
if (replyCount > 0) stats.push(`${Icons.fedimbed.reply} ${statsFormatter.format(replyCount)}`);
|
||||
if (post.shares?.totalItems ?? 0 > 0)
|
||||
stats.push(`${Icons.fedimbed.repost} ${statsFormatter.format(post.shares.totalItems)}`);
|
||||
if (post.likes?.totalItems ?? 0 > 0)
|
||||
stats.push(`${Icons.fedimbed.like} ${statsFormatter.format(post.likes.totalItems)}`);
|
||||
|
||||
return stats.join("\u3000");
|
||||
}
|
||||
|
||||
function getStatsMasto(post) {
|
||||
const stats = [];
|
||||
if (post.replies_count > 0) stats.push(`\u21a9 ${statsFormatter.format(post.replies_count)}`);
|
||||
if (post.reblogs_count > 0) stats.push(`\ud83d\udd01 ${statsFormatter.format(post.reblogs_count)}`);
|
||||
if (post.favourites_count > 0) stats.push(`\u2665 ${statsFormatter.format(post.favourites_count)}`);
|
||||
if (post.replies_count > 0) stats.push(`${Icons.fedimbed.reply} ${statsFormatter.format(post.replies_count)}`);
|
||||
if (post.reblogs_count > 0) stats.push(`${Icons.fedimbed.repost} ${statsFormatter.format(post.reblogs_count)}`);
|
||||
if (post.favourites_count > 0) stats.push(`${Icons.fedimbed.like} ${statsFormatter.format(post.favourites_count)}`);
|
||||
|
||||
return stats.join("\u3000");
|
||||
}
|
||||
|
@ -1061,58 +1060,23 @@ async function processUrl(msg, url, spoiler = false, command = false) {
|
|||
const attachments = postData.media_attachments ?? postData.files;
|
||||
if (attachments) {
|
||||
for (const attachment of attachments) {
|
||||
const contentType = await fetch(attachment.url, {
|
||||
method: "HEAD",
|
||||
}).then((res) => res.headers.get("Content-Type"));
|
||||
const type = attachment.type?.toLowerCase();
|
||||
|
||||
if (contentType) {
|
||||
if (contentType.startsWith("image/")) {
|
||||
images.push({
|
||||
url: attachment.url,
|
||||
desc: attachment.description ?? attachment.comment,
|
||||
type: contentType,
|
||||
});
|
||||
} else if (contentType.startsWith("video/")) {
|
||||
videos.push({
|
||||
url: attachment.url,
|
||||
desc: attachment.description ?? attachment.comment,
|
||||
type: contentType,
|
||||
});
|
||||
} else if (contentType.startsWith("audio/")) {
|
||||
audios.push({
|
||||
url: attachment.url,
|
||||
desc: attachment.description ?? attachment.comment,
|
||||
type: contentType,
|
||||
});
|
||||
}
|
||||
} else {
|
||||
const type = attachment.type?.toLowerCase();
|
||||
|
||||
const fileType =
|
||||
attachment.pleroma?.mime_type ?? type.indexOf("/") > -1
|
||||
? type
|
||||
: type +
|
||||
"/" +
|
||||
(url.match(/\.([a-z0-9]{3,4})$/)?.[0] ?? type == "image" ? "png" : type == "video" ? "mp4" : "mpeg");
|
||||
if (type.startsWith("image")) {
|
||||
images.push({
|
||||
url: attachment.url,
|
||||
desc: attachment.description ?? attachment.comment,
|
||||
type: fileType,
|
||||
});
|
||||
} else if (type.startsWith("video")) {
|
||||
videos.push({
|
||||
url: attachment.url,
|
||||
desc: attachment.description ?? attachment.comment,
|
||||
type: fileType,
|
||||
});
|
||||
} else if (type.startsWith("audio")) {
|
||||
audios.push({
|
||||
url: attachment.url,
|
||||
desc: attachment.description ?? attachment.comment,
|
||||
type: fileType,
|
||||
});
|
||||
}
|
||||
if (type.startsWith("image")) {
|
||||
images.push({
|
||||
media: {url: attachment.url},
|
||||
description: attachment.description ?? attachment.comment,
|
||||
});
|
||||
} else if (type.startsWith("video")) {
|
||||
videos.push({
|
||||
media: {url: attachment.url},
|
||||
description: attachment.description ?? attachment.comment,
|
||||
});
|
||||
} else if (type.startsWith("audio")) {
|
||||
audios.push({
|
||||
url: attachment.url,
|
||||
description: attachment.description ?? attachment.comment,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1156,19 +1120,19 @@ async function processUrl(msg, url, spoiler = false, command = false) {
|
|||
|
||||
if (postData.inReplyTo) {
|
||||
contextUrl = postData.inReplyTo;
|
||||
context = "Replying to: ";
|
||||
context = `-# ${Icons.fedimbed.reply} Replying to: `;
|
||||
|
||||
const replyData = await fetchPost(postData.inReplyTo, platform);
|
||||
if (replyData) {
|
||||
if (replyData._fedimbed_mastoapi) {
|
||||
context += `${
|
||||
context += `[${
|
||||
replyData.account?.display_name ??
|
||||
replyData.account?.username ??
|
||||
replyData.user?.name ??
|
||||
replyData.user?.username
|
||||
} (@${
|
||||
replyData.account?.fqn ?? `${replyData.account?.username ?? replyData.user?.username}@${urlObj.hostname}`
|
||||
})`;
|
||||
})](${contextUrl})`;
|
||||
} else {
|
||||
const authorData = await signedFetch(replyData.actor ?? replyData.attributedTo, {
|
||||
headers: {
|
||||
|
@ -1183,13 +1147,13 @@ async function processUrl(msg, url, spoiler = false, command = false) {
|
|||
|
||||
if (authorData) {
|
||||
const authorUrlObj = new URL(authorData.url ?? authorData.id);
|
||||
context += `${authorData.name} (${authorData.preferredUsername}@${authorUrlObj.hostname})`;
|
||||
context += `[${authorData.name} (${authorData.preferredUsername}@${authorUrlObj.hostname})](${contextUrl})`;
|
||||
} else {
|
||||
// bootleg author
|
||||
const authorUrl = replyData.actor ?? replyData.attributedTo;
|
||||
const authorUrlObj = new URL(authorUrl);
|
||||
const name = authorUrlObj.pathname.substring(authorUrlObj.pathname.lastIndexOf("/") + 1);
|
||||
context += `${name}@${authorUrlObj.hostname}`;
|
||||
context += `[${name}@${authorUrlObj.hostname}](${authorUrl})`;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -1201,36 +1165,18 @@ async function processUrl(msg, url, spoiler = false, command = false) {
|
|||
// NB: everyone else except gts doesnt follow the spec (they should be using attachments)
|
||||
const attachments = Array.isArray(postData.attachment) ? postData.attachment : [postData.attachment];
|
||||
for (const attachment of attachments) {
|
||||
if (attachment.mediaType) {
|
||||
if (attachment.mediaType.startsWith("video/")) {
|
||||
videos.push({
|
||||
url: attachment.url,
|
||||
desc: attachment.name ?? attachment.description ?? attachment.comment,
|
||||
type: attachment.mediaType,
|
||||
});
|
||||
} else if (attachment.mediaType.startsWith("image/")) {
|
||||
images.push({
|
||||
url: attachment.url,
|
||||
desc: attachment.name ?? attachment.description ?? attachment.comment,
|
||||
type: attachment.mediaType,
|
||||
});
|
||||
} else if (attachment.mediaType.startsWith("audio/")) {
|
||||
audios.push({
|
||||
url: attachment.url,
|
||||
desc: attachment.name ?? attachment.description ?? attachment.comment,
|
||||
type: attachment.mediaType,
|
||||
});
|
||||
}
|
||||
} else if (attachment.url) {
|
||||
if (attachment.url) {
|
||||
const type = attachment.type?.toLowerCase();
|
||||
|
||||
let attUrl = attachment.url;
|
||||
if (Array.isArray(attachment.url)) {
|
||||
switch (attachment.type) {
|
||||
case "Image": {
|
||||
switch (type) {
|
||||
case "image": {
|
||||
const newUrl = attachment.url.find((a) => a.mediaType?.startsWith("image/"))?.href;
|
||||
if (newUrl) attUrl = newUrl;
|
||||
break;
|
||||
}
|
||||
case "Video": {
|
||||
case "video": {
|
||||
const newUrl = attachment.url.find((a) => a.mediaType?.startsWith("video/"))?.href;
|
||||
if (newUrl) attUrl = newUrl;
|
||||
break;
|
||||
|
@ -1240,60 +1186,21 @@ async function processUrl(msg, url, spoiler = false, command = false) {
|
|||
}
|
||||
}
|
||||
|
||||
let contentType;
|
||||
if (attUrl != null)
|
||||
contentType = await fetch(attUrl, {
|
||||
method: "HEAD",
|
||||
}).then((res) => res.headers.get("Content-Type"));
|
||||
|
||||
if (contentType) {
|
||||
if (contentType.startsWith("image/")) {
|
||||
images.push({
|
||||
url: attUrl,
|
||||
desc: attachment.name ?? attachment.description ?? attachment.comment,
|
||||
type: contentType,
|
||||
});
|
||||
} else if (contentType.startsWith("video/")) {
|
||||
videos.push({
|
||||
url: attUrl,
|
||||
desc: attachment.name ?? attachment.description ?? attachment.comment,
|
||||
type: contentType,
|
||||
});
|
||||
} else if (contentType.startsWith("audio/")) {
|
||||
audios.push({
|
||||
url: attUrl,
|
||||
desc: attachment.name ?? attachment.description ?? attachment.comment,
|
||||
type: contentType,
|
||||
});
|
||||
}
|
||||
} else {
|
||||
const type = attachment.type?.toLowerCase();
|
||||
|
||||
const fileType =
|
||||
type.indexOf("/") > -1
|
||||
? type
|
||||
: type +
|
||||
"/" +
|
||||
(url.match(/\.([a-z0-9]{3,4})$/)?.[0] ?? type == "image" ? "png" : type == "video" ? "mp4" : "mpeg");
|
||||
if (type.startsWith("image")) {
|
||||
images.push({
|
||||
url: attUrl,
|
||||
desc: attachment.name ?? attachment.description ?? attachment.comment,
|
||||
type: fileType,
|
||||
});
|
||||
} else if (type.startsWith("video")) {
|
||||
videos.push({
|
||||
url: attUrl,
|
||||
desc: attachment.name ?? attachment.description ?? attachment.comment,
|
||||
type: fileType,
|
||||
});
|
||||
} else if (type.startsWith("audio")) {
|
||||
audios.push({
|
||||
url: attUrl,
|
||||
desc: attachment.name ?? attachment.description ?? attachment.comment,
|
||||
type: fileType,
|
||||
});
|
||||
}
|
||||
if (type.startsWith("image")) {
|
||||
images.push({
|
||||
media: {url: attUrl},
|
||||
description: attachment.name ?? attachment.description ?? attachment.comment,
|
||||
});
|
||||
} else if (type.startsWith("video")) {
|
||||
videos.push({
|
||||
media: {url: attUrl},
|
||||
description: attachment.name ?? attachment.description ?? attachment.comment,
|
||||
});
|
||||
} else if (type.startsWith("audio")) {
|
||||
audios.push({
|
||||
url: attUrl,
|
||||
description: attachment.name ?? attachment.description ?? attachment.comment,
|
||||
});
|
||||
}
|
||||
} else {
|
||||
logger.warn("fedimbed", `Unhandled attachment structure! ${JSON.stringify(attachment)}`);
|
||||
|
@ -1306,14 +1213,8 @@ async function processUrl(msg, url, spoiler = false, command = false) {
|
|||
}
|
||||
|
||||
if (postData.image?.url) {
|
||||
const imageUrl = new URL(postData.image.url);
|
||||
const contentType = await fetch(postData.image.url, {
|
||||
method: "HEAD",
|
||||
}).then((res) => res.headers.get("Content-Type"));
|
||||
images.push({
|
||||
url: postData.image.url,
|
||||
desc: "",
|
||||
type: contentType ?? "image/" + imageUrl.pathname.substring(imageUrl.pathname.lastIndexOf(".") + 1),
|
||||
media: {url: postData.image.url},
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -1328,7 +1229,7 @@ async function processUrl(msg, url, spoiler = false, command = false) {
|
|||
})
|
||||
.then((res) => res.json())
|
||||
.catch((err) => {
|
||||
/*if (platform !== "cohost")*/ logger.error("fedimbed", `Failed to get author for "${url}": ${err}`);
|
||||
logger.error("fedimbed", `Failed to get author for "${url}": ${err}`);
|
||||
});
|
||||
|
||||
if (authorData) {
|
||||
|
@ -1394,31 +1295,15 @@ async function processUrl(msg, url, spoiler = false, command = false) {
|
|||
|
||||
let desc = "";
|
||||
let MAX_LENGTH = 3999;
|
||||
if ((cw != "" || sensitive) && images.length == 0 && videos.length == 0 && audios.length == 0) {
|
||||
if (cw != "" || sensitive) {
|
||||
const ors = content.split("||");
|
||||
desc += `||${content.replaceAll("||", "|\u200b|")}||`;
|
||||
MAX_LENGTH -= ors.length - 1;
|
||||
MAX_LENGTH -= 4;
|
||||
|
||||
if (cw != "") {
|
||||
desc = "\u26a0 " + cw + "\n\n" + desc;
|
||||
MAX_LENGTH -= 4 - cw.length;
|
||||
}
|
||||
} else {
|
||||
desc = content;
|
||||
}
|
||||
|
||||
if (desc.length > MAX_LENGTH) {
|
||||
if (desc.endsWith("||")) {
|
||||
desc = desc.substring(0, MAX_LENGTH - 2);
|
||||
desc += "\u2026||";
|
||||
} else {
|
||||
desc = desc.substring(0, MAX_LENGTH) + "\u2026";
|
||||
}
|
||||
}
|
||||
|
||||
let user = author.name ? `${author.name} (${author.handle})` : author.handle;
|
||||
|
||||
const crawled = await getCrawledData(url, color, platformName);
|
||||
if (!color && crawled?.color) {
|
||||
color = crawled.color;
|
||||
|
@ -1429,328 +1314,184 @@ async function processUrl(msg, url, spoiler = false, command = false) {
|
|||
|
||||
if (platformName.includes("Nitter") && platformName.includes(" \u2022 ")) {
|
||||
const [nn, ns] = platformName.split(" \u2022 ");
|
||||
stats = ns;
|
||||
stats = ns
|
||||
.replace("\u21a9", Icons.fedimbed.reply)
|
||||
.replace("\ud83d\udd01", Icons.fedimbed.repost)
|
||||
.replace("\u2198", Icons.fedimbed.quote)
|
||||
.replace("\u2665", Icons.fedimbed.like)
|
||||
.replace("\ud83d\udd16", Icons.fedimbed.bookmark)
|
||||
.replace("\ud83d\udc41", Icons.fedimbed.views)
|
||||
.replaceAll(/ <:i:/g, "\u3000<:i:");
|
||||
platformName = nn;
|
||||
}
|
||||
|
||||
if (platformName == "Nitter") {
|
||||
const newHandle = author.handle.split("@")[0];
|
||||
user = `${author.name} (@${newHandle})`;
|
||||
author.handle = "@" + newHandle;
|
||||
|
||||
if (context) {
|
||||
const contextHandle = context.match(/\(([^@]+?@.+?)\)/)?.[1];
|
||||
if (contextHandle) {
|
||||
const newContextHandle = "@" + contextHandle.split("@")[0];
|
||||
context = context.replace(contextHandle, newContextHandle);
|
||||
const newContextHandle = contextHandle.split("@")[0];
|
||||
context = context.replace(contextHandle, "@" + newContextHandle);
|
||||
context = context.replace(/: (.+?)$/, `: [$1](${contextUrl})`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const baseEmbed = {
|
||||
color,
|
||||
url,
|
||||
timestamp,
|
||||
description: desc,
|
||||
title: title ?? user,
|
||||
author: title
|
||||
? {
|
||||
name: user,
|
||||
url: author.url,
|
||||
}
|
||||
: context
|
||||
? {
|
||||
name: context,
|
||||
url: contextUrl,
|
||||
icon_url: "https://cdn.discordapp.com/emojis/1308640078825787412.png",
|
||||
}
|
||||
: null,
|
||||
footer: {
|
||||
icon_url: crawled?.icon,
|
||||
text: (stats != null && stats != "" ? stats + "\n" : "") + platformName,
|
||||
},
|
||||
thumbnail: {
|
||||
url: author.avatar,
|
||||
},
|
||||
fields: [],
|
||||
const warningText = {
|
||||
type: 10,
|
||||
content: `## ${cw}`,
|
||||
};
|
||||
if (images.length > 0) {
|
||||
if (images.length > 1) {
|
||||
const links = images.map((attachment, index) => `[Image ${index + 1}](${attachment.url})`).join("\u3000\u3000");
|
||||
|
||||
if (links.length <= 1024)
|
||||
baseEmbed.fields.push({
|
||||
name: "Images",
|
||||
value: links,
|
||||
inline: true,
|
||||
});
|
||||
const container = {
|
||||
type: 17,
|
||||
accent_color: color,
|
||||
components: [],
|
||||
spoiler,
|
||||
};
|
||||
|
||||
let headerContent = `${author.name ? `## ${author.name}\n` : ""}-# [${author.handle}](${author.url})`;
|
||||
|
||||
if (title) headerContent += "\n### " + title;
|
||||
|
||||
MAX_LENGTH -= headerContent.length + 1;
|
||||
|
||||
if (desc.length > MAX_LENGTH) {
|
||||
if (desc.endsWith("||")) {
|
||||
desc = desc.substring(0, MAX_LENGTH - 2);
|
||||
desc += "\u2026||";
|
||||
} else {
|
||||
baseEmbed.fields.push({
|
||||
name: "Image",
|
||||
value: `[Click for image](${images[0].url})`,
|
||||
inline: true,
|
||||
});
|
||||
}
|
||||
}
|
||||
if (videos.length > 0) {
|
||||
if (videos.length > 1) {
|
||||
baseEmbed.fields.push({
|
||||
name: "Videos",
|
||||
value: videos.map((attachment, index) => `[Video ${index + 1}](${attachment.url})`).join("\u3000\u3000"),
|
||||
inline: true,
|
||||
});
|
||||
} else {
|
||||
baseEmbed.fields.push({
|
||||
name: "Video",
|
||||
value: `[Click for video](${videos[0].url})`,
|
||||
inline: true,
|
||||
});
|
||||
}
|
||||
}
|
||||
if (audios.length > 0) {
|
||||
if (audios.length > 1) {
|
||||
baseEmbed.fields.push({
|
||||
name: "Audios",
|
||||
value: audios.map((attachment, index) => `[Audio ${index + 1}](${attachment.url})`).join("\u3000\u3000"),
|
||||
inline: true,
|
||||
});
|
||||
} else {
|
||||
baseEmbed.fields.push({
|
||||
name: "Audio",
|
||||
value: `[Click for audio](${audios[0].url})`,
|
||||
inline: true,
|
||||
});
|
||||
desc = desc.substring(0, MAX_LENGTH) + "\u2026";
|
||||
}
|
||||
}
|
||||
headerContent += "\n" + desc;
|
||||
|
||||
const header = [
|
||||
context && {
|
||||
type: 10,
|
||||
content: context,
|
||||
},
|
||||
{
|
||||
type: 9,
|
||||
components: [
|
||||
{
|
||||
type: 10,
|
||||
content: headerContent,
|
||||
},
|
||||
],
|
||||
accessory: {
|
||||
type: 11,
|
||||
media: {
|
||||
url: author.avatar,
|
||||
},
|
||||
},
|
||||
},
|
||||
].filter((x) => !!x);
|
||||
container.components.push(...header);
|
||||
|
||||
if (poll) {
|
||||
const pollTime = poll.end.getTime();
|
||||
const now = Date.now();
|
||||
baseEmbed.fields.push({
|
||||
name: "Poll",
|
||||
value:
|
||||
container.components.push({
|
||||
type: 10,
|
||||
content:
|
||||
poll.options
|
||||
.map((o) => {
|
||||
const percent = o.count / poll.total;
|
||||
const bar = Math.round(percent * 32);
|
||||
|
||||
return `**${o.name}** (${numberFormatter.format(o.count)}, ${Math.round(
|
||||
return `> **${o.name}** (${numberFormatter.format(o.count)}, ${Math.round(
|
||||
percent * 100
|
||||
)}%)\n\`${"\u2588".repeat(bar)}${" ".repeat(32 - bar)}\``;
|
||||
)}%)> \n\`${"\u2588".repeat(bar)}${" ".repeat(32 - bar)}\``;
|
||||
})
|
||||
.join("\n\n") +
|
||||
`\n\n${poll.total} votes \u2022 End${pollTime > now ? "s" : "ed"} <t:${Math.floor(pollTime / 1000)}:R>`,
|
||||
.join("> \n> \n") +
|
||||
`> \n> \n${poll.total} votes \u2022 End${pollTime > now ? "s" : "ed"} <t:${Math.floor(pollTime / 1000)}:R>`,
|
||||
});
|
||||
}
|
||||
|
||||
let sendWait = false;
|
||||
if (videos.length > 0 || audios.length > 0 || images.length > 4) {
|
||||
sendWait = true;
|
||||
if (msg instanceof Message) await msg.addReaction("\uD83D\uDCE4");
|
||||
const footer = {
|
||||
type: 9,
|
||||
components: [
|
||||
{
|
||||
type: 10,
|
||||
content: `-# ${stats}\n${platformName} \u2022 <t:${Math.floor(new Date(timestamp).getTime() / 1000)}:F>`,
|
||||
},
|
||||
],
|
||||
accessory: {
|
||||
type: 2,
|
||||
style: 5,
|
||||
label: "View Post",
|
||||
url,
|
||||
},
|
||||
};
|
||||
|
||||
for (const image in images) {
|
||||
if (image.description?.length === 0) image.description = null;
|
||||
}
|
||||
|
||||
const embeds = [];
|
||||
const files = [];
|
||||
|
||||
const guild = msg.channel?.guild ?? (msg.guildID ? hf.bot.guilds.get(msg.guildID) : false);
|
||||
|
||||
let limit = getUploadLimit(guild);
|
||||
if (msg.attachmentSizeLimit != null) limit = msg.attachmentSizeLimit;
|
||||
|
||||
if (images.length > 0) {
|
||||
if (images.length <= 4) {
|
||||
for (const attachment of images) {
|
||||
const embed = Object.assign({}, baseEmbed);
|
||||
embed.image = {
|
||||
url: attachment.url,
|
||||
description: attachment.desc,
|
||||
};
|
||||
embeds.push(embed);
|
||||
}
|
||||
} else if (images.length > 4 && images.length <= 10) {
|
||||
for (const attachment of images) {
|
||||
const size = await fetch(attachment.url, {
|
||||
method: "HEAD",
|
||||
headers: {
|
||||
"User-Agent": FRIENDLY_USERAGENT,
|
||||
},
|
||||
}).then((res) => Number(res.headers.get("Content-Length")));
|
||||
|
||||
if (size <= limit) {
|
||||
const file = await fetch(attachment.url, {
|
||||
headers: {
|
||||
"User-Agent": FRIENDLY_USERAGENT,
|
||||
},
|
||||
})
|
||||
.then((res) => res.arrayBuffer())
|
||||
.then((buf) => Buffer.from(buf));
|
||||
|
||||
files.push({
|
||||
filename:
|
||||
(cw != "" || spoiler ? "SPOILER_" : "") +
|
||||
(attachment.type.indexOf("/") > -1
|
||||
? attachment.type.replace("/", ".")
|
||||
: attachment.type + "." + (url.match(/\.([a-z0-9]{3,4})$/)?.[0] ?? "png")),
|
||||
file,
|
||||
description: attachment.desc,
|
||||
});
|
||||
}
|
||||
}
|
||||
embeds.push(baseEmbed);
|
||||
} else {
|
||||
const ten = images.slice(0, 10);
|
||||
|
||||
for (const attachment of ten) {
|
||||
const size = await fetch(attachment.url, {
|
||||
method: "HEAD",
|
||||
headers: {
|
||||
"User-Agent": FRIENDLY_USERAGENT,
|
||||
},
|
||||
}).then((res) => Number(res.headers.get("Content-Length")));
|
||||
|
||||
if (size <= limit) {
|
||||
const file = await fetch(attachment.url, {
|
||||
headers: {
|
||||
"User-Agent": FRIENDLY_USERAGENT,
|
||||
},
|
||||
})
|
||||
.then((res) => res.arrayBuffer())
|
||||
.then((buf) => Buffer.from(buf));
|
||||
|
||||
files.push({
|
||||
filename:
|
||||
(cw != "" || spoiler ? "SPOILER_" : "") +
|
||||
(attachment.type.indexOf("/") > -1
|
||||
? attachment.type.replace("/", ".")
|
||||
: attachment.type + "." + (url.match(/\.([a-z0-9]{3,4})$/)?.[0] ?? "png")),
|
||||
file,
|
||||
description: attachment.desc,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (images.length <= 14) {
|
||||
const fourteen = images.slice(10, 14);
|
||||
|
||||
for (const attachment of fourteen) {
|
||||
const embed = Object.assign({}, baseEmbed);
|
||||
embed.image = {
|
||||
url: attachment.url,
|
||||
description: attachment.desc,
|
||||
};
|
||||
embeds.push(embed);
|
||||
}
|
||||
} else if (images.length <= 18) {
|
||||
const fourteen = images.slice(10, 14);
|
||||
|
||||
for (const attachment of fourteen) {
|
||||
const embed = Object.assign({}, baseEmbed);
|
||||
embed.image = {
|
||||
url: attachment.url,
|
||||
description: attachment.desc,
|
||||
};
|
||||
embeds.push(embed);
|
||||
}
|
||||
|
||||
const eighteen = images.slice(14, 18);
|
||||
const _embed = {
|
||||
color: baseEmbed.color,
|
||||
url: baseEmbed.url + "?_",
|
||||
title: "Additional Images",
|
||||
};
|
||||
|
||||
for (const attachment of eighteen) {
|
||||
const embed = Object.assign({}, _embed);
|
||||
embed.image = {
|
||||
url: attachment.url,
|
||||
description: attachment.desc,
|
||||
};
|
||||
embeds.push(embed);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
embeds.push(baseEmbed);
|
||||
}
|
||||
|
||||
if (videos.length > 0) {
|
||||
for (const attachment of videos) {
|
||||
const size = await fetch(attachment.url, {
|
||||
method: "HEAD",
|
||||
headers: {
|
||||
"User-Agent": FRIENDLY_USERAGENT,
|
||||
},
|
||||
}).then((res) => Number(res.headers.get("Content-Length")));
|
||||
|
||||
if (size <= limit) {
|
||||
const file = await fetch(attachment.url, {
|
||||
headers: {
|
||||
"User-Agent": FRIENDLY_USERAGENT,
|
||||
},
|
||||
})
|
||||
.then((res) => res.arrayBuffer())
|
||||
.then((buf) => Buffer.from(buf));
|
||||
|
||||
files.push({
|
||||
filename:
|
||||
(cw != "" || spoiler ? "SPOILER_" : "") +
|
||||
(attachment.type.indexOf("/") > -1
|
||||
? attachment.type.replace("/", ".").replace("quicktime", "mov")
|
||||
: attachment.type + "." + (url.match(/\.([a-z0-9]{3,4})$/)?.[0] ?? "mp4")),
|
||||
file,
|
||||
description: attachment.desc,
|
||||
if (images.length > 10) {
|
||||
while (images.length > 10) {
|
||||
container.components.push({
|
||||
type: 12,
|
||||
items: images.splice(0, 10),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
container.components.push({
|
||||
type: 12,
|
||||
items: images,
|
||||
});
|
||||
}
|
||||
for (const video of videos) {
|
||||
if (video.description?.length === 0) video.description = null;
|
||||
container.components.push({
|
||||
type: 12,
|
||||
items: [video],
|
||||
});
|
||||
}
|
||||
|
||||
if (audios.length > 0) {
|
||||
for (const attachment of audios) {
|
||||
const size = await fetch(attachment.url, {
|
||||
method: "HEAD",
|
||||
headers: {
|
||||
"User-Agent": FRIENDLY_USERAGENT,
|
||||
},
|
||||
}).then((res) => Number(res.headers.get("Content-Length")));
|
||||
|
||||
if (size <= limit) {
|
||||
const file = await fetch(attachment.url, {
|
||||
headers: {
|
||||
"User-Agent": FRIENDLY_USERAGENT,
|
||||
},
|
||||
})
|
||||
.then((res) => res.arrayBuffer())
|
||||
.then((buf) => Buffer.from(buf));
|
||||
|
||||
files.push({
|
||||
filename:
|
||||
(cw != "" || spoiler ? "SPOILER_" : "") +
|
||||
(attachment.type.indexOf("/") > -1
|
||||
? attachment.type.replace("/", ".").replace("mpeg", "mp3").replace("vnd.wave", "wav").replace("x-", "")
|
||||
: attachment.type + "." + (url.match(/\.([a-z0-9]{3,4})$/)?.[0] ?? "mp3")),
|
||||
file,
|
||||
description: attachment.desc,
|
||||
});
|
||||
container.components.push(
|
||||
{
|
||||
type: 10,
|
||||
content: "### Audio Attachments",
|
||||
},
|
||||
{
|
||||
type: 1,
|
||||
components: audios.map((a) => ({
|
||||
type: 2,
|
||||
style: 5,
|
||||
emoji: {name: "silk_sound", id: "1273119755376529418", animated: false},
|
||||
label:
|
||||
a.description?.length > 0
|
||||
? `"${a.description.length > 78 ? a.description.substring(0, 77) + "\u2026" : a.description}"`
|
||||
: "Audio",
|
||||
url: a.url,
|
||||
})),
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
container.components.push(footer);
|
||||
|
||||
if (quoteRes) {
|
||||
if (!sendWait && quoteRes.sendWait) sendWait = true;
|
||||
files.push(...quoteRes.response.attachments);
|
||||
const quoteEmbed = quoteRes.response.embeds[0];
|
||||
quoteEmbed.author = {name: "Quoted Post", icon_url: "https://cdn.discordapp.com/emojis/1308640087759654922.png"};
|
||||
embeds.push(quoteEmbed);
|
||||
const quoteComponents = quoteRes.response.components[0].components;
|
||||
const quoteContext = `-# ${Icons.fedimbed.quote} Quoted Post`;
|
||||
if (quoteComponents[0].type == 10) {
|
||||
quoteComponents[0].content = quoteContext + "\n" + quoteComponents[0].content;
|
||||
} else {
|
||||
quoteComponents.splice(0, 0, {type: 10, content: quoteContext});
|
||||
}
|
||||
container.components.push({type: 14}, ...quoteComponents);
|
||||
}
|
||||
|
||||
return {
|
||||
response: {
|
||||
content:
|
||||
cw != "" && (images.length > 0 || videos.length > 0 || audios.length > 0)
|
||||
? `:warning: ${cw} || ${url} ||`
|
||||
: spoiler
|
||||
? `|| ${url} ||`
|
||||
: "",
|
||||
embeds,
|
||||
attachments: files,
|
||||
flags: 1 << 15,
|
||||
components: [cw.length > 0 ? warningText : false, container].filter((x) => !!x),
|
||||
allowedMentions: {
|
||||
repliedUser: false,
|
||||
},
|
||||
|
@ -1758,7 +1499,6 @@ async function processUrl(msg, url, spoiler = false, command = false) {
|
|||
messageID: msg.id,
|
||||
},
|
||||
},
|
||||
sendWait,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue