0

Receive Application Command Sample

by
Published May 27, 2023

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.

Script discord Verified

The script

Submitted by hugo989 Bun
Verified 10 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 discord_bot_configuration resource. To VERIFY interactions you only
8
// need the public_key (the Ed25519 "Public Key" from General Information);
9
// application_id and bot_token (Bot tab) are also on the portal and used for
10
// outbound REST calls. Populate discord_config below with your resource path.
11

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

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

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

22
import {
23
  InteractionResponseType,
24
  InteractionType,
25
  verifyKey,
26
} from "[email protected]";
27

28
type DiscordBotConfiguration = {
29
  // Ed25519 Public Key — used here to verify the interaction signature.
30
  public_key: string;
31
  application_id: string;
32
  // Bot token (not needed for verification; used for outbound REST calls).
33
  bot_token?: string;
34
};
35
export async function main(
36
  x_signature_ed25519: string,
37
  x_signature_timestamp: string,
38
  raw_string: string,
39
  discord_config: DiscordBotConfiguration,
40
) {
41
  // We'll need the http request body as a string and the two headers to verify the request signature
42
  // https://discord.com/developers/docs/interactions/receiving-and-responding#security-and-authorization
43
  const isVerified = verifyKey(
44
    raw_string,
45
    x_signature_ed25519,
46
    x_signature_timestamp,
47
    discord_config.public_key,
48
  );
49

50
  // If we can't verify the request, we return 401.
51
  // We will be tested when we submit the interaction webhook to discord
52
  if (!isVerified) {
53
    return { windmill_status_code: 401 };
54
  }
55

56
  const interaction = JSON.parse(raw_string);
57

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

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

78
    return {
79
      type: InteractionResponseType.CHANNEL_MESSAGE_WITH_SOURCE,
80
      data: {
81
        content: message,
82
      },
83
    };
84
  }
85
}
86

Other submissions
  • Submitted by jonathan ohlrich398 Deno
    Created 11 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 discord_bot_configuration resource. To VERIFY interactions you only
    8
    // need the public_key (the Ed25519 "Public Key" from General Information);
    9
    // application_id and bot_token (Bot tab) are also on the portal and used for
    10
    // outbound REST calls. Populate discord_config below with your resource path.
    11
    
    
    12
    // Next we deploy this script to Windmill and register it as the "Interactions Endpoint URL"
    13
    //   Get the endpoint for the sync version: https://docs.windmill.dev/docs/core_concepts/webhooks#synchronous
    14
    //   Include query parameters for your token as well as capturing the raw body and headers to verify the signature
    15
    //   {DEPLOYED_SCRIPT_SYNC_WEBHOOK}?include_header=X-Signature-Ed25519,X-Signature-Timestamp&raw=true&token={YOUR_TOKEN}
    16
    
    
    17
    // Finally we need to create a discord command and register it with our application:
    18
    //   https://discord.com/developers/docs/interactions/application-commands#making-a-global-command
    19
    
    
    20
    // Now you should be able to use your registered command in discord and see the bot reply with some of the json payload
    21
    
    
    22
    import {
    23
      InteractionResponseType,
    24
      InteractionType,
    25
      verifyKey,
    26
    } from "npm:[email protected]";
    27
    
    
    28
    type DiscordBotConfiguration = {
    29
      // Ed25519 Public Key — used here to verify the interaction signature.
    30
      public_key: string;
    31
      application_id: string;
    32
      // Bot token (not needed for verification; used for outbound REST calls).
    33
      bot_token?: string;
    34
    };
    35
    export async function main(
    36
      x_signature_ed25519: string,
    37
      x_signature_timestamp: string,
    38
      raw_string: string,
    39
      discord_config: DiscordBotConfiguration,
    40
    ) {
    41
      // We'll need the http request body as a string and the two headers to verify the request signature
    42
      // https://discord.com/developers/docs/interactions/receiving-and-responding#security-and-authorization
    43
      const isVerified = verifyKey(
    44
        raw_string,
    45
        x_signature_ed25519,
    46
        x_signature_timestamp,
    47
        discord_config.public_key,
    48
      );
    49
    
    
    50
      // If we can't verify the request, we return 401.
    51
      // We will be tested when we submit the interaction webhook to discord
    52
      if (!isVerified) {
    53
        return { windmill_status_code: 401 };
    54
      }
    55
    
    
    56
      const interaction = JSON.parse(raw_string);
    57
    
    
    58
      // If we get a PING, we need to respond with a PONG
    59
      // https://discord.com/developers/docs/interactions/receiving-and-responding#responding-to-an-interaction
    60
      const type = interaction.type as InteractionType;
    61
      if (type === InteractionType.PING) {
    62
        return { type: InteractionResponseType.PONG };
    63
      }
    64
    
    
    65
      // At this point we can process the interaction and can handle here or delegate to another script/flow
    66
      // https://discord.com/developers/docs/interactions/receiving-and-responding#interactions-and-bot-users
    67
      if (type === InteractionType.APPLICATION_COMMAND) {
    68
        const message = `Received command: \`\`\`json\n${JSON.stringify(
    69
          {
    70
            id: interaction.id,
    71
            sender: interaction.member?.user,
    72
            data: interaction.data,
    73
          },
    74
          undefined,
    75
          2,
    76
        )}\`\`\``;
    77
    
    
    78
        return {
    79
          type: InteractionResponseType.CHANNEL_MESSAGE_WITH_SOURCE,
    80
          data: {
    81
            content: message,
    82
          },
    83
        };
    84
      }
    85
    }
    86