aboutsummaryrefslogtreecommitdiff
path: root/app.js
blob: eea4265797e7522234d1b021658b740c9a65f287 (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
import 'dotenv/config';
import express from 'express';
import cron from 'node-cron';
import {
  InteractionType,
  InteractionResponseType,
  verifyKeyMiddleware,
} from 'discord-interactions';
import { Client, GatewayIntentBits } from 'discord.js';
import fs from 'node:fs';
import { v4 as uuidv4 } from 'uuid';

const client = new Client ({ intents: [GatewayIntentBits.Guilds] });
var jobs = {};
const job_crons = {};
client.on('ready', () => {
    console.log(`Logged in as ${client.user.tag}!`);
    fs.readFile('jobs.json', 'utf8', (err,data) => {
        jobs = err ? {} : JSON.parse(data);

        Object.keys(jobs).forEach((job) => {
            job_crons[job] = cron.schedule(jobs[job].crontab, () => {
                client.channels.cache.get(jobs[job].channel_id).send(jobs[job].message);
            });
        });
    });
});

client.login(process.env.DISCORD_TOKEN);

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

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

  if (type === InteractionType.PING) {
    return res.send({ type: InteractionResponseType.PONG });
  }

  if (type === InteractionType.APPLICATION_COMMAND) {
      const { name, options, guild_id } = data;

      if (name === 'schedule_message') {
          const message = options[0].value;
          const crontab = options[1].value;
          const valid = cron.validate(crontab);
          const id = uuidv4();

          const content = valid ? `registered message: "${message}" with cron: "${crontab}" and id: "${id}"` : 'invalid cron';

          if (valid) {
              jobs[id] = {
                  message: message,
                  crontab: crontab,
                  channel_id: req.body.channel_id,
              };
              job_crons[id] = cron.schedule(crontab, () => {
                  client.channels.cache.get(req.body.channel_id).send(message);
              });

              const json = JSON.stringify(jobs);
              fs.writeFile('jobs.json', json, 'utf8', err => {
                  if (err) {
                      console.error(err);
                  }
              });
           }

          return res.send({
              type: InteractionResponseType.CHANNEL_MESSAGE_WITH_SOURCE,
              data: {
                  content: content,
              },
          });
      } else if (name === 'unschedule_message') {
          const id = options[0].value;
          const content = id in jobs ? `stopped job ${id}` : `no such job ${id}`;
          if (id in jobs) {
              job_crons[id].stop();
              delete jobs[id]
              delete job_crons[id];

              const json = JSON.stringify(jobs);
              fs.writeFile('jobs.json', json, 'utf8', err => {
                  if (err) {
                      console.error(err);
                  }
              });
          }

          return res.send({
              type: InteractionResponseType.CHANNEL_MESSAGE_WITH_SOURCE,
              data: {
                  content: content,
              },
          });
      }

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

  console.error('unknown interaction type', type);
  return res.status(400).json({ error: 'unknown interaction type' });
});

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