typescripteventsdiscorddiscord.jsroles

Discord.js "guildMemberUpdate" event only fires the second time i change a Nickname


The Issue:

I wanted to create a feature where the bot sets a certain prefix before the Nickname fitting my discord server theme if a user decides to change it. I'm allowing the users to change their Nickname, i just want to make sure the prefix stays inside it. This code should detect, when a user is changing its nickname to something that doesn't contain the prefix. Then it puts it right back in front of the new Nickname they've set. But somehow if i run the bot, the event registers, but doesn't fire the first time i change a nickname. If i change it again, suddenly the event fires and the nickname gets changed. I believe there's nothing wrong with my code, but rather something with the API.

My code:

import { Client } from "discord.js";

export default function (client: Client) {
    console.log("EVENT REGISTERED!");
    client.on("guildMemberUpdate", async (_, newMember) => {
        console.log("EVENT FIRED!")

        const prefix = '🔥';
        const currentNick = newMember.nickname ?? newMember.user.username;

        if (!currentNick.startsWith(prefix)) {
            const newNick = `${prefix}${currentNick}`;

            await newMember.setNickname(newNick);
            console.log(`Nickname fixed to: ${newNick}`);
        }
    });
}

Infos about my coding setup:


Solution

  • 1- Enable the right intents

    const client = new Client({
        intents: [
            GatewayIntentBits.Guilds,
            GatewayIntentBits.GuildMembers
        ]
    });
    

    2- Use partials if needed

    const client = new Client({
        intents: [
            GatewayIntentBits.Guilds,
            GatewayIntentBits.GuildMembers
        ],
        partials: [Partials.GuildMember, Partials.User]
    });
    
    3- Check nickname changes explicitly:Instead of just listening for every update, compare oldMember.nickname` vs newMember.nickname
    

    **example **

    import {
        Client,
        GuildMember,
        GatewayIntentBits,
        Partials
    } from "discord.js";
    
    export default function registerNicknameHandler(client: Client) {
        console.log("EVENT REGISTERED!");
    
        client.on("guildMemberUpdate", async (oldMember, newMember) => {
            // Only react if nickname actually changed
            if (oldMember.nickname === newMember.nickname) return;
    
            console.log("EVENT FIRED!");
    
            const prefix = "🔥";
            const currentNick = newMember.nickname ?? newMember.user.username;
    
            if (!currentNick.startsWith(prefix)) {
                const newNick = `${prefix}${currentNick}`;
    
                try {
                    await newMember.setNickname(newNick);
                    console.log(`Nickname fixed to: ${newNick}`);
                } catch (err) {
                    console.error("Failed to update nickname:", err);
                }
            }
        });
    }