0
Receive Application Command Sample
One script reply has been approved by the moderators Verified

Basic discord command handler. This script shows how to handle the signature, replying to ping and then replies to the command with some of the received interaction json as a sample.

Created by jonathan ohlrich398 575 days ago Viewed 9340 times
0
Submitted by jonathan ohlrich398 Deno
Verified 575 days ago
1
// Getting started:
2
// If you don't have a discord application yet, follow step 1 to get your application created and registered to your server
3
//   https://discord.com/developers/docs/getting-started#step-1-creating-an-app
4

5
// Navigate to your application in the Discord developer portal: https://discord.com/developers/applications
6

7
// Create a new discord_bot_configuration resource with the public_key and application_id fields from the discord portal
8
// Populate the DEFUALT_DISCORD_CONFIG variable below with the path to your new resource
9

10
// Next we deploy this script to Windmill and register it as the "Interactions Endpoint URL"
11
//   Get the endpoint for the sync version: https://docs.windmill.dev/docs/core_concepts/webhooks#synchronous
12
//   Include query parameters for your token as well as capturing the raw body and headers to verify the signature
13
//   {DEPLOYED_SCRIPT_SYNC_WEBHOOK}?include_header=X-Signature-Ed25519,X-Signature-Timestamp&raw=true&token={YOUR_TOKEN}
14

15
// Finally we need to create a discord command and register it with our application:
16
//   https://discord.com/developers/docs/interactions/application-commands#making-a-global-command
17

18
// Now you should be able to use your registered command in discord and see the bot reply with some of the json payload
19

20
import {
21
  InteractionResponseType,
22
  InteractionType,
23
  verifyKey,
24
} from "npm:discord-interactions@3.4.0";
25

26
type DiscordBotConfiguration = {
27
  public_key: string;
28
  application_id: string;
29
};
30
export async function main(
31
  x_signature_ed25519: string,
32
  x_signature_timestamp: string,
33
  raw_string: string,
34
  discord_config: DiscordBotConfiguration,
35
) {
36
  // We'll need the http request body as a string and the two headers to verify the request signature
37
  // https://discord.com/developers/docs/interactions/receiving-and-responding#security-and-authorization
38
  const isVerified = verifyKey(
39
    raw_string,
40
    x_signature_ed25519,
41
    x_signature_timestamp,
42
    discord_config.public_key,
43
  );
44

45
  // If we can't verify the request, we return 401.
46
  // We will be tested when we submit the interaction webhook to discord
47
  if (!isVerified) {
48
    return { windmill_status_code: 401 };
49
  }
50

51
  const interaction = JSON.parse(raw_string);
52

53
  // If we get a PING, we need to respond with a PONG
54
  // https://discord.com/developers/docs/interactions/receiving-and-responding#responding-to-an-interaction
55
  const type = interaction.type as InteractionType;
56
  if (type === InteractionType.PING) {
57
    return { type: InteractionResponseType.PONG };
58
  }
59

60
  // At this point we can process the interaction and can handle here or delegate to another script/flow
61
  // https://discord.com/developers/docs/interactions/receiving-and-responding#interactions-and-bot-users
62
  if (type === InteractionType.APPLICATION_COMMAND) {
63
    const message = `Received command: \`\`\`json\n${JSON.stringify(
64
      {
65
        id: interaction.id,
66
        sender: interaction.member?.user,
67
        data: interaction.data,
68
      },
69
      undefined,
70
      2,
71
    )}\`\`\``;
72

73
    return {
74
      type: InteractionResponseType.CHANNEL_MESSAGE_WITH_SOURCE,
75
      data: {
76
        content: message,
77
      },
78
    };
79
  }
80
}
81