This commit is contained in:
moriese 2025-01-12 19:55:19 +01:00
parent 6707a95648
commit d902cd1042
10 changed files with 247 additions and 97 deletions

View File

@ -0,0 +1,2 @@
ALTER TABLE `users_table` ADD `join_streak` integer;--> statement-breakpoint
ALTER TABLE `users_table` ADD `last_joined_at` integer;

View File

@ -0,0 +1,79 @@
{
"version": "6",
"dialect": "sqlite",
"id": "e9592066-1da0-41af-9e25-e2672ebe256f",
"prevId": "ddb7170b-7f66-4e3c-ab64-9069e760e09a",
"tables": {
"users_table": {
"name": "users_table",
"columns": {
"id": {
"name": "id",
"type": "integer",
"primaryKey": true,
"notNull": true,
"autoincrement": true
},
"name": {
"name": "name",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"discord_id": {
"name": "discord_id",
"type": "integer",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"join_streak": {
"name": "join_streak",
"type": "integer",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"last_joined_at": {
"name": "last_joined_at",
"type": "integer",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"took_medication_today": {
"name": "took_medication_today",
"type": "integer",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": 0
}
},
"indexes": {
"users_table_discord_id_unique": {
"name": "users_table_discord_id_unique",
"columns": [
"discord_id"
],
"isUnique": true
}
},
"foreignKeys": {},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"checkConstraints": {}
}
},
"views": {},
"enums": {},
"_meta": {
"schemas": {},
"tables": {},
"columns": {}
},
"internal": {
"indexes": {}
}
}

View File

@ -8,6 +8,13 @@
"when": 1735431085265, "when": 1735431085265,
"tag": "0000_needy_nightshade", "tag": "0000_needy_nightshade",
"breakpoints": true "breakpoints": true
},
{
"idx": 1,
"version": "6",
"when": 1736688734822,
"tag": "0001_dusty_wolverine",
"breakpoints": true
} }
] ]
} }

Binary file not shown.

View File

@ -0,0 +1,133 @@
import config from "config";
import client from "lib/client";
import { getRandomInt } from "lib/utils";
import { customContent, createEmbed } from "./customMessage.components.ts";
import {
Client,
EmbedBuilder,
type Message,
type CacheType,
type GuildMember,
type Interaction,
type OmitPartialGroupDMChannel,
type ChatInputCommandInteraction,
ChannelType,
} from "discord.js";
import { type CommandsType, Commands } from "commands/index.ts";
import { time } from "drizzle-orm/mysql-core";
export class CustomMessageService {
async handleInteraction(interaction: Interaction<CacheType>) {
if (interaction.isChatInputCommand()) {
await this.handleChatInputCommand(interaction);
return;
}
}
async handleChatInputCommand(
interaction: ChatInputCommandInteraction<CacheType>,
) {
console.log("accept");
const commandName = interaction.commandName as CommandsType;
switch (commandName) {
case Commands.Enum.embed:
await this.customEmbed(interaction);
return;
case Commands.Enum.message:
await this.customMessage(interaction);
return;
default:
break;
}
}
async checkPermission(interaction: ChatInputCommandInteraction<CacheType>) {
const userIdCommand = interaction.user.id;
if (userIdCommand !== config.discord.myId) {
await interaction.reply({
content: "you have no permission for that command",
ephemeral: true,
});
return false;
}
return true;
}
// check if command done in server
async checkIfServer(interaction: ChatInputCommandInteraction<CacheType>) {
const guild = interaction.guild;
if (!guild) {
await interaction.reply({
content: "command can only be used on a server",
ephemeral: true,
});
return false;
}
return true;
}
async customEmbed(interaction: ChatInputCommandInteraction<CacheType>) {
const title = interaction.options.getString("title") || " ";
const description = interaction.options.getString("description") || " ";
const timestamp = interaction.options.getBoolean("timestamp") || false;
// return the value
console.log(title, description, timestamp);
// permission check
// permission check
if (await this.checkPermission(interaction) && await this.checkIfServer(interaction))
try {
const channels = client.channels;
const channel = channels.cache.get(interaction.channelId);
if (channel?.isTextBased() && channel?.isSendable()) {
await channel.send({
embeds: [createEmbed(title, description, timestamp)],
});
}
await interaction.reply({
content: "successfully created embed",
ephemeral: true,
});
} catch (error) {
console.error("error while creating embed:", error);
await interaction.reply({
content:
"error while creating embed",
ephemeral: true,
});
}
}
async customMessage(interaction: ChatInputCommandInteraction<CacheType>) {
const input: string = interaction.options.getString("input") || "";
const result = input.replaceAll(";", "\n");
// return the value
console.log(input);
// permission check && server check
if (await this.checkPermission(interaction) && await this.checkIfServer(interaction))
try {
const channels = client.channels;
const channel = channels.cache.get(interaction.channelId);
if (channel?.isTextBased() && channel?.isSendable()) {
await channel.send({
content: result,
});
}
await interaction.reply({
content: "successfully created message",
ephemeral: true,
});
} catch (error) {
console.error("error while creating message:", error);
await interaction.reply({
content:
"error while creating message",
ephemeral: true,
});
}
}
}

