Compare commits
No commits in common. "6e85237cab311b1c27020b105998c3f441bf5ea6" and "542070b33b4cd17be9e5b1cd401a524103dae875" have entirely different histories.
6e85237cab
...
542070b33b
6 changed files with 1802 additions and 2452 deletions
3770
pnpm-lock.yaml
3770
pnpm-lock.yaml
File diff suppressed because it is too large
Load diff
163
src/index.js
163
src/index.js
|
@ -1,20 +1,15 @@
|
||||||
const Dysnomia = require("@projectdysnomia/dysnomia");
|
const Dysnomia = require("@projectdysnomia/dysnomia");
|
||||||
const logger = require("./lib/logger.js");
|
const logger = require("./lib/logger.js");
|
||||||
const fs = require("node:fs");
|
const fs = require("fs");
|
||||||
const {resolve} = require("node:path");
|
const {resolve} = require("path");
|
||||||
const sqlite3 = require("sqlite3");
|
const sqlite3 = require("sqlite3");
|
||||||
const {instead, before} = require("spitroast");
|
const {instead, before} = require("spitroast");
|
||||||
|
|
||||||
const config = require("../config.json");
|
const config = require("../config.json");
|
||||||
const apikeys = require("../apikeys.json");
|
const apikeys = require("../apikeys.json");
|
||||||
|
|
||||||
const events = require("./lib/events.js");
|
|
||||||
const {formatUsername} = require("./lib/utils.js");
|
|
||||||
const timer = require("./lib/timer.js");
|
|
||||||
const Command = require("./lib/command.js");
|
const Command = require("./lib/command.js");
|
||||||
const CommandDispatcher = require("./lib/commandDispatcher.js");
|
const events = require("./lib/events.js");
|
||||||
const InteractionCommand = require("./lib/interactionCommand.js");
|
const timer = require("./lib/timer.js");
|
||||||
const {InteractionDispatcher} = require("./lib/interactionDispatcher.js");
|
|
||||||
|
|
||||||
const bot = new Dysnomia.Client(config.token, {
|
const bot = new Dysnomia.Client(config.token, {
|
||||||
defaultImageFormat: "png",
|
defaultImageFormat: "png",
|
||||||
|
@ -22,11 +17,9 @@ const bot = new Dysnomia.Client(config.token, {
|
||||||
gateway: {
|
gateway: {
|
||||||
intents: Object.values(Dysnomia.Constants.Intents),
|
intents: Object.values(Dysnomia.Constants.Intents),
|
||||||
},
|
},
|
||||||
restMode: true,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const commands = new Dysnomia.Collection();
|
const commands = new Dysnomia.Collection();
|
||||||
const interactionCommands = new Dysnomia.Collection();
|
|
||||||
|
|
||||||
const database = new sqlite3.Database(resolve(__dirname, "..", "database.db"));
|
const database = new sqlite3.Database(resolve(__dirname, "..", "database.db"));
|
||||||
|
|
||||||
|
@ -40,9 +33,6 @@ function registerCommand(cmdObj) {
|
||||||
aliases.length > 0 ? ` (aliases: ${aliases.join(", ")})` : ""
|
aliases.length > 0 ? ` (aliases: ${aliases.join(", ")})` : ""
|
||||||
}`
|
}`
|
||||||
);
|
);
|
||||||
} else if (cmdObj instanceof InteractionCommand) {
|
|
||||||
interactionCommands.set(cmdObj.name, cmdObj);
|
|
||||||
logger.info("hf:cmd", `Registered interaction command '${cmdObj.name}'`);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,120 +41,44 @@ global.hf = {
|
||||||
config,
|
config,
|
||||||
apikeys,
|
apikeys,
|
||||||
commands,
|
commands,
|
||||||
interactionCommands,
|
|
||||||
registerCommand,
|
registerCommand,
|
||||||
events,
|
events,
|
||||||
timer,
|
timer,
|
||||||
database,
|
database,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const CommandDispatcher = require("./lib/commandDispatcher.js");
|
||||||
|
const {formatUsername} = require("./lib/utils.js");
|
||||||
|
|
||||||
for (const file of fs.readdirSync(resolve(__dirname, "modules"))) {
|
for (const file of fs.readdirSync(resolve(__dirname, "modules"))) {
|
||||||
require(resolve(__dirname, "modules", file));
|
require(resolve(__dirname, "modules", file));
|
||||||
logger.info("hf:modules", `Loaded module: '${file}'`);
|
logger.info("hf:modules", `Loaded module: '${file}'`);
|
||||||
}
|
}
|
||||||
|
|
||||||
bot.on("messageCreate", async (msg) => {
|
bot.on("messageCreate", async (msg) => {
|
||||||
try {
|
// fix DMs cause of gateway v8 changes
|
||||||
// fix DMs cause of gateway v8 changes
|
if (
|
||||||
if (
|
!(msg.channel instanceof Dysnomia.Channel) &&
|
||||||
!(msg.channel instanceof Dysnomia.Channel) &&
|
msg.author.id != bot.user.id &&
|
||||||
msg.author.id != bot.user.id &&
|
!msg.guildID
|
||||||
!msg.guildID
|
) {
|
||||||
) {
|
const newChannel = await bot.getDMChannel(msg.author.id);
|
||||||
const newChannel = await bot.getDMChannel(msg.author.id);
|
if (msg.channel.id == newChannel.id) msg.channel = newChannel;
|
||||||
if (msg.channel.id == newChannel.id) msg.channel = newChannel;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(msg.channel instanceof Dysnomia.Channel)) return;
|
|
||||||
|
|
||||||
await CommandDispatcher(msg);
|
|
||||||
} catch (err) {
|
|
||||||
const stack = (err?.stack ?? err.message).split("\n");
|
|
||||||
const error = stack.shift();
|
|
||||||
logger.error(
|
|
||||||
"hf:main",
|
|
||||||
`Failed to dispatch command: ${error}\n\t${stack.join("\n\t")}`
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!(msg.channel instanceof Dysnomia.Channel)) return;
|
||||||
|
|
||||||
|
await CommandDispatcher(msg);
|
||||||
});
|
});
|
||||||
bot.on("messageUpdate", async (msg, oldMsg) => {
|
bot.on("messageUpdate", (msg, oldMsg) => {
|
||||||
try {
|
const oneDay = Date.now() - 86400000;
|
||||||
const oneDay = Date.now() - 86400000;
|
if (
|
||||||
if (
|
msg.timestamp > oneDay &&
|
||||||
msg.timestamp > oneDay &&
|
!msg.hasRan &&
|
||||||
!msg.hasRan &&
|
oldMsg &&
|
||||||
oldMsg &&
|
oldMsg.content !== msg.content
|
||||||
oldMsg.content !== msg.content
|
) {
|
||||||
) {
|
CommandDispatcher(msg);
|
||||||
await CommandDispatcher(msg);
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
const stack = (err?.stack ?? err.message).split("\n");
|
|
||||||
const error = stack.shift();
|
|
||||||
logger.error(
|
|
||||||
"hf:main",
|
|
||||||
`Failed to dispatch command update: ${error}\n\t${stack.join("\n\t")}`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
bot.on("messageReactionAdd", async (msg, reaction, reactor) => {
|
|
||||||
if (msg.author.id !== bot.user.id) return;
|
|
||||||
if (reaction.name !== "\u274c") return;
|
|
||||||
|
|
||||||
try {
|
|
||||||
let channel = msg.channel;
|
|
||||||
if (!(channel instanceof Dysnomia.Channel)) {
|
|
||||||
const newChannel = hf.bot.getChannel(channel.id);
|
|
||||||
if (newChannel) {
|
|
||||||
channel = newChannel;
|
|
||||||
} else {
|
|
||||||
channel = await hf.bot.getRESTChannel(channel.id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!msg.messageReference) {
|
|
||||||
msg = await channel.getMessage(msg.id);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!msg.messageReference) return;
|
|
||||||
|
|
||||||
const ref = await channel.getMessage(msg.messageReference.messageID);
|
|
||||||
if (!ref) return;
|
|
||||||
if (ref.author.id !== reactor.id) return;
|
|
||||||
|
|
||||||
await msg.delete("Command sender requested output deletion.");
|
|
||||||
} catch (err) {
|
|
||||||
const stack = (err?.stack ?? err.message).split("\n");
|
|
||||||
const error = stack.shift();
|
|
||||||
logger.error(
|
|
||||||
"hf:main",
|
|
||||||
`Failed to self-delete message: ${error}\n\t${stack.join("\n\t")}`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
bot.on("interactionCreate", async (interaction) => {
|
|
||||||
try {
|
|
||||||
if (!(interaction.channel instanceof Dysnomia.Channel)) {
|
|
||||||
const newChannel = hf.bot.getChannel(interaction.channel.id);
|
|
||||||
if (newChannel) {
|
|
||||||
interaction.channel = newChannel;
|
|
||||||
} else {
|
|
||||||
interaction.channel = await hf.bot.getRESTChannel(
|
|
||||||
interaction.channel.id
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
await InteractionDispatcher(interaction);
|
|
||||||
} catch (err) {
|
|
||||||
const stack = (err?.stack ?? err.message).split("\n");
|
|
||||||
const error = stack.shift();
|
|
||||||
logger.error(
|
|
||||||
"hf:main",
|
|
||||||
`Failed to dispatch interaction command: ${error}\n\t${stack.join(
|
|
||||||
"\n\t"
|
|
||||||
)}`
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -184,27 +98,6 @@ bot.once("ready", async () => {
|
||||||
bot.on("ready", () => {
|
bot.on("ready", () => {
|
||||||
logger.info("hf:main", "Reconnected to Discord.");
|
logger.info("hf:main", "Reconnected to Discord.");
|
||||||
});
|
});
|
||||||
|
|
||||||
const commands = await bot.getCommands();
|
|
||||||
for (const command of interactionCommands.values()) {
|
|
||||||
const hasCommand = commands.find((c) => c.name == command.name);
|
|
||||||
if (hasCommand) continue;
|
|
||||||
|
|
||||||
await bot.createCommand({
|
|
||||||
name: command.name,
|
|
||||||
type: command.type,
|
|
||||||
description: command.helpText,
|
|
||||||
options: Object.values(command.options),
|
|
||||||
defaultMemberPermissions: command.permissions,
|
|
||||||
dmPermission: !command.guildOnly,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const command of commands) {
|
|
||||||
if (interactionCommands.has(command.name)) continue;
|
|
||||||
|
|
||||||
await bot.deleteCommand(command.id);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
bot.on("error", (err) => {
|
bot.on("error", (err) => {
|
||||||
|
|
|
@ -1,26 +0,0 @@
|
||||||
const {ApplicationCommandTypes, ApplicationCommandOptionTypes} =
|
|
||||||
require("@projectdysnomia/dysnomia").Constants;
|
|
||||||
|
|
||||||
class InteractionCommand {
|
|
||||||
constructor(name) {
|
|
||||||
this.name = name;
|
|
||||||
this.type = ApplicationCommandTypes.CHAT_INPUT;
|
|
||||||
this.helpText = "No description provided.";
|
|
||||||
this.guildOnly = false;
|
|
||||||
this.options = {
|
|
||||||
send: {
|
|
||||||
type: ApplicationCommandOptionTypes.BOOLEAN,
|
|
||||||
name: "send",
|
|
||||||
description: "Should the output be ephemeral or not",
|
|
||||||
required: false,
|
|
||||||
default: true,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
callback() {
|
|
||||||
return "Callback not overwritten.";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = InteractionCommand;
|
|
|
@ -1,127 +0,0 @@
|
||||||
const logger = require("./logger.js");
|
|
||||||
const {MessageFlags} = require("@projectdysnomia/dysnomia").Constants;
|
|
||||||
const {pastelize, getTopColor} = require("./utils.js");
|
|
||||||
|
|
||||||
function getOption(interaction, command, key) {
|
|
||||||
return (
|
|
||||||
interaction.data.options?.find((o) => o.name === key)?.value ??
|
|
||||||
command.options[key].default
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
async function runCommand(interaction, command) {
|
|
||||||
if (command.ownerOnly && interaction.user.id != hf.config.owner_id) {
|
|
||||||
return {
|
|
||||||
content: "No\n\nSent from my iPhone.",
|
|
||||||
flags: MessageFlags.EPHEMERAL,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
|
||||||
command.elevatedOnly &&
|
|
||||||
!hf.config.elevated.includes(interaction.user.id)
|
|
||||||
) {
|
|
||||||
return {
|
|
||||||
content: "No\n\nSent from my iPhone.",
|
|
||||||
flags: MessageFlags.EPHEMERAL,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
const ret = command.callback(interaction);
|
|
||||||
if (ret instanceof Promise) {
|
|
||||||
return await ret;
|
|
||||||
} else {
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
logger.error("hf:cmd:" + command.name, err + "\n" + err.stack);
|
|
||||||
return {
|
|
||||||
content: ":warning: An internal error occurred.",
|
|
||||||
flags: MessageFlags.EPHEMERAL,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function InteractionDispatcher(interaction) {
|
|
||||||
const command = hf.interactionCommands.get(interaction.data.name);
|
|
||||||
const shouldSend = getOption(interaction, command, "send");
|
|
||||||
|
|
||||||
try {
|
|
||||||
const response = await runCommand(interaction, command);
|
|
||||||
if (response != null) {
|
|
||||||
if (response.file) {
|
|
||||||
const newFile = response.file;
|
|
||||||
delete response.file;
|
|
||||||
if (newFile.contents) {
|
|
||||||
newFile.file = newFile.contents;
|
|
||||||
delete newFile.contents;
|
|
||||||
}
|
|
||||||
if (newFile.name) {
|
|
||||||
newFile.filename = newFile.name;
|
|
||||||
delete newFile.name;
|
|
||||||
}
|
|
||||||
const files = response.attachments ?? [];
|
|
||||||
files.push(newFile);
|
|
||||||
response.attachments = files;
|
|
||||||
}
|
|
||||||
if (response.files) {
|
|
||||||
response.attachments = response.files;
|
|
||||||
delete response.files;
|
|
||||||
for (const attachment of response.attachments) {
|
|
||||||
if (attachment.contents) {
|
|
||||||
attachment.file = attachment.contents;
|
|
||||||
delete attachment.contents;
|
|
||||||
}
|
|
||||||
if (attachment.name) {
|
|
||||||
attachment.filename = attachment.name;
|
|
||||||
delete attachment.name;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (response.embed) {
|
|
||||||
response.embeds = [...(response.embeds ?? []), response.embed];
|
|
||||||
delete response.embed;
|
|
||||||
}
|
|
||||||
if (response.embeds) {
|
|
||||||
for (const embed of response.embeds) {
|
|
||||||
embed.color =
|
|
||||||
embed.color ??
|
|
||||||
getTopColor(interaction, hf.bot.user.id, pastelize(hf.bot.user.id));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
await interaction.createMessage(
|
|
||||||
Object.assign(
|
|
||||||
typeof response === "string" ? {content: response} : response,
|
|
||||||
{
|
|
||||||
flags: shouldSend ? response.flags : MessageFlags.EPHEMERAL,
|
|
||||||
allowedMentions: {
|
|
||||||
repliedUser: false,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
)
|
|
||||||
);
|
|
||||||
} catch (err) {
|
|
||||||
await interaction.createMessage({
|
|
||||||
content: `:warning: An error has occurred:\n\`\`\`${err}\`\`\``,
|
|
||||||
flags: MessageFlags.EPHEMERAL,
|
|
||||||
allowedMentions: {
|
|
||||||
repliedUser: false,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
await interaction.createMessage({
|
|
||||||
content: `:warning: An error has occurred:\n\`\`\`${err}\`\`\``,
|
|
||||||
flags: MessageFlags.EPHEMERAL,
|
|
||||||
allowedMentions: {
|
|
||||||
repliedUser: false,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = {InteractionDispatcher, getOption};
|
|
|
@ -28,7 +28,7 @@ async function processFile(link, spoiler = false) {
|
||||||
const file = await res.text();
|
const file = await res.text();
|
||||||
const lines = file.replace(/\r/g, "").split("\n");
|
const lines = file.replace(/\r/g, "").split("\n");
|
||||||
|
|
||||||
const fileName = decodeURI(link).substring(
|
const fileName = link.substring(
|
||||||
link.lastIndexOf("/") + 1,
|
link.lastIndexOf("/") + 1,
|
||||||
link.indexOf("#") == -1 ? link.length : link.indexOf("#")
|
link.indexOf("#") == -1 ? link.length : link.indexOf("#")
|
||||||
);
|
);
|
||||||
|
@ -155,3 +155,40 @@ events.add("messageCreate", "codePreviews", async function (msg) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// TODO: maybe all command outputs should have this ability
|
||||||
|
events.add(
|
||||||
|
"messageReactionAdd",
|
||||||
|
"codePreviews",
|
||||||
|
async function (msg, reaction, reactor) {
|
||||||
|
if (!msg.guildID) return;
|
||||||
|
if (!(await hasFlag(msg.guildID, "codePreviews"))) return;
|
||||||
|
if (reaction.name != "\u274c") return;
|
||||||
|
|
||||||
|
let channel = msg.channel;
|
||||||
|
if (!channel.name) {
|
||||||
|
channel = hf.bot.getChannel(channel.id);
|
||||||
|
}
|
||||||
|
if (!msg.messageReference) {
|
||||||
|
msg = await channel.getMessage(msg.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!msg.messageReference) return;
|
||||||
|
|
||||||
|
const ref = await channel.getMessage(msg.messageReference.messageID);
|
||||||
|
if (!ref) return;
|
||||||
|
if (
|
||||||
|
ref.author.id != reactor.id &&
|
||||||
|
!channel.permissionsOf(reactor.id).has("manageMessages")
|
||||||
|
)
|
||||||
|
return;
|
||||||
|
if (
|
||||||
|
!REGEX_GITHUB.test(ref.content) &&
|
||||||
|
!REGEX_GITLAB.test(ref.content) &&
|
||||||
|
!REGEX_GITEA.test(ref.content)
|
||||||
|
)
|
||||||
|
return;
|
||||||
|
|
||||||
|
await msg.delete("Author requested code preview deletion");
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
const {MessageFlags, ApplicationCommandOptionTypes} =
|
const {MessageFlags} = require("@projectdysnomia/dysnomia").Constants;
|
||||||
require("@projectdysnomia/dysnomia").Constants;
|
|
||||||
const fs = require("node:fs");
|
const fs = require("node:fs");
|
||||||
const path = require("node:path");
|
const path = require("node:path");
|
||||||
const httpSignature = require("@peertube/http-signature");
|
const httpSignature = require("@peertube/http-signature");
|
||||||
|
@ -8,8 +7,6 @@ const events = require("../lib/events.js");
|
||||||
const logger = require("../lib/logger.js");
|
const logger = require("../lib/logger.js");
|
||||||
const {hasFlag} = require("../lib/guildSettings.js");
|
const {hasFlag} = require("../lib/guildSettings.js");
|
||||||
const {parseHtmlEntities, getUploadLimit} = require("../lib/utils.js");
|
const {parseHtmlEntities, getUploadLimit} = require("../lib/utils.js");
|
||||||
const InteractionCommand = require("../lib/interactionCommand.js");
|
|
||||||
const {getOption} = require("../lib/interactionDispatcher.js");
|
|
||||||
|
|
||||||
const FRIENDLY_USERAGENT =
|
const FRIENDLY_USERAGENT =
|
||||||
"HiddenPhox/fedimbed (https://gitdab.com/Cynosphere/HiddenPhox)";
|
"HiddenPhox/fedimbed (https://gitdab.com/Cynosphere/HiddenPhox)";
|
||||||
|
@ -160,7 +157,7 @@ async function processUrl(msg, url, spoiler = false) {
|
||||||
invalidUrl = true;
|
invalidUrl = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (invalidUrl) return {};
|
if (invalidUrl) return;
|
||||||
|
|
||||||
// some lemmy instances have old reddit frontend subdomains
|
// some lemmy instances have old reddit frontend subdomains
|
||||||
// but these frontends are just frontends and dont actually expose the API
|
// but these frontends are just frontends and dont actually expose the API
|
||||||
|
@ -664,7 +661,7 @@ async function processUrl(msg, url, spoiler = false) {
|
||||||
"fedimbed",
|
"fedimbed",
|
||||||
`Bailing trying to re-embed "${url}": Failed to get author.`
|
`Bailing trying to re-embed "${url}": Failed to get author.`
|
||||||
);
|
);
|
||||||
return {};
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start constructing embed
|
// Start constructing embed
|
||||||
|
@ -809,16 +806,12 @@ async function processUrl(msg, url, spoiler = false) {
|
||||||
let sendWait = false;
|
let sendWait = false;
|
||||||
if (videos.length > 0 || audios.length > 0 || images.length > 4) {
|
if (videos.length > 0 || audios.length > 0 || images.length > 4) {
|
||||||
sendWait = true;
|
sendWait = true;
|
||||||
if (msg) await msg.addReaction("\uD83D\uDCE4");
|
await msg.addReaction("\uD83D\uDCE4");
|
||||||
}
|
}
|
||||||
|
|
||||||
const embeds = [];
|
const embeds = [];
|
||||||
const files = [];
|
const files = [];
|
||||||
|
|
||||||
const guild =
|
|
||||||
msg.channel?.guild ??
|
|
||||||
(msg.guildID ? hf.bot.guilds.get(msg.guildID) : false);
|
|
||||||
|
|
||||||
if (images.length > 0) {
|
if (images.length > 0) {
|
||||||
if (images.length <= 4) {
|
if (images.length <= 4) {
|
||||||
for (const attachment of images) {
|
for (const attachment of images) {
|
||||||
|
@ -837,7 +830,7 @@ async function processUrl(msg, url, spoiler = false) {
|
||||||
},
|
},
|
||||||
}).then((res) => Number(res.headers.get("Content-Length")));
|
}).then((res) => Number(res.headers.get("Content-Length")));
|
||||||
|
|
||||||
if (size <= getUploadLimit(guild)) {
|
if (size <= getUploadLimit(msg.channel.guild)) {
|
||||||
const file = await fetch(attachment.url, {
|
const file = await fetch(attachment.url, {
|
||||||
headers: {
|
headers: {
|
||||||
"User-Agent": FRIENDLY_USERAGENT,
|
"User-Agent": FRIENDLY_USERAGENT,
|
||||||
|
@ -871,7 +864,7 @@ async function processUrl(msg, url, spoiler = false) {
|
||||||
},
|
},
|
||||||
}).then((res) => Number(res.headers.get("Content-Length")));
|
}).then((res) => Number(res.headers.get("Content-Length")));
|
||||||
|
|
||||||
if (size <= getUploadLimit(guild)) {
|
if (size <= getUploadLimit(msg.channel.guild)) {
|
||||||
const file = await fetch(attachment.url, {
|
const file = await fetch(attachment.url, {
|
||||||
headers: {
|
headers: {
|
||||||
"User-Agent": FRIENDLY_USERAGENT,
|
"User-Agent": FRIENDLY_USERAGENT,
|
||||||
|
@ -944,7 +937,7 @@ async function processUrl(msg, url, spoiler = false) {
|
||||||
},
|
},
|
||||||
}).then((res) => Number(res.headers.get("Content-Length")));
|
}).then((res) => Number(res.headers.get("Content-Length")));
|
||||||
|
|
||||||
if (size <= getUploadLimit(guild)) {
|
if (size <= getUploadLimit(msg.channel.guild)) {
|
||||||
const file = await fetch(attachment.url, {
|
const file = await fetch(attachment.url, {
|
||||||
headers: {
|
headers: {
|
||||||
"User-Agent": FRIENDLY_USERAGENT,
|
"User-Agent": FRIENDLY_USERAGENT,
|
||||||
|
@ -975,7 +968,7 @@ async function processUrl(msg, url, spoiler = false) {
|
||||||
},
|
},
|
||||||
}).then((res) => Number(res.headers.get("Content-Length")));
|
}).then((res) => Number(res.headers.get("Content-Length")));
|
||||||
|
|
||||||
if (size <= getUploadLimit(guild)) {
|
if (size <= getUploadLimit(msg.channel.guild)) {
|
||||||
const file = await fetch(attachment.url, {
|
const file = await fetch(attachment.url, {
|
||||||
headers: {
|
headers: {
|
||||||
"User-Agent": FRIENDLY_USERAGENT,
|
"User-Agent": FRIENDLY_USERAGENT,
|
||||||
|
@ -1002,8 +995,8 @@ async function processUrl(msg, url, spoiler = false) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
await msg.channel
|
||||||
response: {
|
.createMessage({
|
||||||
content:
|
content:
|
||||||
cw != "" &&
|
cw != "" &&
|
||||||
(images.length > 0 || videos.length > 0 || audios.length > 0)
|
(images.length > 0 || videos.length > 0 || audios.length > 0)
|
||||||
|
@ -1019,9 +1012,16 @@ async function processUrl(msg, url, spoiler = false) {
|
||||||
messageReference: {
|
messageReference: {
|
||||||
messageID: msg.id,
|
messageID: msg.id,
|
||||||
},
|
},
|
||||||
},
|
})
|
||||||
sendWait,
|
.then(() => {
|
||||||
};
|
if (sendWait) {
|
||||||
|
msg.removeReaction("\uD83D\uDCE4");
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((msg.flags & MessageFlags.SUPPRESS_EMBEDS) === 0) {
|
||||||
|
msg.edit({flags: MessageFlags.SUPPRESS_EMBEDS}).catch(() => {});
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
events.add("messageCreate", "fedimbed", async function (msg) {
|
events.add("messageCreate", "fedimbed", async function (msg) {
|
||||||
|
@ -1054,100 +1054,15 @@ events.add("messageCreate", "fedimbed", async function (msg) {
|
||||||
"fedimbed",
|
"fedimbed",
|
||||||
`Hit "${service}" for "${url}", processing now.`
|
`Hit "${service}" for "${url}", processing now.`
|
||||||
);
|
);
|
||||||
try {
|
await processUrl(msg, url, hasSpoiler).catch((err) => {
|
||||||
const {response, sendWait} = await processUrl(msg, url, hasSpoiler);
|
|
||||||
await msg.channel.createMessage(response).then(() => {
|
|
||||||
if (sendWait) {
|
|
||||||
msg.removeReaction("\uD83D\uDCE4");
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((msg.flags & MessageFlags.SUPPRESS_EMBEDS) === 0) {
|
|
||||||
msg.edit({flags: MessageFlags.SUPPRESS_EMBEDS}).catch(() => {});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} catch (err) {
|
|
||||||
logger.error(
|
logger.error(
|
||||||
"fedimbed",
|
"fedimbed",
|
||||||
`Error processing "${url}":\n` + err.stack
|
`Error processing "${url}":\n` + err.stack
|
||||||
);
|
);
|
||||||
}
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const fedimbedCommand = new InteractionCommand("fedimbed");
|
|
||||||
fedimbedCommand.helpText =
|
|
||||||
"Better embeds for fediverse (Mastodon, Pleroma, etc) posts";
|
|
||||||
fedimbedCommand.options.url = {
|
|
||||||
name: "url",
|
|
||||||
type: ApplicationCommandOptionTypes.STRING,
|
|
||||||
description: "URL to attempt to parse for re-embedding",
|
|
||||||
required: true,
|
|
||||||
default: "",
|
|
||||||
};
|
|
||||||
fedimbedCommand.options.spoiler = {
|
|
||||||
name: "spoiler",
|
|
||||||
type: ApplicationCommandOptionTypes.BOOLEAN,
|
|
||||||
description: "Send embed spoilered",
|
|
||||||
required: false,
|
|
||||||
default: false,
|
|
||||||
};
|
|
||||||
fedimbedCommand.callback = async function (interaction) {
|
|
||||||
let url = getOption(interaction, fedimbedCommand, "url");
|
|
||||||
const spoiler = getOption(interaction, fedimbedCommand, "spoiler");
|
|
||||||
|
|
||||||
url = url
|
|
||||||
.replace(/\|/g, "")
|
|
||||||
.replace(/^\]\(/, "")
|
|
||||||
.replace(/\s*[\S]*?\)$/, "")
|
|
||||||
.trim()
|
|
||||||
.replace("@\u200b", "@")
|
|
||||||
.replace("@%E2%80%8B", "@");
|
|
||||||
let urlObj;
|
|
||||||
try {
|
|
||||||
urlObj = new URL(url);
|
|
||||||
} catch (err) {
|
|
||||||
return {
|
|
||||||
content: `Failed to parse URL:\`\`\`\n${err}\`\`\``,
|
|
||||||
flags: MessageFlags.EPHEMERAL,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
let hasService = false;
|
|
||||||
for (const service of Object.keys(PATH_REGEX)) {
|
|
||||||
const regex = PATH_REGEX[service];
|
|
||||||
if (urlObj && regex.test(urlObj.pathname)) {
|
|
||||||
hasService = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hasService) {
|
|
||||||
try {
|
|
||||||
const {response} = await processUrl(interaction, url, spoiler);
|
|
||||||
|
|
||||||
if (!response)
|
|
||||||
return {
|
|
||||||
content: "Failed to process URL.",
|
|
||||||
flags: MessageFlags.EPHEMERAL,
|
|
||||||
};
|
|
||||||
|
|
||||||
delete response.messageReference;
|
|
||||||
return response;
|
|
||||||
} catch (err) {
|
|
||||||
logger.error("fedimbed", `Error processing "${url}":\n` + err.stack);
|
|
||||||
return {
|
|
||||||
content: "Failed to process URL.",
|
|
||||||
flags: MessageFlags.EPHEMERAL,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return {
|
|
||||||
content: "Did not get a valid service for this URL.",
|
|
||||||
flags: MessageFlags.EPHEMERAL,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
Loading…
Reference in a new issue