// Getting started:
// If you don't have a discord application yet, follow step 1 to get your application created and registered to your server
// https://discord.com/developers/docs/getting-started#step-1-creating-an-app
// Navigate to your application in the Discord developer portal: https://discord.com/developers/applications
// Create a discord_bot_configuration resource. To VERIFY interactions you only
// need the public_key (the Ed25519 "Public Key" from General Information);
// application_id and bot_token (Bot tab) are also on the portal and used for
// outbound REST calls. Populate discord_config below with your resource path.
// Next we deploy this script to Windmill and register it as the "Interactions Endpoint URL"
// Get the endpoint for the sync version: https://docs.windmill.dev/docs/core_concepts/webhooks#synchronous
// Include query parameters for your token as well as capturing the raw body and headers to verify the signature
// {DEPLOYED_SCRIPT_SYNC_WEBHOOK}?include_header=X-Signature-Ed25519,X-Signature-Timestamp&raw=true&token={YOUR_TOKEN}
// Finally we need to create a discord command and register it with our application:
// https://discord.com/developers/docs/interactions/application-commands#making-a-global-command
// Now you should be able to use your registered command in discord and see the bot reply with some of the json payload
import {
InteractionResponseType,
InteractionType,
verifyKey,
} from "[email protected]";
type DiscordBotConfiguration = {
// Ed25519 Public Key — used here to verify the interaction signature.
public_key: string;
application_id: string;
// Bot token (not needed for verification; used for outbound REST calls).
bot_token?: string;
};
export async function main(
x_signature_ed25519: string,
x_signature_timestamp: string,
raw_string: string,
discord_config: DiscordBotConfiguration,
) {
// We'll need the http request body as a string and the two headers to verify the request signature
// https://discord.com/developers/docs/interactions/receiving-and-responding#security-and-authorization
const isVerified = verifyKey(
raw_string,
x_signature_ed25519,
x_signature_timestamp,
discord_config.public_key,
);
// If we can't verify the request, we return 401.
// We will be tested when we submit the interaction webhook to discord
if (!isVerified) {
return { windmill_status_code: 401 };
}
const interaction = JSON.parse(raw_string);
// If we get a PING, we need to respond with a PONG
// https://discord.com/developers/docs/interactions/receiving-and-responding#responding-to-an-interaction
const type = interaction.type as InteractionType;
if (type === InteractionType.PING) {
return { type: InteractionResponseType.PONG };
}
// At this point we can process the interaction and can handle here or delegate to another script/flow
// https://discord.com/developers/docs/interactions/receiving-and-responding#interactions-and-bot-users
if (type === InteractionType.APPLICATION_COMMAND) {
const message = `Received command: \`\`\`json\n${JSON.stringify(
{
id: interaction.id,
sender: interaction.member?.user,
data: interaction.data,
},
undefined,
2,
)}\`\`\``;
return {
type: InteractionResponseType.CHANNEL_MESSAGE_WITH_SOURCE,
data: {
content: message,
},
};
}
}
Submitted by hugo989 10 days ago