import { Message } from "discord.js"; import got from "got"; import { logger } from "src/logging"; import { Command, ICommandData, Plugin } from "src/model/plugin"; import { tryDo } from "@shared/common/async_utils"; import Jimp from "jimp"; const rcgRe = /
\s*\s*\s*\s*<\/div>/gi; interface XkcdResponse { img: string; } @Plugin export class Rcg { async sendErrorMessage(msg: Message): Promise { const xkcdResult = await tryDo(got.get("https://xkcd.com/info.0.json", { responseType: "json" })); if(!xkcdResult.ok || !xkcdResult.result) { await msg.reply("sorry, I couldn't get any comics :(."); return; } await msg.reply("sorry, I couldn't get a random comic! Here is today's XKCD instead:", { files: [ xkcdResult.result.body.img ] }); } @Command({ type: "mention", pattern: "random comic", auth: false, documentation: {description: "Generates a comic just for you!", example: "random comic"} }) async randomComic({ message }: ICommandData): Promise { const result = await tryDo(got.get("http://explosm.net/rcg/view/?promo=false")); if (!result.ok) { logger.error("Failed to get RCG. Got error: %s", result.error); await this.sendErrorMessage(message); return; } const regexResult = rcgRe.exec(result.result.body); if(!regexResult || regexResult.length == 0) { logger.error("Could not find RCG from body. Got response body: %s", result.result.body); await this.sendErrorMessage(message); return; } const panelUrls = [regexResult[1], regexResult[2], regexResult[3]]; const panels = []; let totalWidth = 0; let maxHeight = 0; for (const panelUrl of panelUrls) { const panelImgResult = await tryDo(Jimp.read(panelUrl)); if (!panelImgResult.ok) { logger.error("Failed to download panel %s", panelUrl); await this.sendErrorMessage(message); return; } const img = panelImgResult.result; const [w, h] = [ img.getWidth(), img.getHeight() ]; panels.push(img); totalWidth += w; if (h > maxHeight) { maxHeight = h; } } const PADDING = 5; let newImg = await Jimp.create(PADDING * 4 + totalWidth, PADDING * 2 + maxHeight, "white"); let curX = PADDING; for (const panel of panels) { newImg = await newImg.blit(panel, curX, PADDING); curX += panel.getWidth() + PADDING; } newImg.quality(80); const buffer = await newImg.getBufferAsync(Jimp.MIME_JPEG); const messagePostResult = await tryDo(message.reply("I find this very funny:", { files: [ buffer ] })); if (!messagePostResult.ok) { logger.error("Failed to get RCG. Got error: %s", messagePostResult.error); await this.sendErrorMessage(message); } } }