discord.ts icon indicating copy to clipboard operation
discord.ts copied to clipboard

Guards TypeError: undefined is not a function

Open Satont opened this issue 3 years ago • 15 comments

Unhandled rejection TypeError: undefined is not a function
    at DGuard.guard [as _fn] (/config/workspace/plumeware/src/guards/SlashCommandPermission.ts:5:55)
    at next (/config/workspace/plumeware/node_modules/@typeit/src/decorators/classes/Method.ts:83:37)
    at /config/workspace/plumeware/node_modules/@typeit/src/decorators/classes/Method.ts:97:34
    at DSlash.<anonymous> (/config/workspace/plumeware/node_modules/@typeit/src/decorators/classes/Method.ts:29:43)
    at Bot.executeSlash (/config/workspace/plumeware/node_modules/@typeit/src/Client.ts:368:24)
    at AppDiscord.onMessage (/config/workspace/plumeware/src/events/interaction.ts:8:12)
    at next (/config/workspace/plumeware/node_modules/@typeit/src/decorators/classes/Method.ts:74:37)
    at /config/workspace/plumeware/node_modules/@typeit/src/decorators/classes/Method.ts:97:34
    at DOn.<anonymous> (/config/workspace/plumeware/node_modules/@typeit/src/decorators/classes/Method.ts:29:43)
    at Bot.<anonymous> (/config/workspace/plumeware/node_modules/@typeit/src/logic/metadatas/MetadataStorage.ts:301:30)

SlashCommandPermission.ts

import { GuardFunction, ArgsOf } from '@typeit/discord';
import { PermissionResolvable } from 'discord.js';

export function SlashCommandPermission(permissions: PermissionResolvable[] | PermissionResolvable) {
  const guard: GuardFunction<ArgsOf<'interaction'>> = async ([interaction], client, next, guardDatas) => {
    const perms = Array.isArray(permissions) ? permissions : [permissions];
    const guildMember = interaction.guild.members.cache.get(interaction.member.user.id);
    const hasPermissions = perms.every((perm) => guildMember.permissions.has(perm));

    if (!hasPermissions) {
      guardDatas.error = 'You have no access to this command';
    }

    await next();
  };

  return guard;
}

Some controller:

@Discord()
@Group('channel', 'Add or remove channel to bot watching list')
@Guard(SlashCommandPermission('MANAGE_CHANNELS'))
export abstract class AppDiscord {
  @Slash('add')
  async add(
    @Option('channelId', { description: 'id of the channel for listening on join', required: true })
    channelId: string,
    interaction: CommandInteraction,
    guardDatas: Record<string, string>,
  ) {
    if (guardDatas.error) {
      interaction.reply(guardDatas.erorr);
    } else {
      const result = await add(interaction, channelId);
      interaction.reply(result);
    }
  }
}

Satont avatar Jul 04 '21 01:07 Satont

https://github.com/OwenCalvin/discord.ts/blob/slash/examples/guards/guards/Say.ts

check above example for proper usage and let us know if issue persist

samarmeena avatar Jul 04 '21 04:07 samarmeena

Changed my code to

export const SlashCommandPermission = (permissions: PermissionResolvable[] | PermissionResolvable) => {
  const guard: GuardFunction<ArgsOf<'message'> | CommandInteraction> = async (data, client, next, guardDatas: GuardDatas) => {
    console.log(data instanceof CommandInteraction);
    if (data instanceof CommandInteraction) {
      const perms = Array.isArray(permissions) ? permissions : [permissions];
      const guildMember = data.guild.members.cache.get(data.member.user.id);
      const hasPermissions = perms.every((perm) => guildMember.permissions.has(perm));

      if (!hasPermissions) {
        guardDatas.error = 'You have no access to this command';

        data.reply({ embeds: [noPermissionError] });
      } else {
        await next();
      }
    } else {
      await next();
    }
  };

  return guard;
};

Now i has no errors, but seems like nothing responsed to me in discord. I mean when i using some slash command, then it's failed.

It's even not logging does it's instance of interaction or not.

Command is now more simple:

@Slash('add')
  async add(
    @Option('channelId', { description: 'id of the channel for listening on join', required: true })
    channelId: string,
    interaction: CommandInteraction,
  ) {
    interaction.reply('Test');
  }

Satont avatar Jul 04 '21 04:07 Satont

Btw, just copied example of Say guard, same behavior.

Satont avatar Jul 04 '21 04:07 Satont

Make you are using this PR OwenCalvin/discord.ts/pull/62

and try this

export function ExampleGaurd(): GuardFunction {
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
  const guard: GuardFunction<ArgsOf<"interaction">> = async (interaction, client, next, _guardDatas: string[]) => {
    console.log(interaction instanceof CommandInteraction);
    await next();
  };
  return guard;
}


@Discord()
@Guild(yourguild)
@Guard(ExampleGaurd())
export abstract class example {
  @Slash("testguard", { description: "test guard" })
  async testguard(interaction: CommandInteraction) {
    await interaction.reply('guard is working');
    return;
  }
}

this example, has been tested right before this comment and working okay

samarmeena avatar Jul 04 '21 04:07 samarmeena

Sadly, but not working for me.

Am i executing interactions correctly?

 @On('interaction')
  onMessage([interaction]: ArgsOf<'interaction'>, client: Client) {
    info(`Interaction comed: ${interaction.type}`);
    client.executeInteraction(interaction);
  }

Satont avatar Jul 04 '21 05:07 Satont

it's okay but you can log each steps, that all are executing correctly

btw interaction event has been rename to interactionCreate

samarmeena avatar Jul 04 '21 05:07 samarmeena

and test your function without guard, that it's being executed.

samarmeena avatar Jul 04 '21 05:07 samarmeena

btw interaction event has been rename to interactionCreate

Yea i know, and i see deprecation warning. But it missed typings on your branch and has only 'interaction' for me.

But everything like botid is here, so i installed your branch correctly, right?

Satont avatar Jul 04 '21 05:07 Satont

yes, log each steps that all are executing for debug

samarmeena avatar Jul 04 '21 05:07 samarmeena

Ok, i just checked, interaction is comed, but not executed.


@Discord()
abstract class AppDiscord {
  @On('interaction')
  onMessage([interaction]: ArgsOf<'interaction'>, client: Client) {
    info(`Interaction comed: ${interaction.type}`);
    client.executeInteraction(interaction);
  }
}

image

@Discord()
@Group('channels', 'Add or remove channel to bot watching list')
//@Guard(SlashCommandPermission('MANAGE_CHANNELS'))
export abstract class AppDiscord {
 @Slash('add')
 //@Guard(ExampleGaurd())
 async add(
   @Option('channelId', { description: 'id of the channel for listening on join', required: true })
   channelId: string,
   interaction: CommandInteraction,
 ) {
   interaction.reply('test');
 }

But nothing returned from bot.

Satont avatar Jul 04 '21 05:07 Satont

you can pull new updates, I have added warning in console if a unknown interaction called

samarmeena avatar Jul 04 '21 05:07 samarmeena

and to resolve your issue, create a test repo to produce bug. I will verify the issue in your repo.

samarmeena avatar Jul 04 '21 05:07 samarmeena

const testMe: GuardFunction<CommandInteraction> = async (messageOrCommand, client, next, nextObj) => {
  console.log("text");
  await next();
};

samarmeena avatar Jul 07 '21 05:07 samarmeena

check out this example https://github.com/oceanroleplay/discord.ts/blob/slash/examples/guards/guards/NotBot.ts from @AndyClausen

samarmeena avatar Jul 07 '21 07:07 samarmeena