-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
113 lines (75 loc) · 3.45 KB
/
index.js
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
import { InteractionResponseType, InteractionType } from 'discord-api-types/v10';
import { isChatInputApplicationCommandInteraction, isContextMenuApplicationCommandInteraction, isMessageComponentButtonInteraction, isMessageComponentSelectMenuInteraction } from 'discord-api-types/utils';
import { AutoRouter } from 'itty-router';
import { verifyKey } from 'discord-interactions';
import { handleSlashCommand } from './Handlers/Commands/slashCommandHandler.js';
import { handleContextCommand } from './Handlers/Commands/contextCommandHandler.js';
import { handleButton } from './Handlers/Interactions/buttonHandler.js';
import { handleSelect } from './Handlers/Interactions/selectHandler.js';
import { handleAutocomplete } from './Handlers/Interactions/autocompleteHandler.js';
import { handleModal } from './Handlers/Interactions/modalHandler.js';
import { DISCORD_APP_PUBLIC_KEY, DISCORD_APP_USER_ID } from './config.js';
import { JsonResponse } from './Utility/utilityMethods.js';
// *******************************
// Create Router
const router = AutoRouter();
/** Wave to verify CF worker is working */
router.get('/', (request, env) => {
return new Response(`👏 ${DISCORD_APP_USER_ID}`);
});
// *******************************
/** Main route for all requests sent from Discord. They will include a JSON payload */
router.post('/', async (request, env) => {
// Verify request
const { isValid, interaction } = await server.verifyDiscordRequest(request, env);
if ( !isValid || !interaction ) {
return new Response('Bad request signature.', { status: 401 });
}
// Handle PING Interaction
if ( interaction.type === InteractionType.Ping ) {
return new JsonResponse({ type: InteractionResponseType.Pong });
}
// Now split off & handle each Interaction type
if ( isChatInputApplicationCommandInteraction(interaction) ) {
return await handleSlashCommand(interaction);
}
else if ( isContextMenuApplicationCommandInteraction(interaction) ) {
return await handleContextCommand(interaction);
}
else if ( isMessageComponentButtonInteraction(interaction) ) {
return await handleButton(interaction);
}
else if ( isMessageComponentSelectMenuInteraction(interaction) ) {
return await handleSelect(interaction);
}
else if ( interaction.type === InteractionType.ApplicationCommandAutocomplete ) {
return await handleAutocomplete(interaction);
}
else if ( interaction.type === InteractionType.ModalSubmit ) {
return await handleModal(interaction);
}
else {
console.info(`****Unrecognised or new unhandled Interaction Type triggered: ${interaction.type}`);
return new JsonResponse({ error: 'Unknown Type' }, { status: 400 });
}
});
router.all('*', () => new Response('Not Found.', { status: 400 }));
// *******************************
async function verifyDiscordRequest(request, env) {
const signature = request.headers.get('x-signature-ed25519');
const timestamp = request.headers.get('x-signature-timestamp');
const body = await request.text();
const isValidRequest =
signature &&
timestamp &&
(await verifyKey(body, signature, timestamp, DISCORD_APP_PUBLIC_KEY));
if (!isValidRequest) {
return { isValid: false };
}
return { interaction: JSON.parse(body), isValid: true };
}
const server = {
verifyDiscordRequest,
fetch: router.fetch,
};
export default server;