aboutsummaryrefslogtreecommitdiff
path: root/bot/index.ts
blob: e3a2c6a0261aa8a1823441bed4a9edf8dc6d8637 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
import { Client, Events, GatewayIntentBits } from 'discord.js';
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 });

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 author = authorMatch ? authorMatch[1].trim() : null;
    const title = titleLine ? titleLine.replace(/^#+\s+/, '').replace(/\*\*/g, '').trim() : null;
    const message = lines
        .filter(l => l !== titleLine)
        .join('\n')
        .replace(/\*from(?: the)? [^*]+\*\n?/i, '')
        .trimStart();

    return { author, title, message };
}

client.on(Events.ClientReady, bot => {
  console.log(`Logged in as ${bot.user.tag}!`);
  client.user?.setStatus('invisible');

  try {
    db.run(`CREATE TABLE IF NOT EXISTS announcements (
                    id INTEGER PRIMARY KEY,
                    msg_id INTERGER,
                    title TEXT,
                    author TEXT,
                    message TEXT,
                    created_at INTEGER
                )`);
  } catch (e) {
    console.error(e);
  }
});

client.on(Events.MessageCreate, async (msg) => {
  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;

  const { title, author, message } = parseMessage(msg.content);

  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,
        $msg_id: msg.id,
        $author: author,
        $message: message,
        $created_at: msg.createdTimestamp.toString()
    })
  } catch (e) {
    console.error(e);
  }

});

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;

  const { title, author, message } = parseMessage(msgnew.content);

  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,
        $msg_id: msg.id
    })
  } catch (e) {
    console.error(e);
  }

});

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;

  try {
    const deleteAnnouncement = db.prepare(`DELETE FROM announcements WHERE msg_id = ($msg_id)`);
    deleteAnnouncement.run({
        $msg_id: msg.id
    })
  } catch (e) {
    console.error(e);
  }

});

client.login(process.env.TOKEN);