diff options
Diffstat (limited to 'bot/index.ts')
| -rw-r--r-- | bot/index.ts | 91 |
1 files changed, 79 insertions, 12 deletions
diff --git a/bot/index.ts b/bot/index.ts index e3a2c6a..2c8bfd2 100644 --- a/bot/index.ts +++ b/bot/index.ts @@ -1,13 +1,16 @@ import { Client, Events, GatewayIntentBits } from 'discord.js'; +import removeMd from 'remove-markdown'; +import { writeFileSync, mkdirSync, rmSync } from 'fs'; +import { marked } from 'marked'; import { Database } from "bun:sqlite"; const client = new Client({ intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMembers, GatewayIntentBits.GuildMessages, GatewayIntentBits.MessageContent] }); -const db = new Database("../database.sqlite", { create: true }); +const db = new Database(process.env.DB_LOCATION, { create: true }); function parseMessage(content: string) { const lines = content.split('\n'); const authorMatch = content.match(/\*from(?: the)? ([^*]+)\*/i); - const titleLine = lines.slice(0, 2).find(l => /^#+\s+.+|^.+\*\*[^*]+\*\*$/.test(l)) ?? null; + const titleLine = lines.slice(0, 2).find(l => /^#+\s+.+|^\*\*.+\*\*|^.+\*\*[^*]+\*\*$/.test(l)) ?? null; const author = authorMatch ? authorMatch[1].trim() : null; const title = titleLine ? titleLine.replace(/^#+\s+/, '').replace(/\*\*/g, '').trim() : null; @@ -33,28 +36,67 @@ client.on(Events.ClientReady, bot => { message TEXT, created_at INTEGER )`); + + db.run(`CREATE TABLE IF NOT EXISTS announcements_attachments ( + id INTEGER PRIMARY KEY, + msg_id INTERGER, + file_name TEXT + )`); + + db.run(`CREATE TABLE IF NOT EXISTS exclude_person ( + id INTEGER PRIMARY KEY, + user_id INTERGER + )`); } catch (e) { console.error(e); } }); client.on(Events.MessageCreate, async (msg) => { + const query = db.prepare('SELECT * FROM exclude_person WHERE user_id = ?'); + const result = query.get(msg.author.id); + if (result) return; + if (msg.author.bot) return; - if (msg.author.id === client.user!.id) return; + if (msg.channel.id !== process.env.ANNOUNCEMENT_CHANNEL) return; - if (!(msg.content.startsWith('# ') || msg.content.startsWith('*') || msg.content.match(/^:[a-z0-9_]+:/i) || msg.content.match(/^\p{Emoji}/u))) return; + if (!(msg.content.startsWith('#') || msg.content.startsWith('*') || msg.content.match(/^:[a-z0-9_]+:/i) || msg.content.match(/^\p{Emoji}/u))) return; const { title, author, message } = parseMessage(msg.content); + if (!title || !author || !message) return; + try { const insert = db.prepare(`INSERT INTO announcements (title, msg_id, author, message, created_at) VALUES (($title), ($msg_id), ($author), ($message), ($created_at))`); insert.run({ - $title: title, + $title: removeMd(title), $msg_id: msg.id, - $author: author, - $message: message, + $author: removeMd(author), + $message: await marked(message), $created_at: msg.createdTimestamp.toString() }) + + if (msg.attachments.size > 0) { + try { + mkdirSync(`../public/images/${msg.id}`, { recursive: true }); + + for (const a of msg.attachments.values()) { + const response = await fetch(a.url); + const buffer = Buffer.from(await response.arrayBuffer()); + writeFileSync(`../public/images/${msg.id}/${a.name}`, buffer); + + const insert = db.prepare(`INSERT INTO announcements_attachments (msg_id, file_name) VALUES ($msg_id, $file_name)`); + insert.run({ + $msg_id: msg.id, + $file_name: a.name + }); + } + } catch (e) { + console.error(e); + return; + } + } + } catch (e) { console.error(e); } @@ -64,19 +106,34 @@ client.on(Events.MessageCreate, async (msg) => { client.on(Events.MessageUpdate, async (msg, msgnew) => { if (!msg.author) return; if (!msg.content) return; + if (msg.author.bot) return; - if (msg.author.id === client.user!.id) return; if (msg.channel.id !== process.env.ANNOUNCEMENT_CHANNEL) return; - if (!(msgnew.content.startsWith('# ') || msgnew.content.startsWith('*') || msgnew.content.match(/^:[a-z0-9_]+:/i) || msgnew.content.match(/^\p{Emoji}/u))) return; + if (!(msgnew.content.startsWith('#') || msgnew.content.startsWith('*') || msgnew.content.match(/^:[a-z0-9_]+:/i) || msgnew.content.match(/^\p{Emoji}/u))) return; const { title, author, message } = parseMessage(msgnew.content); + if (!title || !author || !message) return; + + try { + const removedAttachments = msg.attachments.filter(a => !msgnew.attachments.has(a.id)); + + for (const a of removedAttachments.values()) { + const deleteAttachment = db.prepare(`DELETE FROM announcements_attachments WHERE msg_id = ($msg_id) AND file_name = ($file_name)`); + deleteAttachment.run({ + $msg_id: msg.id, + $file_name: a.name + }); + } + } catch (e) { + console.error(e); + } try { const update = db.prepare(`UPDATE announcements SET title = ($title), author = ($author), message = ($message) WHERE msg_id = ($msg_id)`); update.run({ - $title: title, - $author: author, - $message: message, + $title: removeMd(title), + $author: removeMd(author), + $message: await marked(message), $msg_id: msg.id }) } catch (e) { @@ -89,6 +146,7 @@ client.on(Events.MessageDelete, async (msg) => { if (!msg.author) return; if (!msg.content) return; if (msg.author.bot) return; + if (msg.author.id === client.user!.id) return; if (msg.channel.id !== process.env.ANNOUNCEMENT_CHANNEL) return; @@ -97,6 +155,15 @@ client.on(Events.MessageDelete, async (msg) => { deleteAnnouncement.run({ $msg_id: msg.id }) + + if (msg.attachments.size > 0) { + const deleteAttachment = db.prepare(`DELETE FROM announcements_attachments WHERE msg_id = ($msg_id)`); + deleteAttachment.run({ + $msg_id: msg.id + }); + + rmSync(`../public/images/${msg.id}`, { recursive: true }); + } } catch (e) { console.error(e); } |
