import { Plugin, Event, BotEventData, Command, ICommandData } from "src/model/plugin"; import { readdirSync, statSync } from "fs"; import { join, basename, extname } from "path"; import { Message } from "discord.js"; import { tryDo } from "src/util"; import { logger } from "src/logging"; const STICKERS_PATH = "./stickers"; const STICKERS_PREFIX = "!"; const STICKERS_PER_ROW = 5; const ROWS_PER_MESSAGE = 30; @Plugin export class Stickers { stickers: Record = {}; @Event("message") async onMessage(data: BotEventData, msg: Message): Promise { if (data.actionsDone) return; const lowerContent = msg.cleanContent.trim().toLowerCase(); if (!lowerContent.startsWith(STICKERS_PREFIX)) return; const stickerName = lowerContent.substr(1); if (!(stickerName in this.stickers)) return; const deleteResult = await tryDo(msg.delete()); if (!deleteResult.ok) { logger.error("Stickers: failed to delete message %s from user %s. Reason: %s", msg.id, msg.author.id, deleteResult.error); } const sendResult = await tryDo(msg.channel.send(`${msg.author.toString()} *sent a sticker:*`, { files: [this.stickers[stickerName]] })); if (!sendResult.ok) { logger.error("Stickers: failed to send sticker to channel %s. Reason: %s", msg.channel.id, sendResult.error); } data.actionsDone = true; } @Command({ type: "mention", pattern: "stickers", auth: false, documentation: { description: "Lists all available stickers", example: "stickers" } }) async listStickers({ message }: ICommandData): Promise { const m = Object.keys(this.stickers) .filter(s => Object.prototype.hasOwnProperty.call(this.stickers, s)) .reduce((prev, cur, i) => `${prev} !${cur}${i != 0 && i % STICKERS_PER_ROW == 0 ? "\n" : ""}`, ""); let toSend = `${message.author.toString()}, I have the following stickers:\n\`\`\``; const rows = m.split("\n"); for (let i = 0; i < rows.length; i++) { toSend += `${rows[i]}\n`; if (i != 0 && i % ROWS_PER_MESSAGE == 0) { toSend += "```"; await message.channel.send(toSend); toSend = "```\n"; } } toSend += "```\n"; toSend += "To use stickers, simply use their name. Example: !hackermaid"; await message.channel.send(toSend); } async start(): Promise { const files = readdirSync(STICKERS_PATH).filter(f => !statSync(join(STICKERS_PATH, f)).isDirectory()); for (const file of files) this.stickers[basename(file, extname(file)).toLowerCase()] = join(STICKERS_PATH, file); logger.info("Found %s stickers", Object.keys(this.stickers).length); } }