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 fs = require("node:fs");
|
||||||
const httpSignature = require("@peertube/http-signature");
|
const httpSignature = require("@peertube/http-signature");
|
||||||
const {XMLParser} = require("fast-xml-parser");
|
const {XMLParser} = require("fast-xml-parser");
|
||||||
|
@ -11,7 +9,6 @@ const InteractionCommand = require("#lib/interactionCommand.js");
|
||||||
|
|
||||||
const {Icons} = require("#util/constants.js");
|
const {Icons} = require("#util/constants.js");
|
||||||
const {MessageFlags, ApplicationCommandOptionTypes, Permissions} = require("#util/dconstants.js");
|
const {MessageFlags, ApplicationCommandOptionTypes, Permissions} = require("#util/dconstants.js");
|
||||||
const {getUploadLimit} = require("#util/misc.js");
|
|
||||||
const {htmlToMarkdown} = require("#util/html.js");
|
const {htmlToMarkdown} = require("#util/html.js");
|
||||||
|
|
||||||
const FRIENDLY_USERAGENT =
|
const FRIENDLY_USERAGENT =
|
||||||
|
@ -715,7 +712,7 @@ async function bluesky(msg, url, spoiler = false) {
|
||||||
return {
|
return {
|
||||||
response: {
|
response: {
|
||||||
flags: 1 << 15,
|
flags: 1 << 15,
|
||||||
components: [warnings.length > 0 ? warningText : false, container].filter((x) => !!x),
|
components: [warnings.length > 0 && warningText, container].filter((x) => !!x),
|
||||||
allowedMentions: {
|
allowedMentions: {
|
||||||
repliedUser: false,
|
repliedUser: false,
|
||||||
},
|
},
|
||||||
|
@ -910,18 +907,20 @@ async function getStatsAS(post) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const stats = [];
|
const stats = [];
|
||||||
if (replyCount > 0) stats.push(`\u21a9 ${statsFormatter.format(replyCount)}`);
|
if (replyCount > 0) stats.push(`${Icons.fedimbed.reply} ${statsFormatter.format(replyCount)}`);
|
||||||
if (post.shares?.totalItems ?? 0 > 0) stats.push(`\ud83d\udd01 ${statsFormatter.format(post.shares.totalItems)}`);
|
if (post.shares?.totalItems ?? 0 > 0)
|
||||||
if (post.likes?.totalItems ?? 0 > 0) stats.push(`\u2665 ${statsFormatter.format(post.likes.totalItems)}`);
|
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");
|
return stats.join("\u3000");
|
||||||
}
|
}
|
||||||
|
|
||||||
function getStatsMasto(post) {
|
function getStatsMasto(post) {
|
||||||
const stats = [];
|
const stats = [];
|
||||||
if (post.replies_count > 0) stats.push(`\u21a9 ${statsFormatter.format(post.replies_count)}`);
|
if (post.replies_count > 0) stats.push(`${Icons.fedimbed.reply} ${statsFormatter.format(post.replies_count)}`);
|
||||||
if (post.reblogs_count > 0) stats.push(`\ud83d\udd01 ${statsFormatter.format(post.reblogs_count)}`);
|
if (post.reblogs_count > 0) stats.push(`${Icons.fedimbed.repost} ${statsFormatter.format(post.reblogs_count)}`);
|
||||||
if (post.favourites_count > 0) stats.push(`\u2665 ${statsFormatter.format(post.favourites_count)}`);
|
if (post.favourites_count > 0) stats.push(`${Icons.fedimbed.like} ${statsFormatter.format(post.favourites_count)}`);
|
||||||
|
|
||||||
return stats.join("\u3000");
|
return stats.join("\u3000");
|
||||||
}
|
}
|
||||||
|
@ -1061,61 +1060,26 @@ async function processUrl(msg, url, spoiler = false, command = false) {
|
||||||
const attachments = postData.media_attachments ?? postData.files;
|
const attachments = postData.media_attachments ?? postData.files;
|
||||||
if (attachments) {
|
if (attachments) {
|
||||||
for (const attachment of attachments) {
|
for (const attachment of attachments) {
|
||||||
const contentType = await fetch(attachment.url, {
|
|
||||||
method: "HEAD",
|
|
||||||
}).then((res) => res.headers.get("Content-Type"));
|
|
||||||
|
|
||||||
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 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")) {
|
if (type.startsWith("image")) {
|
||||||
images.push({
|
images.push({
|
||||||
url: attachment.url,
|
media: {url: attachment.url},
|
||||||
desc: attachment.description ?? attachment.comment,
|
description: attachment.description ?? attachment.comment,
|
||||||
type: fileType,
|
|
||||||
});
|
});
|
||||||
} else if (type.startsWith("video")) {
|
} else if (type.startsWith("video")) {
|
||||||
videos.push({
|
videos.push({
|
||||||
url: attachment.url,
|
media: {url: attachment.url},
|
||||||
desc: attachment.description ?? attachment.comment,
|
description: attachment.description ?? attachment.comment,
|
||||||
type: fileType,
|
|
||||||
});
|
});
|
||||||
} else if (type.startsWith("audio")) {
|
} else if (type.startsWith("audio")) {
|
||||||
audios.push({
|
audios.push({
|
||||||
url: attachment.url,
|
url: attachment.url,
|
||||||
desc: attachment.description ?? attachment.comment,
|
description: attachment.description ?? attachment.comment,
|
||||||
type: fileType,
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (!spoiler && postData.sensitive && attachments.length > 0) {
|
if (!spoiler && postData.sensitive && attachments.length > 0) {
|
||||||
spoiler = true;
|
spoiler = true;
|
||||||
}
|
}
|
||||||
|
@ -1156,19 +1120,19 @@ async function processUrl(msg, url, spoiler = false, command = false) {
|
||||||
|
|
||||||
if (postData.inReplyTo) {
|
if (postData.inReplyTo) {
|
||||||
contextUrl = postData.inReplyTo;
|
contextUrl = postData.inReplyTo;
|
||||||
context = "Replying to: ";
|
context = `-# ${Icons.fedimbed.reply} Replying to: `;
|
||||||
|
|
||||||
const replyData = await fetchPost(postData.inReplyTo, platform);
|
const replyData = await fetchPost(postData.inReplyTo, platform);
|
||||||
if (replyData) {
|
if (replyData) {
|
||||||
if (replyData._fedimbed_mastoapi) {
|
if (replyData._fedimbed_mastoapi) {
|
||||||
context += `${
|
context += `[${
|
||||||
replyData.account?.display_name ??
|
replyData.account?.display_name ??
|
||||||
replyData.account?.username ??
|
replyData.account?.username ??
|
||||||
replyData.user?.name ??
|
replyData.user?.name ??
|
||||||
replyData.user?.username
|
replyData.user?.username
|
||||||
} (@${
|
} (@${
|
||||||
replyData.account?.fqn ?? `${replyData.account?.username ?? replyData.user?.username}@${urlObj.hostname}`
|
replyData.account?.fqn ?? `${replyData.account?.username ?? replyData.user?.username}@${urlObj.hostname}`
|
||||||
})`;
|
})](${contextUrl})`;
|
||||||
} else {
|
} else {
|
||||||
const authorData = await signedFetch(replyData.actor ?? replyData.attributedTo, {
|
const authorData = await signedFetch(replyData.actor ?? replyData.attributedTo, {
|
||||||
headers: {
|
headers: {
|
||||||
|
@ -1183,13 +1147,13 @@ async function processUrl(msg, url, spoiler = false, command = false) {
|
||||||
|
|
||||||
if (authorData) {
|
if (authorData) {
|
||||||
const authorUrlObj = new URL(authorData.url ?? authorData.id);
|
const authorUrlObj = new URL(authorData.url ?? authorData.id);
|
||||||
context += `${authorData.name} (${authorData.preferredUsername}@${authorUrlObj.hostname})`;
|
context += `[${authorData.name} (${authorData.preferredUsername}@${authorUrlObj.hostname})](${contextUrl})`;
|
||||||
} else {
|
} else {
|
||||||
// bootleg author
|
// bootleg author
|
||||||
const authorUrl = replyData.actor ?? replyData.attributedTo;
|
const authorUrl = replyData.actor ?? replyData.attributedTo;
|
||||||
const authorUrlObj = new URL(authorUrl);
|
const authorUrlObj = new URL(authorUrl);
|
||||||
const name = authorUrlObj.pathname.substring(authorUrlObj.pathname.lastIndexOf("/") + 1);
|
const name = authorUrlObj.pathname.substring(authorUrlObj.pathname.lastIndexOf("/") + 1);
|
||||||
context += `${name}@${authorUrlObj.hostname}`;
|
context += `[${name}@${authorUrlObj.hostname}](${authorUrl})`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} 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)
|
// NB: everyone else except gts doesnt follow the spec (they should be using attachments)
|
||||||
const attachments = Array.isArray(postData.attachment) ? postData.attachment : [postData.attachment];
|
const attachments = Array.isArray(postData.attachment) ? postData.attachment : [postData.attachment];
|
||||||
for (const attachment of attachments) {
|
for (const attachment of attachments) {
|
||||||
if (attachment.mediaType) {
|
if (attachment.url) {
|
||||||
if (attachment.mediaType.startsWith("video/")) {
|
const type = attachment.type?.toLowerCase();
|
||||||
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) {
|
|
||||||
let attUrl = attachment.url;
|
let attUrl = attachment.url;
|
||||||
if (Array.isArray(attachment.url)) {
|
if (Array.isArray(attachment.url)) {
|
||||||
switch (attachment.type) {
|
switch (type) {
|
||||||
case "Image": {
|
case "image": {
|
||||||
const newUrl = attachment.url.find((a) => a.mediaType?.startsWith("image/"))?.href;
|
const newUrl = attachment.url.find((a) => a.mediaType?.startsWith("image/"))?.href;
|
||||||
if (newUrl) attUrl = newUrl;
|
if (newUrl) attUrl = newUrl;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "Video": {
|
case "video": {
|
||||||
const newUrl = attachment.url.find((a) => a.mediaType?.startsWith("video/"))?.href;
|
const newUrl = attachment.url.find((a) => a.mediaType?.startsWith("video/"))?.href;
|
||||||
if (newUrl) attUrl = newUrl;
|
if (newUrl) attUrl = newUrl;
|
||||||
break;
|
break;
|
||||||
|
@ -1240,61 +1186,22 @@ 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")) {
|
if (type.startsWith("image")) {
|
||||||
images.push({
|
images.push({
|
||||||
url: attUrl,
|
media: {url: attUrl},
|
||||||
desc: attachment.name ?? attachment.description ?? attachment.comment,
|
description: attachment.name ?? attachment.description ?? attachment.comment,
|
||||||
type: fileType,
|
|
||||||
});
|
});
|
||||||
} else if (type.startsWith("video")) {
|
} else if (type.startsWith("video")) {
|
||||||
videos.push({
|
videos.push({
|
||||||
url: attUrl,
|
media: {url: attUrl},
|
||||||
desc: attachment.name ?? attachment.description ?? attachment.comment,
|
description: attachment.name ?? attachment.description ?? attachment.comment,
|
||||||
type: fileType,
|
|
||||||
});
|
});
|
||||||
} else if (type.startsWith("audio")) {
|
} else if (type.startsWith("audio")) {
|
||||||
audios.push({
|
audios.push({
|
||||||
url: attUrl,
|
url: attUrl,
|
||||||
desc: attachment.name ?? attachment.description ?? attachment.comment,
|
description: attachment.name ?? attachment.description ?? attachment.comment,
|
||||||
type: fileType,
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
logger.warn("fedimbed", `Unhandled attachment structure! ${JSON.stringify(attachment)}`);
|
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) {
|
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({
|
images.push({
|
||||||
url: postData.image.url,
|
media: {url: postData.image.url},
|
||||||
desc: "",
|
|
||||||
type: contentType ?? "image/" + imageUrl.pathname.substring(imageUrl.pathname.lastIndexOf(".") + 1),
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1328,7 +1229,7 @@ async function processUrl(msg, url, spoiler = false, command = false) {
|
||||||
})
|
})
|
||||||
.then((res) => res.json())
|
.then((res) => res.json())
|
||||||
.catch((err) => {
|
.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) {
|
if (authorData) {
|
||||||
|
@ -1394,31 +1295,15 @@ async function processUrl(msg, url, spoiler = false, command = false) {
|
||||||
|
|
||||||
let desc = "";
|
let desc = "";
|
||||||
let MAX_LENGTH = 3999;
|
let MAX_LENGTH = 3999;
|
||||||
if ((cw != "" || sensitive) && images.length == 0 && videos.length == 0 && audios.length == 0) {
|
if (cw != "" || sensitive) {
|
||||||
const ors = content.split("||");
|
const ors = content.split("||");
|
||||||
desc += `||${content.replaceAll("||", "|\u200b|")}||`;
|
desc += `||${content.replaceAll("||", "|\u200b|")}||`;
|
||||||
MAX_LENGTH -= ors.length - 1;
|
MAX_LENGTH -= ors.length - 1;
|
||||||
MAX_LENGTH -= 4;
|
MAX_LENGTH -= 4;
|
||||||
|
|
||||||
if (cw != "") {
|
|
||||||
desc = "\u26a0 " + cw + "\n\n" + desc;
|
|
||||||
MAX_LENGTH -= 4 - cw.length;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
desc = content;
|
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);
|
const crawled = await getCrawledData(url, color, platformName);
|
||||||
if (!color && crawled?.color) {
|
if (!color && crawled?.color) {
|
||||||
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 ")) {
|
if (platformName.includes("Nitter") && platformName.includes(" \u2022 ")) {
|
||||||
const [nn, ns] = platformName.split(" \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;
|
platformName = nn;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (platformName == "Nitter") {
|
if (platformName == "Nitter") {
|
||||||
const newHandle = author.handle.split("@")[0];
|
const newHandle = author.handle.split("@")[0];
|
||||||
user = `${author.name} (@${newHandle})`;
|
author.handle = "@" + newHandle;
|
||||||
|
|
||||||
if (context) {
|
if (context) {
|
||||||
const contextHandle = context.match(/\(([^@]+?@.+?)\)/)?.[1];
|
const contextHandle = context.match(/\(([^@]+?@.+?)\)/)?.[1];
|
||||||
if (contextHandle) {
|
if (contextHandle) {
|
||||||
const newContextHandle = "@" + contextHandle.split("@")[0];
|
const newContextHandle = contextHandle.split("@")[0];
|
||||||
context = context.replace(contextHandle, newContextHandle);
|
context = context.replace(contextHandle, "@" + newContextHandle);
|
||||||
|
context = context.replace(/: (.+?)$/, `: [$1](${contextUrl})`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const baseEmbed = {
|
const warningText = {
|
||||||
color,
|
type: 10,
|
||||||
url,
|
content: `## ${cw}`,
|
||||||
timestamp,
|
};
|
||||||
description: desc,
|
|
||||||
title: title ?? user,
|
const container = {
|
||||||
author: title
|
type: 17,
|
||||||
? {
|
accent_color: color,
|
||||||
name: user,
|
components: [],
|
||||||
url: author.url,
|
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 {
|
||||||
|
desc = desc.substring(0, MAX_LENGTH) + "\u2026";
|
||||||
}
|
}
|
||||||
: context
|
|
||||||
? {
|
|
||||||
name: context,
|
|
||||||
url: contextUrl,
|
|
||||||
icon_url: "https://cdn.discordapp.com/emojis/1308640078825787412.png",
|
|
||||||
}
|
}
|
||||||
: null,
|
headerContent += "\n" + desc;
|
||||||
footer: {
|
|
||||||
icon_url: crawled?.icon,
|
const header = [
|
||||||
text: (stats != null && stats != "" ? stats + "\n" : "") + platformName,
|
context && {
|
||||||
|
type: 10,
|
||||||
|
content: context,
|
||||||
},
|
},
|
||||||
thumbnail: {
|
{
|
||||||
|
type: 9,
|
||||||
|
components: [
|
||||||
|
{
|
||||||
|
type: 10,
|
||||||
|
content: headerContent,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
accessory: {
|
||||||
|
type: 11,
|
||||||
|
media: {
|
||||||
url: author.avatar,
|
url: author.avatar,
|
||||||
},
|
},
|
||||||
fields: [],
|
},
|
||||||
};
|
},
|
||||||
if (images.length > 0) {
|
].filter((x) => !!x);
|
||||||
if (images.length > 1) {
|
container.components.push(...header);
|
||||||
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,
|
|
||||||
});
|
|
||||||
} 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,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (poll) {
|
if (poll) {
|
||||||
const pollTime = poll.end.getTime();
|
const pollTime = poll.end.getTime();
|
||||||
const now = Date.now();
|
const now = Date.now();
|
||||||
baseEmbed.fields.push({
|
container.components.push({
|
||||||
name: "Poll",
|
type: 10,
|
||||||
value:
|
content:
|
||||||
poll.options
|
poll.options
|
||||||
.map((o) => {
|
.map((o) => {
|
||||||
const percent = o.count / poll.total;
|
const percent = o.count / poll.total;
|
||||||
const bar = Math.round(percent * 32);
|
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
|
percent * 100
|
||||||
)}%)\n\`${"\u2588".repeat(bar)}${" ".repeat(32 - bar)}\``;
|
)}%)> \n\`${"\u2588".repeat(bar)}${" ".repeat(32 - bar)}\``;
|
||||||
})
|
})
|
||||||
.join("\n\n") +
|
.join("> \n> \n") +
|
||||||
`\n\n${poll.total} votes \u2022 End${pollTime > now ? "s" : "ed"} <t:${Math.floor(pollTime / 1000)}:R>`,
|
`> \n> \n${poll.total} votes \u2022 End${pollTime > now ? "s" : "ed"} <t:${Math.floor(pollTime / 1000)}:R>`,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
let sendWait = false;
|
const footer = {
|
||||||
if (videos.length > 0 || audios.length > 0 || images.length > 4) {
|
type: 9,
|
||||||
sendWait = true;
|
components: [
|
||||||
if (msg instanceof Message) await msg.addReaction("\uD83D\uDCE4");
|
{
|
||||||
|
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 > 0) {
|
||||||
if (images.length <= 4) {
|
if (images.length > 10) {
|
||||||
for (const attachment of images) {
|
while (images.length > 10) {
|
||||||
const embed = Object.assign({}, baseEmbed);
|
container.components.push({
|
||||||
embed.image = {
|
type: 12,
|
||||||
url: attachment.url,
|
items: images.splice(0, 10),
|
||||||
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) {
|
container.components.push({
|
||||||
const fourteen = images.slice(10, 14);
|
type: 12,
|
||||||
|
items: images,
|
||||||
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,
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
for (const video of videos) {
|
||||||
|
if (video.description?.length === 0) video.description = null;
|
||||||
|
container.components.push({
|
||||||
|
type: 12,
|
||||||
|
items: [video],
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (audios.length > 0) {
|
if (audios.length > 0) {
|
||||||
for (const attachment of audios) {
|
container.components.push(
|
||||||
const size = await fetch(attachment.url, {
|
{
|
||||||
method: "HEAD",
|
type: 10,
|
||||||
headers: {
|
content: "### Audio Attachments",
|
||||||
"User-Agent": FRIENDLY_USERAGENT,
|
|
||||||
},
|
},
|
||||||
}).then((res) => Number(res.headers.get("Content-Length")));
|
{
|
||||||
|
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,
|
||||||
|
})),
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if (size <= limit) {
|
container.components.push(footer);
|
||||||
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,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (quoteRes) {
|
if (quoteRes) {
|
||||||
if (!sendWait && quoteRes.sendWait) sendWait = true;
|
const quoteComponents = quoteRes.response.components[0].components;
|
||||||
files.push(...quoteRes.response.attachments);
|
const quoteContext = `-# ${Icons.fedimbed.quote} Quoted Post`;
|
||||||
const quoteEmbed = quoteRes.response.embeds[0];
|
if (quoteComponents[0].type == 10) {
|
||||||
quoteEmbed.author = {name: "Quoted Post", icon_url: "https://cdn.discordapp.com/emojis/1308640087759654922.png"};
|
quoteComponents[0].content = quoteContext + "\n" + quoteComponents[0].content;
|
||||||
embeds.push(quoteEmbed);
|
} else {
|
||||||
|
quoteComponents.splice(0, 0, {type: 10, content: quoteContext});
|
||||||
|
}
|
||||||
|
container.components.push({type: 14}, ...quoteComponents);
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
response: {
|
response: {
|
||||||
content:
|
flags: 1 << 15,
|
||||||
cw != "" && (images.length > 0 || videos.length > 0 || audios.length > 0)
|
components: [cw.length > 0 ? warningText : false, container].filter((x) => !!x),
|
||||||
? `:warning: ${cw} || ${url} ||`
|
|
||||||
: spoiler
|
|
||||||
? `|| ${url} ||`
|
|
||||||
: "",
|
|
||||||
embeds,
|
|
||||||
attachments: files,
|
|
||||||
allowedMentions: {
|
allowedMentions: {
|
||||||
repliedUser: false,
|
repliedUser: false,
|
||||||
},
|
},
|
||||||
|
@ -1758,7 +1499,6 @@ async function processUrl(msg, url, spoiler = false, command = false) {
|
||||||
messageID: msg.id,
|
messageID: msg.id,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
sendWait,
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue