mirror of
https://github.com/roleypoly/roleypoly.git
synced 2025-04-24 19:39:11 +00:00
fix interactions, apparently cfw doesn't speak Buffer
This commit is contained in:
parent
7007cfea9d
commit
544ef1b2f0
5 changed files with 56 additions and 20 deletions
|
@ -10,10 +10,15 @@ export const helloWorld: InteractionHandler = (
|
|||
interaction: InteractionRequest,
|
||||
context: Context
|
||||
): InteractionResponse => {
|
||||
console.log({ interaction });
|
||||
return {
|
||||
type: InteractionCallbackType.CHANNEL_MESSAGE_WITH_SOURCE,
|
||||
data: {
|
||||
content: `Hey there, ${interaction.member?.nick || interaction.user?.username}`,
|
||||
content: `Hey there, ${
|
||||
interaction.member?.nick ||
|
||||
interaction.member?.user?.username ||
|
||||
interaction.user?.username
|
||||
}`,
|
||||
},
|
||||
};
|
||||
};
|
||||
|
|
|
@ -13,6 +13,7 @@ export const verifyRequest = async (
|
|||
request: Request,
|
||||
interaction: InteractionRequest
|
||||
): Promise<boolean> => {
|
||||
try {
|
||||
const timestamp = request.headers.get('x-signature-timestamp');
|
||||
const signature = request.headers.get('x-signature-ed25519');
|
||||
|
||||
|
@ -22,18 +23,40 @@ export const verifyRequest = async (
|
|||
|
||||
const key = await crypto.subtle.importKey(
|
||||
'raw',
|
||||
Buffer.from(config.publicKey, 'hex'),
|
||||
bufferizeHex(config.publicKey),
|
||||
{ name: 'NODE-ED25519', namedCurve: 'NODE-ED25519', public: true } as any,
|
||||
false,
|
||||
['verify']
|
||||
);
|
||||
|
||||
return crypto.subtle.verify(
|
||||
const verified = await crypto.subtle.verify(
|
||||
'NODE-ED25519',
|
||||
key,
|
||||
Buffer.from(signature, 'hex'),
|
||||
Buffer.from(timestamp + JSON.stringify(interaction))
|
||||
bufferizeHex(signature),
|
||||
bufferizeString(timestamp + JSON.stringify(interaction))
|
||||
);
|
||||
|
||||
return verified;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
// Cloudflare Workers + SubtleCrypto has no idea what a Buffer.from() is.
|
||||
// What the fuck?
|
||||
const bufferizeHex = (input: string) => {
|
||||
const buffer = new Uint8Array(input.length / 2);
|
||||
|
||||
for (let i = 0; i < input.length; i += 2) {
|
||||
buffer[i / 2] = parseInt(input.substring(i, i + 2), 16);
|
||||
}
|
||||
|
||||
return buffer;
|
||||
};
|
||||
|
||||
const bufferizeString = (input: string) => {
|
||||
const encoder = new TextEncoder();
|
||||
return encoder.encode(input);
|
||||
};
|
||||
|
||||
export type InteractionHandler = ((
|
||||
|
@ -59,7 +82,7 @@ export const runAsync = async (
|
|||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
type: InteractionCallbackType.DEFERRED_UPDATE_MESSAGE,
|
||||
type: InteractionCallbackType.DEFERRED_CHANNEL_MESSAGE_WITH_SOURCE,
|
||||
data: {
|
||||
flags: handler.ephemeral ? InteractionFlags.EPHEMERAL : 0,
|
||||
...response.data,
|
||||
|
@ -82,7 +105,7 @@ export const runAsync = async (
|
|||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
type: InteractionCallbackType.DEFERRED_UPDATE_MESSAGE,
|
||||
type: InteractionCallbackType.DEFERRED_CHANNEL_MESSAGE_WITH_SOURCE,
|
||||
data: {
|
||||
content: "I'm sorry, I'm having trouble processing this request.",
|
||||
flags: InteractionFlags.EPHEMERAL,
|
||||
|
|
|
@ -30,14 +30,17 @@ export const handleInteraction: RoleypolyHandler = async (
|
|||
}
|
||||
|
||||
if (!(await verifyRequest(context.config, request, interaction))) {
|
||||
console.warn('interactions: invalid signature');
|
||||
return new Response('invalid request signature', { status: 401 });
|
||||
}
|
||||
|
||||
if (interaction.type !== InteractionType.APPLICATION_COMMAND) {
|
||||
if (interaction.type === InteractionType.PING) {
|
||||
console.info('interactions: ping');
|
||||
return json({ type: InteractionCallbackType.PONG });
|
||||
}
|
||||
|
||||
console.warn('interactions: not application command');
|
||||
return json({ err: 'not implemented' }, { status: 400 });
|
||||
}
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ export const corsHeaders = {
|
|||
'Access-Control-Max-Age': '86400',
|
||||
};
|
||||
|
||||
export const noContent = () => new Response(null, { status: 204 });
|
||||
export const noContent = () => new Response(null, { status: 204, headers: corsHeaders });
|
||||
export const seeOther = (url: string) =>
|
||||
new Response(
|
||||
`<!doctype html>If you are not redirected soon, <a href="${url}">click here.</a>`,
|
||||
|
|
5
terraform/interactions.tf
Normal file
5
terraform/interactions.tf
Normal file
|
@ -0,0 +1,5 @@
|
|||
resource "discord-interactions_guild_command" "hello-world" {
|
||||
name = "hello-world"
|
||||
description = "Says hello!"
|
||||
guild_id = "386659935687147521"
|
||||
}
|
Loading…
Add table
Reference in a new issue