View File

@ -1,88 +0,0 @@
import config from "config";
import client from "lib/client";
import { getRandomInt } from "lib/utils";
import { customContent, createEmbed } from "./embed.components.ts";
import {
Client,
EmbedBuilder,
type Message,
type CacheType,
type GuildMember,
type Interaction,
type OmitPartialGroupDMChannel,
type ChatInputCommandInteraction,
} from "discord.js";
import { type CommandsType, Commands } from "commands/index.ts";
import { time } from "drizzle-orm/mysql-core";
export class EmbedService {
async handleInteraction(interaction: Interaction<CacheType>) {
if (interaction.isChatInputCommand()) {
await this.handleChatInputCommand(interaction);
return;
}
}
async handleChatInputCommand(
interaction: ChatInputCommandInteraction<CacheType>,
) {
console.log("accept");
const commandName = interaction.commandName as CommandsType;
switch (commandName) {
case Commands.Enum.embed:
await this.customEmbed(interaction);
return;
default:
break;
}
}
async customEmbed(interaction: ChatInputCommandInteraction<CacheType>) {
const title = interaction.options.getString("title") || " ";
const description = interaction.options.getString("description") || " ";
const timestamp = interaction.options.getBoolean("timestamp") || false;
// return the value
console.log(title, description, timestamp);
// permission check
const userIdCommand = interaction.user.id;
if (userIdCommand !== config.discord.myId) {
await interaction.reply({
content: "you have no permission for that command",
ephemeral: true,
});
return;
}
try {
// get user id from mentioning
const guild = interaction.guild;
if (!guild) {
await interaction.reply({
content: "command can only be used on a server",
ephemeral: true,
});
return;
}
const channels = client.channels;
const channel = channels.cache.get(interaction.channelId);
if (channel?.isTextBased() && channel?.isSendable()) {
await channel.send({
embeds: [createEmbed(title, description, timestamp)],
});
}
await interaction.reply({
content: "done",
ephemeral: true,
});
} catch (error) {
console.error("Fehler beim Hinzufügen der Rolle:", error);
await interaction.reply({
content:
"Es gab einen Fehler beim Hinzufügen der Rolle. Stelle sicher, dass du einen gültigen User erwähnt hast.",
ephemeral: true,
});
}
}
}

View File

