foxwells: add vinboard
This commit is contained in:
parent
57d1a3d76a
commit
cb00a01da3
1 changed files with 205 additions and 0 deletions
|
@ -1,7 +1,11 @@
|
||||||
const Command = require("../lib/command.js");
|
const Command = require("../lib/command.js");
|
||||||
|
const events = require("../lib/events.js");
|
||||||
|
|
||||||
const CATEGORY = "misc";
|
const CATEGORY = "misc";
|
||||||
|
const FOXWELLS_GUILD_ID = "300436792916836352";
|
||||||
|
|
||||||
const {tinycolor} = require("@ctrl/tinycolor");
|
const {tinycolor} = require("@ctrl/tinycolor");
|
||||||
|
const {pastelize, getTopColor} = require("../lib/utils.js");
|
||||||
|
|
||||||
const logger = require("../lib/logger.js");
|
const logger = require("../lib/logger.js");
|
||||||
|
|
||||||
|
@ -101,3 +105,204 @@ plant.callback = async function () {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
hf.registerCommand(plant);
|
hf.registerCommand(plant);
|
||||||
|
|
||||||
|
/* vinboard */
|
||||||
|
const VINBOARD_CHANNEL_ID = "770879461871714324";
|
||||||
|
const VINBOARD_THREAD_ID = "1048462330201124935";
|
||||||
|
const VINBOARD_WEBHOOK_ID = "1048471543287660665";
|
||||||
|
|
||||||
|
hf.database.run(
|
||||||
|
"CREATE TABLE IF NOT EXISTS vinboard (message_id STRING NOT NULL PRIMARY KEY, count INTEGER NOT NULL, board_id STRING NOT NULL) WITHOUT ROWID"
|
||||||
|
);
|
||||||
|
|
||||||
|
function getBoardEntry(id) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
hf.database.get(
|
||||||
|
"SELECT message_id,count,board_id FROM vinboard WHERE message_id = $id",
|
||||||
|
{
|
||||||
|
$id: id,
|
||||||
|
},
|
||||||
|
(err, row) => {
|
||||||
|
if (err == null) {
|
||||||
|
resolve(
|
||||||
|
row?.message_id
|
||||||
|
? {count: row?.count, board_id: row?.board_id}
|
||||||
|
: null
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
reject(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
function setBoardEntry(id, count, board_id) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
hf.database.run(
|
||||||
|
"REPLACE INTO vinboard VALUES ($id,$count,$board_id)",
|
||||||
|
{
|
||||||
|
$id: id,
|
||||||
|
$count: count,
|
||||||
|
$board_id: board_id,
|
||||||
|
},
|
||||||
|
(err) => {
|
||||||
|
if (err == null) {
|
||||||
|
resolve(true);
|
||||||
|
} else {
|
||||||
|
reject(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
function deleteBoardEntry(id) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
hf.database.run(
|
||||||
|
"DELETE FROM vinboard WHERE message_id = $id",
|
||||||
|
{
|
||||||
|
$id: id,
|
||||||
|
},
|
||||||
|
(err) => {
|
||||||
|
if (err == null) {
|
||||||
|
resolve(true);
|
||||||
|
} else {
|
||||||
|
reject(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function findSuitableImage(msg) {
|
||||||
|
const out = {};
|
||||||
|
|
||||||
|
const attachments = [...msg.attachments.values()];
|
||||||
|
const attachment = attachments[0];
|
||||||
|
|
||||||
|
if (attachment) {
|
||||||
|
const url = attachment.url;
|
||||||
|
if (/(jpe?g|png|gif|webp)$/.test(url)) {
|
||||||
|
out.url = url;
|
||||||
|
} else if (/(mp4|webm|mov)$/.test(url)) {
|
||||||
|
out.video = true;
|
||||||
|
out.attachment = true;
|
||||||
|
out.url = "attachment://thumb.jpg";
|
||||||
|
out.file = await fetch(attachment.proxy_url)
|
||||||
|
.then((res) => res.arrayBuffer())
|
||||||
|
.then((buf) => Buffer.from(buf));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const embed of msg.embeds) {
|
||||||
|
if (!embed.url) continue;
|
||||||
|
if (embed.image) {
|
||||||
|
out.url = embed.image.url;
|
||||||
|
break;
|
||||||
|
} else if (embed.video) {
|
||||||
|
out.video = true;
|
||||||
|
out.url = "attachment://thumb.jpg";
|
||||||
|
out.file = await fetch(embed.video.proxy_url)
|
||||||
|
.then((res) => res.arrayBuffer())
|
||||||
|
.then((buf) => Buffer.from(buf));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function createBoardMessage(msg, count) {
|
||||||
|
const embed = {
|
||||||
|
title: `${count} \u2b50`,
|
||||||
|
color: getTopColor(msg, msg.author.id, pastelize(msg.author.id)),
|
||||||
|
description: msg.content,
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
name: "Jump Link",
|
||||||
|
value: `[Jump](${msg.jumpLink})`,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
timestamp: msg.timestamp,
|
||||||
|
};
|
||||||
|
|
||||||
|
const image = await findSuitableImage(msg);
|
||||||
|
if (image.url) {
|
||||||
|
if (image.video) {
|
||||||
|
embed.description += `\n(contains video ${
|
||||||
|
out.attachment ? "attachment" : "embed"
|
||||||
|
})`;
|
||||||
|
}
|
||||||
|
embed.image = {
|
||||||
|
url: image.url,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
avatarURL: msg.member.avatarURL("png", 256),
|
||||||
|
username: msg.member.displayName,
|
||||||
|
threadID: VINBOARD_THREAD_ID,
|
||||||
|
threadName: "Vinboard",
|
||||||
|
embeds: [embed],
|
||||||
|
attachments: image.file ? {file: image.file, filename: "thumb.jpg"} : null,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
let vinboard_webhook;
|
||||||
|
async function processReaction(msg, user, reaction) {
|
||||||
|
if (msg.guildID != FOXWELLS_GUILD_ID) return;
|
||||||
|
if (msg.channel.id != VINBOARD_CHANNEL_ID) return;
|
||||||
|
if (user.bot) return;
|
||||||
|
if (reaction.name != "\u2b50") return;
|
||||||
|
|
||||||
|
if (!vinboard_webhook) {
|
||||||
|
const webhooks = await msg.channel.getWebhooks();
|
||||||
|
vinboard_webhook = webhooks.find(
|
||||||
|
(webhook) => webhook.id == VINBOARD_WEBHOOK_ID
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!vinboard_webhook) {
|
||||||
|
logger.error("vinboard", "Failed to get webhook.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const reacts = await msg.getReactions("\u2b50");
|
||||||
|
const trueCount = reacts.filter(
|
||||||
|
(reactor) => reactor.id != msg.author.id
|
||||||
|
).length;
|
||||||
|
|
||||||
|
const dbEntry = getBoardEntry(msg.id);
|
||||||
|
if (dbEntry) {
|
||||||
|
if (trueCount == 0) {
|
||||||
|
logger.verbose("vinboard", `Deleting entry for "${msg.id}"`);
|
||||||
|
if (dbEntry.board_id) {
|
||||||
|
await webhook.deleteMessage(
|
||||||
|
dbEntry.board_id,
|
||||||
|
"[Vinboard] Message has 0 reactions now."
|
||||||
|
);
|
||||||
|
await deleteBoardEntry(msg.id);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
logger.verbose(
|
||||||
|
"vinboard",
|
||||||
|
`Updating count for "${msg.id}" (${dbEntry.count ?? 0} -> ${trueCount})`
|
||||||
|
);
|
||||||
|
if (dbEntry.board_id) {
|
||||||
|
await webhook.editMessage(
|
||||||
|
dbEntry.board_id,
|
||||||
|
await createBoardMessage(msg, trueCount)
|
||||||
|
);
|
||||||
|
await setBoardEntry(msg.id, trueCount, dbEntry.board_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
logger.verbose("vinboard", `Creating entry for "${msg.id}"`);
|
||||||
|
const boardMessage = await webhook.execute(
|
||||||
|
await createBoardMessage(msg, trueCount)
|
||||||
|
);
|
||||||
|
await setBoardEntry(msg.id, trueCount, boardMessage.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
events.add("messageReactionAdd", "vinboard", processReaction);
|
||||||
|
events.add("messageReactionRemove", "vinboard", processReaction);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue