- refactor
- add modal
This commit is contained in:
parent
b7cc57770c
commit
c018d35e2a
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,3 +1,4 @@
|
|||||||
node_modules
|
node_modules
|
||||||
# Keep environment variables out of version control
|
# Keep environment variables out of version control
|
||||||
.env
|
.env
|
||||||
|
prisma/dev.db
|
||||||
|
BIN
prisma/dev.db
BIN
prisma/dev.db
Binary file not shown.
10
src/Components/actions.component.ts
Normal file
10
src/Components/actions.component.ts
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
import { ActionRowBuilder, ButtonBuilder, ButtonStyle } from "discord.js";
|
||||||
|
|
||||||
|
export default function getActionsComponent() {
|
||||||
|
return new ActionRowBuilder().addComponents(
|
||||||
|
new ButtonBuilder()
|
||||||
|
.setCustomId("quoteModal")
|
||||||
|
.setLabel("Quote")
|
||||||
|
.setStyle(ButtonStyle.Primary)
|
||||||
|
);
|
||||||
|
}
|
30
src/Components/commands.component.ts
Normal file
30
src/Components/commands.component.ts
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
import { SlashCommandBuilder } from "discord.js";
|
||||||
|
|
||||||
|
export default function getCommands() {
|
||||||
|
const commands = [
|
||||||
|
new SlashCommandBuilder()
|
||||||
|
.setName("quote")
|
||||||
|
.setDescription("Lets you post a qoute without showing your name")
|
||||||
|
.addStringOption((option) =>
|
||||||
|
option
|
||||||
|
.setName("content")
|
||||||
|
.setDescription("The content of the quote")
|
||||||
|
.setRequired(true)
|
||||||
|
),
|
||||||
|
new SlashCommandBuilder()
|
||||||
|
.setName("quotemodal")
|
||||||
|
.setDescription(
|
||||||
|
"Shows a model which lets you post a quote without showing your name"
|
||||||
|
),
|
||||||
|
new SlashCommandBuilder()
|
||||||
|
.setName("actions")
|
||||||
|
.setDescription("Handle actions on this server")
|
||||||
|
.addSubcommand((subcommand) =>
|
||||||
|
subcommand
|
||||||
|
.setName("send")
|
||||||
|
.setDescription("Sends bot actions in the current channel")
|
||||||
|
),
|
||||||
|
].map((command) => command.toJSON());
|
||||||
|
|
||||||
|
return commands;
|
||||||
|
}
|
23
src/Components/quote-modal.component.ts
Normal file
23
src/Components/quote-modal.component.ts
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
import {
|
||||||
|
ActionRowBuilder,
|
||||||
|
ModalBuilder,
|
||||||
|
TextInputBuilder,
|
||||||
|
TextInputStyle,
|
||||||
|
} from "discord.js";
|
||||||
|
|
||||||
|
export default function getQuoteModal() {
|
||||||
|
const modal = new ModalBuilder()
|
||||||
|
.setCustomId("quoteModal")
|
||||||
|
.setTitle("Submit a quote!");
|
||||||
|
|
||||||
|
const contentInput = new TextInputBuilder()
|
||||||
|
.setCustomId("contentInput")
|
||||||
|
.setLabel("Content")
|
||||||
|
.setStyle(TextInputStyle.Paragraph);
|
||||||
|
|
||||||
|
const firstActionRow = new ActionRowBuilder().addComponents(contentInput);
|
||||||
|
|
||||||
|
modal.addComponents(firstActionRow as any);
|
||||||
|
|
||||||
|
return modal;
|
||||||
|
}
|
@ -1,24 +1,24 @@
|
|||||||
import {
|
import {
|
||||||
|
ButtonInteraction,
|
||||||
CacheType,
|
CacheType,
|
||||||
ChatInputCommandInteraction,
|
ChatInputCommandInteraction,
|
||||||
Interaction,
|
Interaction,
|
||||||
|
ModalSubmitInteraction,
|
||||||
} from "discord.js";
|
} from "discord.js";
|
||||||
import config from "config";
|
|
||||||
import EventEmitter from "events";
|
import EventEmitter from "events";
|
||||||
import DiscordService from "Services/discord.service";
|
import DiscordService from "Services/discord/discord.service";
|
||||||
import PrismaService from "Services/prisma.service";
|
|
||||||
|
|
||||||
export default class DiscordController extends EventEmitter {
|
export default class DiscordController extends EventEmitter {
|
||||||
private discordService!: DiscordService;
|
private discordService!: DiscordService;
|
||||||
private prismaService: PrismaService;
|
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
this.discordService = new DiscordService();
|
this.discordService = new DiscordService();
|
||||||
this.prismaService = new PrismaService();
|
// log when running
|
||||||
this.discordService.client.once("ready", () => {
|
this.discordService.client.once("ready", () => {
|
||||||
console.log("Listening...");
|
console.log("Listening...");
|
||||||
});
|
});
|
||||||
|
// listen for interactions
|
||||||
this.discordService.client.on(
|
this.discordService.client.on(
|
||||||
"interactionCreate",
|
"interactionCreate",
|
||||||
this.handleInteraction.bind(this)
|
this.handleInteraction.bind(this)
|
||||||
@ -30,42 +30,55 @@ export default class DiscordController extends EventEmitter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async handleInteraction(interaction: Interaction<CacheType>) {
|
async handleInteraction(interaction: Interaction<CacheType>) {
|
||||||
if (!interaction.isChatInputCommand()) return;
|
if (interaction.isModalSubmit()) {
|
||||||
|
await this.handleModalSubmit(interaction);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (interaction.isChatInputCommand()) {
|
||||||
|
await this.handleChatInputCommand(interaction);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (interaction.isButton()) {
|
||||||
|
await this.handleButton(interaction);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async handleButton(interaction: ButtonInteraction<CacheType>) {
|
||||||
|
const { customId } = interaction;
|
||||||
|
|
||||||
|
if (customId === "quoteModal") {
|
||||||
|
this.discordService.handleQuoteModal(interaction);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async handleChatInputCommand(
|
||||||
|
interaction: ChatInputCommandInteraction<CacheType>
|
||||||
|
) {
|
||||||
const { commandName } = interaction;
|
const { commandName } = interaction;
|
||||||
|
|
||||||
switch (commandName) {
|
switch (commandName) {
|
||||||
case "quote":
|
case "quote":
|
||||||
await this.quote(interaction);
|
await this.discordService.handleQuote(interaction);
|
||||||
|
case "quotemodal":
|
||||||
|
await this.discordService.handleQuoteModal(interaction);
|
||||||
|
case "actions":
|
||||||
|
await this.discordService.handleActions(interaction);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async quote(interaction: ChatInputCommandInteraction<CacheType>) {
|
async handleModalSubmit(interaction: ModalSubmitInteraction<CacheType>) {
|
||||||
// find the channel with configured id
|
const { customId } = interaction;
|
||||||
const channel = this.discordService.client.channels.cache.find(
|
|
||||||
(ch) => ch.id === config.discord.channelId
|
|
||||||
);
|
|
||||||
|
|
||||||
if (channel?.isTextBased()) {
|
switch (customId) {
|
||||||
const content = interaction.options.getString("content") || "";
|
case "quoteModal":
|
||||||
|
await this.discordService.handleQuote(interaction);
|
||||||
// send quote content as message
|
default:
|
||||||
await this.prismaService.client.message.create({
|
break;
|
||||||
data: {
|
|
||||||
content,
|
|
||||||
userName: interaction.user.username,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
await channel.send(content);
|
|
||||||
|
|
||||||
await interaction.reply({
|
|
||||||
content: "Completed!",
|
|
||||||
ephemeral: true,
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async sendActions(interaction: ChatInputCommandInteraction<CacheType>) {}
|
||||||
}
|
}
|
||||||
|
@ -1,46 +0,0 @@
|
|||||||
import {
|
|
||||||
Client,
|
|
||||||
IntentsBitField,
|
|
||||||
Routes,
|
|
||||||
SlashCommandBuilder,
|
|
||||||
} from "discord.js";
|
|
||||||
import { REST } from "@discordjs/rest";
|
|
||||||
import config from "config";
|
|
||||||
|
|
||||||
const COMMANDS = [
|
|
||||||
new SlashCommandBuilder()
|
|
||||||
.setName("quote")
|
|
||||||
.setDescription("Lets you post a qoute without showing your name")
|
|
||||||
.addStringOption((option) =>
|
|
||||||
option
|
|
||||||
.setName("content")
|
|
||||||
.setDescription("The content of the quote")
|
|
||||||
.setRequired(true)
|
|
||||||
),
|
|
||||||
].map((command) => command.toJSON());
|
|
||||||
|
|
||||||
export default class DiscordService {
|
|
||||||
rest: REST;
|
|
||||||
client: Client<boolean>;
|
|
||||||
constructor() {
|
|
||||||
this.rest = new REST({ version: "10" }).setToken(config.discord.token);
|
|
||||||
|
|
||||||
this.client = new Client({ intents: [IntentsBitField.Flags.Guilds] });
|
|
||||||
}
|
|
||||||
|
|
||||||
async init() {
|
|
||||||
try {
|
|
||||||
await this.rest.put(
|
|
||||||
Routes.applicationCommands(config.discord.applicationId),
|
|
||||||
{
|
|
||||||
body: COMMANDS,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
console.log("Successfully added commands");
|
|
||||||
|
|
||||||
await this.client.login(config.discord.token);
|
|
||||||
} catch (e) {
|
|
||||||
console.error(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
114
src/Services/discord/discord.service.ts
Normal file
114
src/Services/discord/discord.service.ts
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
import {
|
||||||
|
CacheType,
|
||||||
|
ChatInputCommandInteraction,
|
||||||
|
Client,
|
||||||
|
IntentsBitField,
|
||||||
|
Interaction,
|
||||||
|
Routes,
|
||||||
|
SlashCommandBuilder,
|
||||||
|
} from "discord.js";
|
||||||
|
import { REST } from "@discordjs/rest";
|
||||||
|
import config from "config";
|
||||||
|
import PrismaService from "Services/prisma.service";
|
||||||
|
import getCommands from "Components/commands.component";
|
||||||
|
import getQuoteModal from "Components/quote-modal.component";
|
||||||
|
import getActionsComponent from "Components/actions.component";
|
||||||
|
|
||||||
|
export default class DiscordService {
|
||||||
|
rest: REST;
|
||||||
|
client: Client<boolean>;
|
||||||
|
private prismaService: PrismaService;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.rest = new REST({ version: "10" }).setToken(config.discord.token);
|
||||||
|
this.prismaService = new PrismaService();
|
||||||
|
|
||||||
|
this.client = new Client({ intents: [IntentsBitField.Flags.Guilds] });
|
||||||
|
}
|
||||||
|
|
||||||
|
async init() {
|
||||||
|
try {
|
||||||
|
await this.rest.put(
|
||||||
|
Routes.applicationCommands(config.discord.applicationId),
|
||||||
|
{
|
||||||
|
body: getCommands(),
|
||||||
|
}
|
||||||
|
);
|
||||||
|
console.log("Successfully added commands");
|
||||||
|
|
||||||
|
await this.client.login(config.discord.token);
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async handleQuote(interaction: Interaction<CacheType>) {
|
||||||
|
let content: string | undefined = undefined;
|
||||||
|
|
||||||
|
if (interaction.isModalSubmit()) {
|
||||||
|
content = interaction.fields.getTextInputValue("contentInput");
|
||||||
|
} else if (interaction.isChatInputCommand()) {
|
||||||
|
content = interaction.options.getString("content") || "";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (content) {
|
||||||
|
await this.createQuote({ content }, interaction);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async handleQuoteModal(interaction: Interaction<CacheType>) {
|
||||||
|
const modal = getQuoteModal();
|
||||||
|
|
||||||
|
if (interaction.isButton() || interaction.isChatInputCommand()) {
|
||||||
|
await interaction.showModal(modal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async handleActions(interaction: Interaction<CacheType>) {
|
||||||
|
if (interaction.isChatInputCommand()) {
|
||||||
|
if (interaction.options.getSubcommand() === "send") {
|
||||||
|
const channel = interaction.channel;
|
||||||
|
|
||||||
|
if (channel?.isTextBased()) {
|
||||||
|
const actions = getActionsComponent();
|
||||||
|
|
||||||
|
await interaction.reply({
|
||||||
|
content: "Choose an action!",
|
||||||
|
components: [actions as any],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async createQuote(
|
||||||
|
{ content }: { content: string },
|
||||||
|
interaction: Interaction
|
||||||
|
) {
|
||||||
|
// find the channel with configured id
|
||||||
|
const channel = this.client.channels.cache.find(
|
||||||
|
(ch) => ch.id === config.discord.channelId
|
||||||
|
);
|
||||||
|
|
||||||
|
if (channel?.isTextBased()) {
|
||||||
|
// send quote content as message
|
||||||
|
await this.prismaService.client.message.create({
|
||||||
|
data: {
|
||||||
|
content,
|
||||||
|
userName: interaction.user.username,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
await channel.send(content);
|
||||||
|
|
||||||
|
if (interaction.isChatInputCommand() || interaction.isModalSubmit()) {
|
||||||
|
await interaction.reply({
|
||||||
|
content: "Completed!",
|
||||||
|
ephemeral: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user