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
|
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,
},
});
} else if (name === 'pet') {
return res.send({
type: InteractionResponseType.CHANNEL_MESSAGE_WITH_SOURCE,
data: {
content: '[purring noises]',
},
});
}
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);
});
|