aboutsummaryrefslogtreecommitdiff
path: root/app.js
blob: 59525d53c75e25b706aff632b3a745f8916263ec (plain)
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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
import "dotenv/config";
import express from "express";
import {
    InteractionType,
    InteractionResponseType,
    verifyKeyMiddleware,
} from "discord-interactions";
import { Client, GatewayIntentBits, ActivityType } from "discord.js";
import {
    blep,
    help,
    pet,
    schedule_message,
    catfact,
    fomx,
    factcheck,
} from "./command_impls.js";
import { MessageSchedule } from "./message-scheduler.js";

class State {
    constructor() {
        this.job_db = "jobs.json";
        this.client = new Client({ intents: [GatewayIntentBits.Guilds] });
    }
}

function handle_application_command(state, data, channel_id) {
    const { name, options } = data;

    switch (name) {
        case "schedule_message":
            return schedule_message(
                state,
                options[0].value,
                channel_id,
                options[1].value,
            );

        case "pet":
            return pet(state);

        case "help":
            return help(state);

        case "blep":
            return blep(state);

        case "catfact":
            return catfact(state);

        case "fomx":
            return fomx(state);

        case "factcheck":
            if (options && options.length >= 1)
                return factcheck(state, options[0].value);
            else return factcheck(state, True);

        default:
            console.error(`unknown command: ${name}`);
            return state.res.status(400).json({ error: "unknown command" });
    }
}

function handle_button_press(state, data) {
    if (data.custom_id.startsWith("stop-")) {
        state.schedule.unschedule(data.custom_id.slice(5));

        return state.res.send({
            type: InteractionResponseType.CHANNEL_MESSAGE_WITH_SOURCE,
            data: {
                content: "no longer sending this message",
            },
        });
    }
    return res.status(400).json({ error: "unknown command" });
}

function main() {
    const state = new State();

    state.client.on("ready", () => {
        console.log(`Logged in as ${state.client.user.tag}!`);
        state.schedule = new MessageSchedule(state);
        state.client.user.setPresence({
            activities: [
                {
                    name: "sily",
                    type: ActivityType.Playing,
                },
            ],
            status: "idle",
        });
    });

    state.client.login(process.env.DISCORD_TOKEN);

    const app = express();
    const PORT = process.env.PORT || 3000;

    app.post(
        "/",
        verifyKeyMiddleware(process.env.PUBLIC_KEY),
        async (req, res) => {
            const { type, data, channel_id } = req.body;

            state.res = res;
            switch (type) {
                case InteractionType.PING:
                    return res.send({ type: InteractionResponseType.PONG });
                case InteractionType.APPLICATION_COMMAND:
                    return handle_application_command(state, data, channel_id);
                case InteractionType.MESSAGE_COMPONENT:
                    return handle_button_press(state, data);
                default:
                    console.error("unknown interaction type", type);
                    return res
                        .status(400)
                        .json({ error: "unknown interaction type" });
            }
        },
    );

    app.listen(PORT, () => {
        console.log("Listening on port", PORT);
    });
}

main();