accept user discord implementation

This commit is contained in:
mo
2026-03-01 16:50:43 +01:00
parent 331fea2c10
commit 0e014dd08d
8 changed files with 93 additions and 22 deletions

View File

@@ -5,12 +5,15 @@ import type { GuildMember } from "discord.js";
export class RolesService implements RolesServiceInterface<GuildMember> { export class RolesService implements RolesServiceInterface<GuildMember> {
private logger = createLogger("RolesService"); private logger = createLogger("RolesService");
async assignRole(user: GuildMember, role: string) { async assignRole(user: GuildMember, roleId: string) {
const roleToAssign = user.guild.roles.cache.find((r) => r.name === role); const roleToAssign = user.guild.roles.cache.find((r) => r.id === roleId);
if (!roleToAssign) { if (!roleToAssign) {
this.logger.error(`Role ${role} not found in guild ${user.guild.name}.`); this.logger.error(
`Role ${roleId} not found in guild ${user.guild.name}.`,
);
return; return;
} }
this.logger.info(`Role ${roleId} found in guild ${user.guild.name}.`);
await user.roles.add(roleToAssign); await user.roles.add(roleToAssign);
} }
@@ -23,10 +26,12 @@ export class RolesService implements RolesServiceInterface<GuildMember> {
await user.roles.remove(roleToRemove); await user.roles.remove(roleToRemove);
} }
/*** get all roles of GuildMember */
async getRoles(user: GuildMember) { async getRoles(user: GuildMember) {
return user.roles.cache.map((role) => role.name); return user.roles.cache.map((role) => role.name);
} }
/*** check if GuildMember has a specific role */
async hasRole(user: GuildMember, role: string) { async hasRole(user: GuildMember, role: string) {
return user.roles.cache.some((r) => r.name === role); return user.roles.cache.some((r) => r.name === role);
} }

View File

@@ -0,0 +1,10 @@
import { AcceptUserService } from "@avocadi/bot-core/features/accept-user/accept-user.service";
import { i18nService } from "@avocadi/bot-core/lib/i18n";
import type { User } from "discord.js";
import { messagesService } from "entities/messages/messages.service";
export const acceptUserService = new AcceptUserService<User>(
messagesService,
i18nService,
"de",
);

View File

@@ -3,7 +3,10 @@ import client from "lib/client";
import { logger } from "lib/common-logger"; import { logger } from "lib/common-logger";
export class LogChannelService { export class LogChannelService {
private logChannelId = config.channelMapping.text.log; private logChannelId =
process.env.NODE_ENV === "production"
? config.channelMapping.text.log
: config.channelMapping.text.testing;
async getLogChannel() { async getLogChannel() {
const logChannel = await client.channels.fetch(this.logChannelId); const logChannel = await client.channels.fetch(this.logChannelId);

View File

@@ -1,20 +1,68 @@
import { Roles } from "@avocadi/bot-core/entities/roles/roles.schema"; import { createLogger } from "@avocadi/bot-core/lib/logger";
import { ReactionRolesService } from "features/reaction-roles/reaction-roles.service"; import type { User } from "@fluxerjs/core";
import { config } from "config";
import { RolesService } from "entities/roles/roles.service";
import { acceptUserService } from "features/accept-user/accept-user.service";
import { logChannelService } from "features/log-channel/log-channel.service";
import client from "lib/client"; import client from "lib/client";
const reactionRolesService = new ReactionRolesService(); const logger = createLogger("ReactionsListener");
// Currently only used for the "people" role, but can be extended to handle multiple roles based on the reaction emoji // client.on("messageReactionRemove", async (reaction, user) => {
// reactionRolesService.handleReaction(
// reaction,
// user,
// Roles.enum.people,
// "remove",
// );
// });
client.on("messageReactionAdd", async (reaction, user) => { client.on("messageReactionAdd", async (reaction, user) => {
reactionRolesService.handleReaction(reaction, user, Roles.enum.people, "add"); const guild = reaction.message.guild;
}); if (!guild) {
logger.error(`Guild not found for message ${reaction.message.id}.`);
return;
}
logger.info(`Guild found for message ${reaction.message.id}.`);
client.on("messageReactionRemove", async (reaction, user) => { const channelIntroduction = await client.channels.fetch(
reactionRolesService.handleReaction( config.channelMapping.text.introduction,
reaction,
user,
Roles.enum.people,
"remove",
); );
const message = await reaction.message.fetch();
// check if valid channel
if (message.guild?.id && message.channel?.id === channelIntroduction?.id) {
logger.info("valid channel");
const member = guild?.members.cache.get(user.id);
// check if member who reacted has role MOD
if (member?.roles.cache.get(config.roleMapping.mod)) {
const messageAuthor_User = await message.author.fetch();
if (messageAuthor_User) {
const roleMemberId = config.roleMapping.people;
const messageAuthor_GuildMember = await guild?.members.fetch(
messageAuthor_User.id,
);
if (
!messageAuthor_GuildMember?.roles.cache.find(
(r) => r.id === roleMemberId,
)
) {
logger.info(`accepting ${messageAuthor_User?.username}...`);
const rolesService = new RolesService();
rolesService.assignRole(messageAuthor_GuildMember, roleMemberId);
await acceptUserService.sendDmAcceptUser(messageAuthor_User);
await logChannelService.sendLogMessage(
`introduction of <@${messageAuthor_User.id}> (${messageAuthor_User.username}) got accepted`,
);
}
}
}
}
}); });

View File

@@ -5,7 +5,10 @@ import client from "lib/client";
export class LogChannelService { export class LogChannelService {
private logger = createLogger("LogChannelService"); private logger = createLogger("LogChannelService");
private logChannelId = config.channelMapping.text.log; private logChannelId =
process.env.NODE_ENV === "production"
? config.channelMapping.text.log
: config.channelMapping.text.testing;
async getLogChannel() { async getLogChannel() {
this.logger.debug(`fetching log channel with ID: ${this.logChannelId}`); this.logger.debug(`fetching log channel with ID: ${this.logChannelId}`);

View File

@@ -1,5 +0,0 @@
import config from "config";
import { EmbedBuilder } from "discord.js";
export const dmWelcomeContent = `hey! ich bin avocadi von [avocadi-study](<https://discord.gg/kkryyeXu3S>)!\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>`;

View File

@@ -0,0 +1,3 @@
export default {
dmAcceptUser: `huhu! du wurdest als lernende:r akzeptiert :3\nsag gerne hallo!`,
} as const;

View File

@@ -0,0 +1,4 @@
export default {
dmAcceptUser: `hey there! you've been accepted :3
feel free to say hello!`,
} as const;