Entonces, mi objetivo es tener un comando que muestre todos los comandos de bots y los permisos de usuario adjuntos. Tengo la función para obtener la lista de comandos.
var commands = await interaction.guild.commands.fetch() .catch(error => { interaction.reply({content: 'Unknown Error', ephemeral: true}) })Y todo esto funciona bien, obtengo una buena colección de mis comandos, mi pregunta es (que no he podido resolver durante 2 horas). ¿Cómo puedo iterar sobre esta colección y obtener los permisos para cada comando? Sé cómo obtener los permisos para un solo comando con esto.
var perms = await interaction.guild.commands.permissions.fetch({command: command.id})pero, ¿cómo puedo obtener una lista JSON con todos los permisos para cada comando que también puede acomodar permisos indefinidos (ya que algunos comandos no tienen permisos adjuntos)
El problema que he tenido es que una función para hacerlo así
await commands.each(async (command) => { await interaction.guild.commands.permissions.fetch({command: command.id}) .then(perms => { console.log(`**${command.name}** \`${command.id}\``) fields.push({title: command.id, value: perms}) }) .catch(error => { //Triggered if command has no perms fields.push({title: command.id, value: 'None'}) }) })con esto, el código posterior que usa los campos continúa antes de que se llenen los campos, lo que significa que mi mensaje siempre está vacío. ¿Cómo puedo hacer que el siguiente código espere a que este ciclo haya terminado por completo?
Tienes que usar Promise.all así:
await Promise.all(commands.map(async (command) => { try { const perms = await interaction.guild.commands.permissions.fetch({command: command.id}) console.log(`**${command.name}** \`${command.id}\``) fields.push({title: command.id, value: perms}) } catch(e) { //Triggered if command has no perms fields.push({title: command.id, value: 'None'}) } })) // At this point the fields array is full (order not guaranteed however)En primer lugar, no confundiría await con .then() .
Puede usar Array.from() para convertir Discord.Collection de ApplicationCommand s en una matriz y luego simplemente usar for...of .
También tenga en cuenta que ApplicationCommand tiene la propiedad .permissions , por lo que puede aprovechar eso.
Solución sencilla (sin devoluciones de llamada):
const fields = []; const commands = await interaction.guild.commands.fetch(); for (const command of Array.from(commands.values())) { try { const permissions = await command.permissions.fetch(); fields.push({title: command.id, value: permissions}); } catch { fields.push({title: command.id, value: "None"}); } } Después de eso, la matriz de fields se verá así (convertida en un JSON para visualización):
[ { "title": "878405785552551936", "value": "None" }, { "title": "878405793769193473", "value": "None" }, { "title": "878405796118003714", "value": [ { "id": "878405800618491907", "permission": true, "type": "USER" } ] } ] Probado usando discord.js ^13.1.0 .
Tal vez usando para esperar... de
La instrucción for await...of crea un ciclo iterando sobre objetos iterables asincrónicos, así como sobre iterables de sincronización, incluidos: String, Array, objetos tipo Array incorporados (por ejemplo, argumentos o NodeList), TypedArray, Map, Set, e iterables asíncronos/sincrónicos definidos por el usuario. Invoca un enlace de iteración personalizado con declaraciones que se ejecutarán para el valor de cada propiedad distinta del objeto. Esta declaración solo se puede usar dentro de una función asíncrona.