@ -1,7 +1,7 @@
import { SlashCommandBuilder, userMention } from "discord.js"; import { SlashCommandBuilder, userMention } from "discord.js";
import { z } from "zod"; import { z } from "zod";
export const Commands = z.enum(["giessen", "medikamente", "hilfe", "accept", "welcome", "embed"]); export const Commands = z.enum(["giessen", "medikamente", "hilfe", "accept", "welcome", "embed", "message"]);
export const CommandsMeta: Record<z.output<typeof Commands>, { description: string }> = { export const CommandsMeta: Record<z.output<typeof Commands>, { description: string }> = {
giessen: { giessen: {
@ -21,6 +21,9 @@ export const CommandsMeta: Record<z.output<typeof Commands>, { description: stri
}, },
embed: { embed: {
description: "admin use only" description: "admin use only"
},
message: {
description: "admin use only"
} }
} }
@ -66,6 +69,13 @@ export default function getCommands() {
option.setName('timestamp') option.setName('timestamp')
.setDescription('timestamp bool') .setDescription('timestamp bool')
.setRequired(false)), .setRequired(false)),
new SlashCommandBuilder()
.setName(Commands.Enum.message)
.setDescription(CommandsMeta.message.description)
.addStringOption(option =>
option.setName('input')
.setDescription('input for bot')
.setRequired(true)),
].map((command) => command.toJSON()); ].map((command) => command.toJSON());

View File

@ -20,7 +20,7 @@ import { HelpService } from "actions/help/help.service";
import { GreetingService } from "actions/greeting/greeting.service"; import { GreetingService } from "actions/greeting/greeting.service";
import { ActivityService } from "actions/activity/activity.service"; import { ActivityService } from "actions/activity/activity.service";
import { DmService } from "actions/dm/dm.service"; import { DmService } from "actions/dm/dm.service";
import { EmbedService } from "actions/embed/embed.service"; import { CustomMessageService } from "actions/customMessage/customMessage.service";
export default class DiscordController extends EventEmitter { export default class DiscordController extends EventEmitter {
private discordService!: DiscordService; private discordService!: DiscordService;
@ -30,7 +30,7 @@ export default class DiscordController extends EventEmitter {
helpService: HelpService; helpService: HelpService;
activityService: ActivityService; activityService: ActivityService;
dmService: DmService; dmService: DmService;
embedService: EmbedService; customMessageService: CustomMessageService;
constructor() { constructor() {
super(); super();
@ -41,7 +41,7 @@ export default class DiscordController extends EventEmitter {
this.helpService = new HelpService(); this.helpService = new HelpService();
this.activityService = new ActivityService(); this.activityService = new ActivityService();
this.dmService = new DmService(); this.dmService = new DmService();
this.embedService = new EmbedService(); this.customMessageService = new CustomMessageService();
// log when running // log when running
client.once("ready", async () => { client.once("ready", async () => {
await this.setActivity(); await this.setActivity();
@ -128,7 +128,10 @@ export default class DiscordController extends EventEmitter {
await this.greetingService.handleInteraction(interaction); await this.greetingService.handleInteraction(interaction);
return; return;
case Commands.Enum.embed: case Commands.Enum.embed:
await this.embedService.handleInteraction(interaction); await this.customMessageService.handleInteraction(interaction);
return;
case Commands.Enum.message:
await this.customMessageService.handleInteraction(interaction);
return; return;
default: default:
break; break;

View File

@ -1,8 +1,12 @@
import { int, sqliteTable, text } from "drizzle-orm/sqlite-core"; import { TimestampStyles } from "discord.js";
import { timestamp } from "drizzle-orm/mysql-core";
import { integer, int, sqliteTable, text } from "drizzle-orm/sqlite-core";
export const usersTable = sqliteTable("users_table", { export const usersTable = sqliteTable("users_table", {
id: int().primaryKey({ autoIncrement: true }), id: integer().primaryKey({ autoIncrement: true }),
name: text().notNull(), name: text().notNull(),
discord_id: int().notNull().unique(), discord_id: integer().notNull().unique(),
took_medication_today: int().notNull().default(0), join_streak: integer(),
last_joined_at: integer({ mode: "timestamp" }),
took_medication_today: integer().notNull().default(0),
}); });