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
import { verify_discord_signature } from "https://esm.town/v/mattx/verify_discord_signature";
import { formatInput } from "https://esm.town/v/rayman/formatInput";
import { fetch } from "https://esm.town/v/std/fetch";
import { example1 } from "https://esm.town/v/stevekrouse/example1?v=3";
import process from "node:process";
export async function mgsrBotEndpoint(request) {
const signatureTimestamp = request.headers.get("X-Signature-Timestamp");
const signatureEd25519 = request.headers.get("X-Signature-Ed25519");
console.log(signatureTimestamp);
console.log(signatureEd25519);
if (!signatureTimestamp || !signatureEd25519) {
return new Response("Signature headers missing!", { status: 400 });
}
const body = await request.json();
const verified = await verify_discord_signature(
process.env.discord_pubkey,
JSON.stringify(body),
signatureEd25519,
signatureTimestamp,
);
if (!verified) {
return new Response("Signature invalid", { status: 401 });
}
let responseBody;
let status = 200;
switch (body.type) {
case 1: // PING interaction
responseBody = JSON.stringify({ type: 1 }); // PONG
break;
case 2: // APPLICATION_COMMAND interactions
// Handling of different application commands
responseBody = await handleApplicationCommands(body);
if (!responseBody) {
status = 400;
responseBody = "bad request";
}
break;
default:
status = 400;
responseBody = "bad request";
break;
}
return new Response(responseBody, {
status: status,
headers: { "Content-Type": "application/json" },
});
}
async function handleApplicationCommands(body) {
let response;
switch (body.data.name) {
case "ping":
response = {
type: 4,
data: {
content: `Hello World! example1 is: ${example1}`,
},
};
break;
case "eval":
const evalResponse = await fetch(
`https://api.val.town/v1/eval/${encodeURIComponent(body.data.options[0].value)}`,
{ headers: { "Content-Type": "application/json" } },
);
const evalText = await evalResponse.text();
response = {
type: 4,
data: {
content: `${JSON.stringify(evalText)}`,
},
};
break;
case "Undo Help":
response = {
type: 4,
data: {
content: "`/undo-record leaderboard:mgsr2 versus:1`",
flags: 64, // EPHEMERAL
},
};
break;
case "Result Formatter":
const messageKey = body.data.target_id;
const content = body.data.resolved.messages[messageKey].content;
const resultString = formatInput(content);
response = {
type: 4,
data: {
content: `/game record leaderboard: mgsr2 result: ${resultString}`,
flags: 64, // EPHEMERAL
},
};
break;