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 events = require("../lib/events.js");
 | 
			
		||||
 | 
			
		||||
const CATEGORY = "misc";
 | 
			
		||||
const FOXWELLS_GUILD_ID = "300436792916836352";
 | 
			
		||||
 | 
			
		||||
const {tinycolor} = require("@ctrl/tinycolor");
 | 
			
		||||
const {pastelize, getTopColor} = require("../lib/utils.js");
 | 
			
		||||
 | 
			
		||||
const logger = require("../lib/logger.js");
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -101,3 +105,204 @@ plant.callback = async function () {
 | 
			
		|||
  }
 | 
			
		||||
};
 | 
			
		||||
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