|
const { Client } = require("discord.js"); |
|
|
|
const { GatewayServer, SlashCreator, Command, CommandOptionType, InteractionResponseFlags } = require("slash-create"); |
|
const { Endpoints } = require("slash-create/lib/constants"); |
|
|
|
const client = new Client(); |
|
|
|
const creator = new SlashCreator({ |
|
applicationID: "APP_ID", |
|
publicKey: "PUBLIC_KEY", |
|
token: "BOT_TOKEN" |
|
}); |
|
|
|
creator.withServer(new GatewayServer( |
|
(handler) => client.ws.on('INTERACTION_CREATE', handler) |
|
)); |
|
|
|
creator.on('commandRun', async (command, promise, context) => { |
|
await promise; |
|
whispers.set(context.user.id, { |
|
...(whispers.get(context.user.id) || {}), |
|
context |
|
}); |
|
}); |
|
|
|
|
|
client.on("debug", (msg) => console.log("[CLIENT]", msg)); |
|
|
|
/** |
|
* @typedef {Object} WhisperContext |
|
* @property {import("slash-create").CommandContext} context |
|
* @property {string} lastWhisperFrom |
|
*/ |
|
|
|
/** |
|
* @type {Map<string, WhisperContext>} |
|
*/ |
|
const whispers = new Map(); |
|
|
|
class UnknownCommand extends Command { |
|
constructor(creator) { |
|
super(creator, { |
|
unknown: true, |
|
}); |
|
} |
|
|
|
/** |
|
* @param {import("slash-create").CommandContext} ctx |
|
* @return {Promise<void>} |
|
*/ |
|
async run(ctx) { |
|
ctx.send(`I was not able to find '${ctx.commandName}'`); |
|
} |
|
} |
|
|
|
class GreetingCommand extends Command { |
|
constructor(creator) { |
|
super(creator, { |
|
name: "hello", |
|
description: "Salutations!", |
|
options: [{ |
|
type: CommandOptionType.STRING, |
|
name: "food", |
|
description: "What's your favorite food?" |
|
}] |
|
}); |
|
} |
|
|
|
/** |
|
* @param {import("slash-create").CommandContext} ctx |
|
*/ |
|
async run(ctx) { |
|
const { food } = ctx.options; |
|
|
|
const message = `Hello, ${ctx.user.username}! ${food ? `I too like ${food}!` : ''}`; |
|
await ctx.send(message, {ephemeral:true}); |
|
} |
|
} |
|
|
|
class WhisperCommand extends Command { |
|
constructor(creator) { |
|
super(creator, { |
|
name: "whisper", |
|
description: "Whisper to someone", |
|
options: [{ |
|
type: CommandOptionType.USER, |
|
name: "to", |
|
description: "Who should I whisper to?", |
|
required: true |
|
}, { |
|
type: CommandOptionType.STRING, |
|
name: "message", |
|
description: "What should I whisper?", |
|
required: true |
|
}], |
|
|
|
deferEphemeral: true, |
|
}); |
|
} |
|
|
|
/** |
|
* @param {import("slash-create").CommandContext} ctx |
|
* @return {Promise<void>} |
|
*/ |
|
async run(ctx) { |
|
const { to, message } = ctx.options; |
|
const whisper = whispers.get(to); |
|
|
|
if(to === ctx.user.id) { |
|
await ctx.send(`You can't whisper to yourself, ${ctx.user.username}!`, {ephemeral:true}); |
|
return; |
|
} |
|
|
|
if (whisper === undefined) { |
|
const message = `I was not able to find '${to}'.`; |
|
await ctx.send(message, {ephemeral:true}); |
|
return; |
|
} |
|
|
|
const { context } = whisper; |
|
|
|
try { |
|
const msg = `**${ctx.user.username}:** ${message}`; |
|
await creator.requestHandler.request( |
|
"POST", Endpoints.FOLLOWUP_MESSAGE(creator.options.applicationID, context.interactionToken), true, |
|
{ |
|
content: msg, |
|
flags: InteractionResponseFlags.EPHEMERAL |
|
}); |
|
await ctx.send(`Whisper sent to **${context.user.username}**!`, {ephemeral:true}); |
|
whisper.lastWhisperFrom = ctx.user.id; |
|
whispers.set(context.user.id, whisper); |
|
} catch (err) { |
|
await ctx.send(`Something went wrong: ${err.message}`); |
|
} |
|
} |
|
} |
|
|
|
class ReplyCommand extends Command { |
|
constructor(creator) { |
|
super(creator, { |
|
name: "reply", |
|
description: "Reply to a message", |
|
options: [{ |
|
type: CommandOptionType.STRING, |
|
name: "message", |
|
description: "What should I reply with?", |
|
required: true |
|
}], |
|
|
|
deferEphemeral: true, |
|
}); |
|
} |
|
|
|
/** |
|
* @param {import("slash-create").CommandContext} ctx |
|
* @return {Promise<void>} |
|
*/ |
|
async run(ctx) { |
|
const currentUserWhisper = whispers.get(ctx.user.id); |
|
|
|
if (currentUserWhisper === undefined) { |
|
const message = `I was not able to find your last whisper.`; |
|
await ctx.send(message); |
|
return; |
|
} |
|
|
|
const { lastWhisperFrom } = currentUserWhisper; |
|
const whisper = whispers.get(lastWhisperFrom); |
|
|
|
if (whisper === undefined) { |
|
const message = `I was not able to find '${lastWhisperFrom}'.`; |
|
await ctx.send(message, {ephemeral:true}); |
|
return; |
|
} |
|
|
|
if(whisper.context.expired) { |
|
const message = `I was not able to find '${lastWhisperFrom}'.`; |
|
await ctx.send(message, {ephemeral:true}); |
|
return; |
|
} |
|
|
|
try { |
|
const { context } = whisper; |
|
const message = `**${ctx.user.username}:** ${ctx.options.message}`; |
|
await creator.requestHandler.request( |
|
"POST", Endpoints.FOLLOWUP_MESSAGE(creator.options.applicationID, context.interactionToken), true, |
|
{ |
|
content: message, |
|
flags: InteractionResponseFlags.EPHEMERAL |
|
}); |
|
await ctx.send(`Reply sent to ${lastWhisperFrom}`, {ephemeral:true}); |
|
whisper.lastWhisperFrom = ctx.user.id; |
|
whispers.set(context.user.id, whisper); |
|
} catch (e) { |
|
await ctx.send(`Something went wrong: ${e.message}`); |
|
} |
|
} |
|
} |
|
|
|
creator |
|
.on("debug", console.log.bind(console, "[SLASH]")) |
|
.registerCommands([ |
|
UnknownCommand, |
|
GreetingCommand, |
|
WhisperCommand, |
|
ReplyCommand |
|
]) |
|
.syncCommands(); |
|
|
|
client.login(creator.options.token); |
ctx.sendFollowUp(msg, opts)
now supports the ephemeral parameter which was added in 10ba62d from Snazzah/slash-create#83 and since added in v3.4.0.