0

I'm currently building a Discord app that allows me to view a user's status (online, DND, offline) and what songs they are listening to. This works perfectly in my own server:

My app works in the server

However, when I switch to DMs, none of my commands (activity, ping, user) show up:

Commands are missing in DMs

My project directory is structured as follows:

commands/
  └── utility/
        ├── ping.js
        ├── check_activity.js
        ├── user.js
server/
  ├── api.js
  ├── models/
        └── activity.js
deploy-commands.js
index.js

The commands work fine in a server but do not function in DMs, and I can't figure out why.

index.js (excluding MongoDB-related parts)

const fs = require('node:fs');
const path = require('node:path');
const { Client, Collection, Events, GatewayIntentBits, MessageFlags } = require('discord.js');
const { token } = require('./config.json');

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

client.commands = new Collection();
const foldersPath = path.join(__dirname, 'commands');
const commandFolders = fs.readdirSync(foldersPath);

for (const folder of commandFolders) {
    const commandsPath = path.join(foldersPath, folder);
    const commandFiles = fs.readdirSync(commandsPath).filter(file => file.endsWith('.js'));
    for (const file of commandFiles) {
        const filePath = path.join(commandsPath, file);
        const command = require(filePath);
        if ('data' in command && 'execute' in command) {
            client.commands.set(command.data.name, command);
        } else {
            console.warn(`[WARNING] The command at ${filePath} is missing a required "data" or "execute" property.`);
        }
    }
}

client.once(Events.ClientReady, readyClient => {
    console.log(`Ready! Logged in as ${readyClient.user.tag}`);
});

client.on(Events.InteractionCreate, async interaction => {
    if (!interaction.isChatInputCommand()) return;
    const command = interaction.client.commands.get(interaction.commandName);

    if (!command) {
        console.error(`No command matching ${interaction.commandName} was found.`);
        return;
    }

    try {
        await command.execute(interaction);
    } catch (error) {
        console.error(error);
        const errorMessage = 'There was an error while executing this command!';
        if (interaction.replied || interaction.deferred) {
            await interaction.followUp({ content: errorMessage, flags: MessageFlags.Ephemeral });
        } else {
            await interaction.reply({ content: errorMessage, flags: MessageFlags.Ephemeral });
        }
    }
});

client.login(token);

I have tried:

  • Searching online for similar issues, but I couldn't find anything useful.
  • Checking if I need different permissions or intents for DMs.

Is this happening because my bot relies on "guild"-related functions, which do not work in DMs? If so, what should I change to support both servers and DMs?

I'm new to JavaScript and Discord app development, so any help would be greatly appreciated! Thanks!


also my deploy-commands.js:

const { REST, Routes } = require('discord.js');
const { clientId, guildId, token } = require('./config.json');
const fs = require('node:fs');
const path = require('node:path');

const commands = [];
const foldersPath = path.join(__dirname, 'commands');
const commandFolders = fs.readdirSync(foldersPath);

for (const folder of commandFolders) {
    const commandsPath = path.join(foldersPath, folder);
    const commandFiles = fs.readdirSync(commandsPath).filter(file => file.endsWith('.js'));
    for (const file of commandFiles) {
        const filePath = path.join(commandsPath, file);
        const command = require(filePath);
        if ('data' in command && 'execute' in command) {
            commands.push(command.data.toJSON());
        } else {
            console.log(`[WARNING] The command at ${filePath} is missing a required "data" or "execute" property.`);
        }
    }
}

const rest = new REST().setToken(token);

(async () => {
    try {
        console.log(`Started refreshing ${commands.length} application (/) commands.`);
        const data = await rest.put(
            Routes.applicationCommands(clientId),
            { body: commands },
        );

        console.log(`Successfully reloaded ${data.length} application (/) commands.`);
    } catch (error) {
        console.error(error);
    }
})();
2
  • stackoverflow.com/a/73975351/12368176 According to the answer in the other thread, you are missing an intent: GatewayIntentBits.DirectMessages and partial: Partials.Channel Commented Mar 9 at 22:31
  • @ColinT hi! i think this does not work for me..? still i can see my app when i open the button, but what shows is only the name and nothing below; i am also going to post my deploy-commands.js which obtained the commands and i think maybe something is wrong there Commented Mar 10 at 1:57

1 Answer 1

0

If the commands rely on guild-specific functions, then the commands will probably just crash/fail, but as far as I can tell they should still show up once registered, at least. It's a little hard to say since I don't know what your command body looks like, but if you have the intents correct, then it may be a contexts and/or integration_types issue. (Documentation link)

Command contexts: specifies where the command should be available: 0 = guild, 1 = in DMs with the bot directly, 2 = group DMs/private channels (if the user has the bot authorized on their account).

For integration_types:, that specifies which installation type the command should be available: 0 means the command will be available in guilds, while 1 means available to user-authorized installs.

You can combine contexts and integration types to specify multiple areas, too - example, one of my bot's 'available everywhere' commands:

{
    name: `trivia`,
    description: `Play a trivia game!`,
    integration_types: [0, 1],
    contexts: [0, 1, 2]
}

Good luck!

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.