// server and discord in one import { Client, Events, GatewayIntentBits } from "npm:discord.js"; import { createCanvas } from "https://deno.land/x/canvas/mod.ts"; import { contentType } from "https://deno.land/std@0.202.0/media_types/mod.ts"; import config from "./config.json" with { type: "json" }; type Message = { author: string; content: string; id: string }; const kv = await Deno.openKv(); let messages = (await kv.get(["messages"])).value ?? []; const client = new Client({ intents: [ GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages, GatewayIntentBits.MessageContent, ], }); client.once(Events.ClientReady, (c) => { console.log(`logged in as ${c.user.tag}`); }); client.login(config.token); // we don't need to await! function update_messages() { kv.set(["messages"], messages); } function add_message(msg: Message) { messages.push(msg); update_messages(); } function delete_message(id: string) { messages = messages.filter((m) => m.id != id); update_messages(); } client.on(Events.MessageCreate, (message) => { if (message.channel.name != "effector") return; add_message({ author: message.author.username, content: message.content, id: message.id, }); console.log("added", messages); }); client.on(Events.MessageDelete, (message) => { delete_message(message.id); console.log("deleted", message.id, messages); }); const canvas = createCanvas(1025, 612); const ctx = canvas.getContext("2d"); const default_fill = "#3B0920"; const bg_fill = "#FFE8D4"; const border_stroke = "#83254F"; function clear_canvas() { ctx.fillStyle = bg_fill; ctx.strokeStyle = border_stroke; ctx.lineWidth = 10; ctx.fillRect(0, 0, 1025, 612); ctx.strokeRect(0, 0, 1025, 612); } function draw_message(x: number, y: number, message: Message) { ctx.fillStyle = "#FFAB5C"; ctx.fillText(message.author, x, y); ctx.fillStyle = default_fill; console.log(message); ctx.fillText( message.content == "" ? "[empty message]" : message.content, x + ctx.measureText(message.author).width + 5, y, ); } Deno.serve({ port: 61263 }, () => { const most_recent = messages.slice(-40); clear_canvas(); most_recent.forEach((msg, i) => { draw_message(13, 17 + i * 15, msg); }); return new Response(canvas.toBuffer(), { headers: { "Content-Type": contentType("png") }, }); });