diff --git a/mydb.sqlite b/mydb.sqlite new file mode 100644 index 0000000..e69de29 diff --git a/src/actions/dm/dm.components.ts b/src/actions/dm/dm.components.ts index 0636f97..6ad4009 100644 --- a/src/actions/dm/dm.components.ts +++ b/src/actions/dm/dm.components.ts @@ -2,4 +2,6 @@ import config from "config"; import { EmbedBuilder } from "discord.js"; export const dmWelcomeContent = `hey! ich bin avocadi von [avocadi-study]()!\n\num auf den rest des servers zugreifen zu koennen, musst du dich noch vorstellen (unter <#${config.discord.channelIdIntroduction}>)!\n\n---\nname und alter:\npronomen:\nklasse/studiengang/beruf:\nhobby:\nueber mich:\n---\n\nsobald wir deine nachricht ueberprueft haben, bekommst du die rolle **lernende:r** :)`; -export const dmAcceptedContent = `huhu! du wurdest als lernende:r akzeptiert :3\nsag gerne hallo: <#${config.discord.channelIdOffTopic}> <:avocadi_cute:1321893797138923602>`; \ No newline at end of file +export const dmAcceptedContent = `huhu! du wurdest als lernende:r akzeptiert :3\nsag gerne hallo: <#${config.discord.channelIdOffTopic}> <:avocadi_cute:1321893797138923602>`; +export const dmRoleMentionAdd = `du hast die rolle **streber** erfolgreich ** *zugeteilt* ** bekommen :3 <#${config.discord.channelIdOffTopic}> <:avocadi_cute:1321893797138923602>`; +export const dmRoleMentionRemove = `du hast die rolle **streber** erfolgreich ** *entfernt* ** bekommen:3 <#${config.discord.channelIdOffTopic}> <:avocadi_cute:1321893797138923602>`; \ No newline at end of file diff --git a/src/actions/dm/dm.service.ts b/src/actions/dm/dm.service.ts index 1994769..3df14db 100644 --- a/src/actions/dm/dm.service.ts +++ b/src/actions/dm/dm.service.ts @@ -1,7 +1,7 @@ import config from "config"; import client from "lib/client"; import { getRandomInt } from "lib/utils"; -import { dmWelcomeContent, dmAcceptedContent } from "./dm.components.ts"; +import { dmWelcomeContent, dmAcceptedContent, dmRoleMentionAdd, dmRoleMentionRemove } from "./dm.components.ts"; import { Client, EmbedBuilder, @@ -85,4 +85,19 @@ export class DmService { console.error("error while sending a accept msg:", error); } } + + async roleMentionDm(member: GuildMember, add: Boolean) { + console.log("rolementionadd dm"); + try { + const contentRoleMentionDm = await (add ? dmRoleMentionAdd : dmRoleMentionRemove); + client.users.send(member, contentRoleMentionDm); + } catch (error) { + const channels = client.channels; + const channel = channels.cache.get(config.discord.channelIdNotification); + if (channel?.isTextBased() && channel?.isSendable()) { + await channel.send(`konnte keine private nachricht an <@${member.user.id}> senden`); + } + console.error("error while sending a accept msg:", error); + } + } } diff --git a/src/actions/reactRole/reactRoles.components.ts b/src/actions/reactRole/reactRoles.components.ts new file mode 100644 index 0000000..e69de29 diff --git a/src/actions/reactRole/reactRoles.service.ts b/src/actions/reactRole/reactRoles.service.ts new file mode 100644 index 0000000..9d5853d --- /dev/null +++ b/src/actions/reactRole/reactRoles.service.ts @@ -0,0 +1,69 @@ +import { DmService } from "actions/dm/dm.service"; +import config from "config"; +import type { CacheType, ChatInputCommandInteraction, Guild, GuildMember, MessageReaction, PartialMessageReaction, PartialUser, User } from "discord.js"; + +export class ReactRolesService { + dmService: DmService; + + constructor() { + this.dmService = new DmService(); + } + + async roleMention(reaction: MessageReaction | PartialMessageReaction, user: User | PartialUser, add: Boolean) { + if (!await this.validMsg(reaction.message.id)) return; + try { + await reaction.fetch(); + const guild = reaction.message.guild; + if (!guild) return; + const member = await this.getUser(guild, user); + if (!member) return; + add ? await this.giveRoleMention(member, guild, user) : await this.removeRoleMention(member, guild, user); + await this.dmService.roleMentionDm(member, add); + } catch (error) { + console.error('smt went wring while roleMention():', error); + return; + } + } + + + async giveRoleMention(member: GuildMember, guild: Guild, user: User | PartialUser) { + this.updateRoleMention(member, guild, user, true); + } + async removeRoleMention(member: GuildMember, guild: Guild, user: User | PartialUser) { + this.updateRoleMention(member, guild, user, false); + } + + async updateRoleMention(member: GuildMember, guild: Guild, user: User | PartialUser, add: Boolean) { + try { + + const role = guild.roles.cache.get(config.discord.roleMention); + if (!role) { + console.error("role ot found."); + return; + } + + if (add === member.roles.cache.has(role.id)) { + console.log(`${member.user.tag} hat die Rolle *streber* bereits.`); + return; + } + + await (add ? member.roles.add(role) : member.roles.remove(role)); + console.log(`role *streber* successfully ${add ? "added to" : "removed from"} ${member.user.tag}.`); + } catch (error) { + console.error(`error while ${add ? "added to" : "removed from"} RoleMention:`, error); + } + } + + async validMsg(id: string) { + return id === config.discord.rolesMsg; + } + + async getUser(guild: Guild, user: User | PartialUser) { + try { + return await guild.members.fetch(user.id); + } catch (error) { + console.error("error fetching user:", error); + return null; + } + } +} \ No newline at end of file diff --git a/src/config.ts b/src/config.ts index 4d5055b..9e9335c 100644 --- a/src/config.ts +++ b/src/config.ts @@ -24,7 +24,10 @@ export default { roleStudy: process.env.PEOPLE || "", roleMod: process.env.MOD || "", roleAdmin: process.env.ADMIN || "", + roleMention: process.env.MENTION || "", + rolesMsg: process.env.ROLES_NOTIFICATION_MSG || "", + rolesMsgTest: process.env.ROLES_MSG_TEST || "", // other applicationId: process.env.DISCORD_APPLICATION_ID || "", token: process.env.DISCORD_TOKEN || "", diff --git a/src/controllers/discord.controller.ts b/src/controllers/discord.controller.ts index 8517deb..d0e1e97 100644 --- a/src/controllers/discord.controller.ts +++ b/src/controllers/discord.controller.ts @@ -22,6 +22,7 @@ import { ActivityService } from "actions/activity/activity.service"; import { DmService } from "actions/dm/dm.service"; import { CustomMessageService } from "actions/customMessage/customMessage.service"; import { DynamicChannelService } from "actions/dynamicChannel/dynamicChannel.service"; +import { ReactRolesService } from "actions/reactRole/reactRoles.service"; import config from "config"; export default class DiscordController extends EventEmitter { @@ -35,9 +36,11 @@ export default class DiscordController extends EventEmitter { customMessageService: CustomMessageService; channelListeners = new Map(); dynamicChannelService: DynamicChannelService; + reactRolesService: ReactRolesService; constructor() { super(); + let channelListeners = new Map(); this.discordService = new DiscordService(); this.waterMeService = new WaterMeService(); this.greetingService = new GreetingService(); @@ -47,8 +50,16 @@ export default class DiscordController extends EventEmitter { this.dmService = new DmService(); this.customMessageService = new CustomMessageService(); this.dynamicChannelService = new DynamicChannelService(); + this.reactRolesService = new ReactRolesService(); + + client.on("messageReactionAdd", async (reaction, user) => { + await this.reactRolesService.roleMention(reaction, user, true); + }); + + client.on("messageReactionRemove", async (reaction, user) => { + await this.reactRolesService.roleMention(reaction, user, false); + }); - let channelListeners = new Map(); // log when running client.once("ready", async () => { await this.setActivity(); @@ -62,7 +73,7 @@ export default class DiscordController extends EventEmitter { console.log(message.id); if (message.channel.type === ChannelType.DM) { console.log("got msg"); - this.dmService.forward(message); + await this.dmService.forward(message); } }); diff --git a/src/lib/client.ts b/src/lib/client.ts index 0202479..0af69a9 100644 --- a/src/lib/client.ts +++ b/src/lib/client.ts @@ -8,16 +8,13 @@ const client = new Client({ IntentsBitField.Flags.GuildMessages, IntentsBitField.Flags.GuildMessageReactions, IntentsBitField.Flags.GuildMessagePolls, + IntentsBitField.Flags.GuildVoiceStates, IntentsBitField.Flags.MessageContent, IntentsBitField.Flags.DirectMessages, IntentsBitField.Flags.DirectMessageReactions, IntentsBitField.Flags.DirectMessageTyping, - IntentsBitField.Flags.DirectMessagePolls, - GatewayIntentBits.DirectMessages, - GatewayIntentBits.MessageContent, - GatewayIntentBits.Guilds, - GatewayIntentBits.GuildVoiceStates,], - partials: [Partials.Channel, Partials.Message] + IntentsBitField.Flags.DirectMessagePolls,], + partials: [Partials.Channel, Partials.Message, Partials.Reaction] }); await client.login(config.discord.token);