How to fix this.uuid is not a function discord.js - discord.js

Hello actually I wanted to make minecraft playerinfo command but I wanted it and I got it on github it was a bit old but I tried to convert it to discord.js v14 code. But I got this error.
TypeError: this.getUuid is not a function
Can you help me please heres the original code: https://github.com/Jystro/Minecraft-info-bot/blob/master/commands/player.js
const mojang = require('mojang-api');
const https = require('https');
const {
EmbedBuilder
} = require('discord.js');
module.exports = {
name: 'playerinfo',
description: 'Diplays player\'s name, uuid, skin, cape and name history',
run: async (client, message, args) => {
//check that a value is sent
if(!args.length) {
message.reply('please specify the player\'s uuid');
return;
}
let uuid = args[0]
//get uuid
this.getUuid(args[0], (err, uuid) => {
if(err) {
message.channel.send('An error occurred. This might be because the player does not exist');
return;
}
//check that uuid exists
mojang.profile(uuid, (err, resp) => {
if(err) {
message.reply('that player\'s uuid does not exist');
return;
}
//get name history
mojang.nameHistory(uuid, (err, resp1) => {
if(err) {
message.reply('there was an error trying to retrieve the data');
console.log(err);
return;
}
let nameHistory = [];
resp1.forEach(element => {
nameHistory.push(element.name);
});
nameHistory = nameHistory.join(', ');
//create embed message
const embedMessage = new EmbedBuilder()
.setColor('Random')
.setTitle(resp.name)
.setDescription(resp.name + "'s profile")
.setThumbnail('https://crafatar.com/avatars/' + resp.id + '.png?overlay')
.addFields(
{
name: 'Name',
value: resp.name
},
{
name: 'UUID',
value: resp.id
},
{
name: 'Skin',
value: 'https://crafatar.com/skins/' + resp.id + '.png'
})
.setImage('https://crafatar.com/renders/body/' + resp.id + '.png?overlay')
//check if cape exists
let cape = 'https://crafatar.com/capes/' + resp.id + '.png';
const req = https.request(cape, res => {
if(res.statusCode == 200) {
embedMessage.fields.push({ name: 'Cape', value: cape });
}
embedMessage.fields.push({ name: 'Name history', value: nameHistory });
//send embed
message.channel.send({ embed: embedMessage });
});
req.on('error', err => {
console.log(err);
message.reply('there was an error while retrieving the cape');
})
req.end();
});
});
})
},
//function to get uuid from uuid/name
getUuid(value, cb) {
let error = false;
let regex = /^[a-f0-9]{32}$/i //regex for uuids
if(!value.match(regex)) {
mojang.nameToUuid(value, (err, resp) => {
if(err || !resp.length) {
error = true;
cb(error, null);
return;
}
cb(error, resp[0].id);
});
}
else { cb(error, value); }
}
}

The issue is your usage of the this keyword and arrow functions.
The main takeaway is this:
Arrow functions don't redeclare this, while anonymous functions do.
This means that when you call the run() method somewhere else in the code, the this keyword in the run method will refer to whatever this is in the current context of where it was executed, which isn't what you want.
To redeclare this to your object, you should rewrite your arrow function as an anonymous function.
module.exports = {
run: async function(client, message, args) {
// you can now safely use `this` in this method
}
}

Related

Args cannot read proprety of undefined ("0")

So basically I have that command that use modals to create giveaways but there is one line bothering me. It is right under the run: async line. I have been trying to search the discord documentation about a change that happened from v13 to v14 (yes this code uses discord.js v1.14.5) but I have found nothing. The error is the following: <rejected> TypeError: Cannot read properties of undefined (reading '0'). If you need anymore code, ask me (like the sub files or the rest of the code). Thanks in advance!
Code:
const {
ChannelType,
ButtonBuilder,
ActionRowBuilder,
ComponentType,
TextInputStyle,
TextInputBuilder,
ModalBuilder,
ButtonStyle,
ApplicationCommandOptionType,
} = require("discord.js");
const ems = require("enhanced-ms");
const start = require("./sub/start");
const pause = require("./sub/pause");
const resume = require("./sub/resume");
const end = require("./sub/end");
const reroll = require("./sub/reroll");
const list = require("./sub/list");
const edit = require("./sub/edit");
module.exports = {
name: "giveaway",
description: "Start a giveaway!",
type: 1,
id: "Giveaway",
options: [
{
name: "start",
description: "start a giveaway",
type: ApplicationCommandOptionType.Subcommand,
options: [
{
name: "channel",
description: "the channel to start the giveaway in",
type: ApplicationCommandOptionType.Channel,
channelTypes: [ChannelType.GuildText],
required: true,
},
],
},
{
name: "pause",
description: "pause a giveaway",
type: ApplicationCommandOptionType.Subcommand,
options: [
{
name: "message_id",
description: "the message id of the giveaway",
type: ApplicationCommandOptionType.String,
required: true,
},
],
},
{
name: "resume",
description: "resume a paused giveaway",
type: ApplicationCommandOptionType.Subcommand,
options: [
{
name: "message_id",
description: "the message id of the giveaway",
type: ApplicationCommandOptionType.String,
required: true,
},
],
},
{
name: "end",
description: "end a giveaway",
type: ApplicationCommandOptionType.Subcommand,
options: [
{
name: "message_id",
description: "the message id of the giveaway",
type: ApplicationCommandOptionType.String,
required: true,
},
],
},
{
name: "reroll",
description: "reroll a giveaway",
type: ApplicationCommandOptionType.Subcommand,
options: [
{
name: "message_id",
description: "the message id of the giveaway",
type: ApplicationCommandOptionType.String,
required: true,
},
],
},
{
name: "list",
description: "list all giveaways",
type: ApplicationCommandOptionType.Subcommand,
},
{
name: "edit",
description: "edit a giveaway",
type: ApplicationCommandOptionType.Subcommand,
options: [
{
name: "message_id",
description: "the message id of the giveaway",
type: ApplicationCommandOptionType.String,
required: true,
},
{
name: "add_duration",
description: "the number of minutes to add to the giveaway duration",
type: ApplicationCommandOptionType.Integer,
required: false,
},
{
name: "new_prize",
description: "the new prize",
type: ApplicationCommandOptionType.String,
required: false,
},
{
name: "new_winners",
description: "the new number of winners",
type: ApplicationCommandOptionType.Integer,
required: false,
},
],
},
],
permissions: {
DEFAULT_MEMBER_PERMISSIONS: "ManageMessages" // User permissions needed
},
/**
* #param {ChatInputCommandInteraction} interaction
*/
run: async (client, interaction, config, db, args, message) => {
const sub = args[0]?.toLowerCase();
//line above
let response;
//
if (sub === "start") {
if (!args[1]) return message.safeReply("Incorrect usage! Please provide a channel to start the giveaway in");
const match = message.guild.findMatchingChannels(args[1]);
if (!match.length) return message.safeReply(`No channel found matching ${args[1]}`);
return await runModalSetup(message, match[0]);
}
//
else if (sub === "pause") {
const messageId = args[1];
response = await pause(message.member, messageId);
}
//
else if (sub === "resume") {
const messageId = args[1];
response = await resume(message.member, messageId);
}
//
else if (sub === "end") {
const messageId = args[1];
response = await end(message.member, messageId);
}
//
else if (sub === "reroll") {
const messageId = args[1];
response = await reroll(message.member, messageId);
}
//
else if (sub === "list") {
response = await list(message.member);
}
//
else if (sub === "edit") {
const messageId = args[1];
if (!messageId) return message.safeReply("Incorrect usage! Please provide a message id");
return await runModalEdit(message, messageId);
}
//
else response = "Not a valid sub command";
await message.safeReply(response);
},
async interactionRun(interaction) {
const sub = interaction.options.getSubcommand();
let response;
//
if (sub === "start") {
const channel = interaction.options.getChannel("channel");
return await runModalSetup(interaction, channel);
}
//
else if (sub === "pause") {
const messageId = interaction.options.getString("message_id");
response = await pause(interaction.member, messageId);
}
//
else if (sub === "resume") {
const messageId = interaction.options.getString("message_id");
response = await resume(interaction.member, messageId);
}
//
else if (sub === "end") {
const messageId = interaction.options.getString("message_id");
response = await end(interaction.member, messageId);
}
//
else if (sub === "reroll") {
const messageId = interaction.options.getString("message_id");
response = await reroll(interaction.member, messageId);
}
//
else if (sub === "list") {
response = await list(interaction.member);
}
//
else if (sub === "edit") {
const messageId = interaction.options.getString("message_id");
const addDurationMs = ems(interaction.options.getInteger("add_duration"));
if (!addDurationMs) {
return interaction.followUp("Not a valid duration");
}
const newPrize = interaction.options.getString("new_prize");
const newWinnerCount = interaction.options.getInteger("new_winners");
response = await edit(interaction.member, messageId, addDurationMs, newPrize, newWinnerCount);
}
//
else response = "Invalid subcommand";
await interaction.followUp(response);
},
};
//...
Command handler:
const client = require("../index");
const { PermissionsBitField, Routes, REST, User } = require('discord.js');
const fs = require("fs");
const colors = require("colors");
module.exports = (client, config) => {
console.log("0------------------| Application commands Handler:".blue);
let commands = [];
// Slash commands handler:
fs.readdirSync('./commands/slash/').forEach((dir) => {
console.log('[!] Started loading slash commands...'.yellow);
const SlashCommands = fs.readdirSync(`./commands/slash/${dir}`).filter((file) => file.endsWith('.js'));
for (let file of SlashCommands) {
let pull = require(`../commands/slash/${dir}/${file}`);
if (pull.name, pull.description, pull.type == 1) {
client.slash_commands.set(pull.name, pull);
console.log(`[HANDLER - SLASH] Loaded a file: ${pull.name} (#${client.slash_commands.size})`.brightGreen);
commands.push({
name: pull.name,
description: pull.description,
type: pull.type || 1,
options: pull.options ? pull.options : null,
default_permission: pull.permissions.DEFAULT_PERMISSIONS ? pull.permissions.DEFAULT_PERMISSIONS : null,
default_member_permissions: pull.permissions.DEFAULT_MEMBER_PERMISSIONS ? PermissionsBitField.resolve(pull.permissions.DEFAULT_MEMBER_PERMISSIONS).toString() : null
});
} else {
console.log(`[HANDLER - SLASH] Couldn't load the file ${file}, missing module name value, description, or type isn't 1.`.red)
continue;
};
};
});
// User commands handler:
fs.readdirSync('./commands/user/').forEach((dir) => {
console.log('[!] Started loading user commands...'.yellow);
const UserCommands = fs.readdirSync(`./commands/user/${dir}`).filter((file) => file.endsWith('.js'));
for (let file of UserCommands) {
let pull = require(`../commands/user/${dir}/${file}`);
if (pull.name, pull.type == 2) {
client.user_commands.set(pull.name, pull);
console.log(`[HANDLER - USER] Loaded a file: ${pull.name} (#${client.user_commands.size})`.brightGreen);
commands.push({
name: pull.name,
type: pull.type || 2,
});
} else {
console.log(`[HANDLER - USER] Couldn't load the file ${file}, missing module name value or type isn't 2.`.red)
continue;
};
};
});
// Message commands handler:
fs.readdirSync('./commands/message/').forEach((dir) => {
console.log('[!] Started loading message commands...'.yellow);
const UserCommands = fs.readdirSync(`./commands/message/${dir}`).filter((file) => file.endsWith('.js'));
for (let file of UserCommands) {
let pull = require(`../commands/message/${dir}/${file}`);
if (pull.name, pull.type == 3) {
client.message_commands.set(pull.name, pull);
console.log(`[HANDLER - MESSAGE] Loaded a file: ${pull.name} (#${client.user_commands.size})`.brightGreen);
commands.push({
name: pull.name,
type: pull.type || 3,
});
} else {
console.log(`[HANDLER - MESSAGE] Couldn't load the file ${file}, missing module name value or type isn't 2.`.red)
continue;
};
};
});
// Registering all the application commands:
if (!config.Client.ID) {
console.log("[CRASH] You need to provide your bot ID in config.js!".red + "\n");
return process.exit();
};
const rest = new REST({ version: '10' }).setToken(config.Client.TOKEN || process.env.TOKEN);
(async () => {
console.log('[HANDLER] Started registering all the application commands.'.yellow);
try {
await rest.put(
Routes.applicationCommands(config.Client.ID),
{ body: commands }
);
console.log('[HANDLER] Successfully registered all the application commands.'.brightGreen);
} catch (err) {
console.log(err);
}
})();
};
InteractionCreate.js:
const { EmbedBuilder } = require("discord.js");
const client = require("../../index");
const config = require("../../config/config.js");
const { QuickDB } = require("quick.db");
const db = new QuickDB();
module.exports = {
name: "interactionCreate"
};
client.on('interactionCreate', async (interaction) => {
if (interaction.isChatInputCommand()) {
const command = client.slash_commands.get(interaction.commandName);
if (!command) return;
try {
command.run(client, interaction, config, db);
} catch (e) {
console.error(e)
};
};
if (interaction.isUserContextMenuCommand()) { // User:
const command = client.user_commands.get(interaction.commandName);
if (!command) return;
try {
command.run(client, interaction, config, db);
} catch (e) {
console.error(e)
};
};
if (interaction.isMessageContextMenuCommand()) { // Message:
const command = client.message_commands.get(interaction.commandName);
if (!command) return;
try {
command.run(client, interaction, config, db);
} catch (e) {
console.error(e)
};
};
if (interaction.isModalSubmit()) { // Modals:
const modal = client.modals.get(interaction.customId);
if (!modal) return interaction.reply({
embeds: [
new EmbedBuilder()
.setDescription('Something went wrong... Probably the Modal ID is not defined in the modals handler.')
.setColor('Red')
],
ephemeral: true
});
try {
modal.run(client, interaction, config, db);
} catch (e) {
console.error(e)
};
}
});

How to implement Authorization with Custom Directives in apollo with graphql-tools/utils?

I know that Apollo 2 allowed custom directives by extending the class "SchemaDirectiveVisitor." However, I am using apollo 3 and I know that the way to achieve this now is by using graphql-tools/utils and graphql-tools/schema.
In my index.js I have the following code:
const serverServer = async () => {
app.use(AuthMiddleware);
app.use(
cors({
origin: 'mydomain',
})
);
let schema = makeExecutableSchema({
typeDefs: [typeDefsLibrary, typeDefsDynamicContent, userTypeDefs],
resolvers: {
Query,
Mutation,
Article,
Blog,
Podcast,
SermonNotes,
Sermon,
// dynamic Content
Friday,
Thursday,
// Post Content
Commentary,
Quote,
Thought,
UserContent_SermonNotes,
// User Content
User,
All_Posts,
},
});
schema = AuthorizationDirective(schema, 'auth');
const apolloServer = new ApolloServer({
schema,
context: ({ req }) => {
const { isAuth, user } = req;
return {
req,
isAuth,
user,
};
},
});
await apolloServer.start();
apolloServer.applyMiddleware({ app: app, path: '/api' });
app.listen(process.env.PORT, () => {
console.log(`listening on port 4000`);
});
};
serverServer();
then on my schema file I have:
directive #auth(requires: [RoleName] ) on OBJECT | FIELD_DEFINITION
enum RoleName {
SUPERADMIN
ADMIN
}
type Commentary #auth(requires: [SUPERADMIN, ADMIN]) {
ID: ID
USER_ID: ID
VERSE_ID: String
body: String
category_tags: String
referenced_verses: String
verse_citation: String
created_date: String
posted_on: String
creator(avatarOnly: Boolean): User
comments(showComment: Boolean): [Commentary_Comment]
approvals: [Commentary_Approval]
total_count: Int
}
and this is my custom directive code:
const { mapSchema, getDirective, MapperKind } = require('#graphql-tools/utils');
const { defaultFieldResolver } = require('graphql');
const { ApolloError } = require('apollo-server-express');
//const { logging } = require('../../helpers');
module.exports.AuthorizationDirective = (schema, directiveName) => {
return mapSchema(schema, {
[MapperKind.FIELD]: (fieldConfig, _fieldName, typeName) => {
const authDirective = getDirective(schema, fieldConfig, directiveName);
console.log('auth Directive line 10: ', authDirective);
if (authDirective && authDirective.length) {
const requiredRoles = authDirective[0].requires;
if (requiredRoles && requiredRoles.length) {
const { resolve = defaultFieldResolver } = fieldConfig;
fieldConfig.resolve = function (source, args, context, info) {
if (requiredRoles.includes('PUBLIC')) {
console.log(
`==> ${context.code || 'ANONYMOUS'} ACCESSING PUBLIC RESOLVER: ${
info.fieldName
}`
);
//logging(context, info.fieldName, args);
return resolve(source, args, context, info);
}
if (!requiredRoles.includes(context.code)) {
throw new ApolloError('NOT AUTHORIZED', 'NO_AUTH');
}
console.log(`==> ${context.code} ACCESSING PRIVATE RESOLVER: ${info.fieldName}`);
//logging(context, info.fieldName, args);
return resolve(source, args, context, info);
};
return fieldConfig;
}
}
},
});
};
But is not working. It seems like it is not even calling the Custom Directive. As you see I have a "console.log('auth Directive line 10: ', authDirective);" on my schema directive function that return "undefined."
I know this post is so ling but I hope someone can help!
Thanks in advance!
Below is the code worked for me
I have used [MapperKind.OBJECT_FIELD]: not [MapperKind.FIELD]:
I have referred this from #graphql-tools ->
https://www.graphql-tools.com/docs/schema-directives#enforcing-access-permissions
`
const { mapSchema, getDirective, MapperKind } = require('#graphql-tools/utils');
const { defaultFieldResolver } = require('graphql');
const HasRoleDirective = (schema, directiveName) => {
return mapSchema(schema, {
// Executes once for each object field in the schems
[MapperKind.OBJECT_FIELD]: (fieldConfig, _fieldName, typeName) => {
// Check whether this field has the specified directive
const authDirective = getDirective(schema, fieldConfig, directiveName);
if (authDirective && authDirective.length) {
const requiredRoles = authDirective[0].requires;
// console.log("requiredRoles: ", requiredRoles);
if (requiredRoles && requiredRoles.length) {
// Get this field's original resolver
const { resolve = defaultFieldResolver } = fieldConfig;
// Replace the original resolver with function that "first" calls
fieldConfig.resolve = function (source, args, context, info) {
// console.log("Context Directive: ", context);
const { currentUser } = context;
if(!currentUser) throw new Error("Not Authenticated");
const { type } = currentUser['userInfo']
const isAuthorized = hasRole(type, requiredRoles);
if(!isAuthorized) throw new Error("You Have Not Enough Permissions!")
//logging(context, info.fieldName, args);
return resolve(source, args, context, info);
};
return fieldConfig;
}
}
}
})
}
`

Making only admins execute commands

The problem is that I couldn't figure out a way to make this command only accessible by admins. I've tried using if statements, however, I failed. message. I am not sure if member. roles. cache. has( ' 732524984777572363 ' ) would allow members with the role ID 732524984777572363 to execute it since there's already an if statement.
const Discord = require('discord.js');
const fs = require('fs');
const cooldown = new Set();
module.exports.run = async (client, msg, args, config) => {
if(cooldown.has(msg.author.id)) {
msg.reply(`You need to wait ${config.COOLDOWN} minutes to use this command again!`)
.then((m) => {
msg.delete();
setTimeout(() => {
m.delete();
}, 5000);
});
} else {
fs.readFile('./accounts/crunchy.txt', 'utf8', function(err, data) {
if (err) throw err;
data = data + '';
var lines = data.split('\n');
let account = lines[Math.floor(Math.random() * 1)];
fs.writeFile('./accounts/crunchy.txt', lines.slice(1).join('\n'), function(err) {
if(err) throw err;
});
let embed = new Discord.RichEmbed()
.addField('Rate Us Here | قيمنا هنا ', `<#915***********80>`)
.addField('CrunchyRoll Account',`\n**${account}**`)
.setThumbnail('**************************')
.setColor("#363940")
.setFooter('Bot made by ******')
.setTimestamp();
msg.author.send(embed);
msg.reply('I\'ve sent you the account! Please check your DM!')
.then(m => {
setTimeout(() => {
m.delete();
}, 900000);
});
cooldown.add(msg.author.id);
setTimeout(() => {
cooldown.delete(msg.author.id);
}, config.COOLDOWN * 60 * 1000);
});
}
};
module.exports.help = {
name: `CrunchyRoll`,
description: `Sends you a CrunchyRoll account!`
};```
Simply adding a role check and a server check will prevent any issues!
The first line would be:
if(!msg.guild) return;
This line makes sure the user is running the command in a server(guild), this prevents a member role from being undefined or null.
The second line would be:
if(!msg.author.roles.cache.has('ROLE_ID_HERE')) return;
This prevents a user from running a command if they do not have a specific role.
The final code would be:
if(!msg.guild) return;
if(!msg.author.roles.cache.has('ROLE_ID_HERE')) return;
You will need to add this to the top of your code in order for it to work as you'd like.
const Discord = require('discord.js');
const fs = require('fs');
const cooldown = new Set();
module.exports.run = async (client, msg, args, config) => {
if(!msg.guild) return;
if(!msg.member.roles.cache.has('ROLE_ID_HERE')) return;
if(cooldown.has(msg.author.id)) {
msg.reply(`You need to wait ${config.COOLDOWN} minutes to use this command again!`)
.then((m) => {
msg.delete();
setTimeout(() => {
m.delete();
}, 5000);
});
} else {
fs.readFile('./accounts/crunchy.txt', 'utf8', function(err, data) {
if (err) throw err;
data = data + '';
var lines = data.split('\n');
let account = lines[Math.floor(Math.random() * 1)];
fs.writeFile('./accounts/crunchy.txt', lines.slice(1).join('\n'), function(err) {
if(err) throw err;
});
let embed = new Discord.RichEmbed()
.addField('Rate Us Here | قيمنا هنا ', `<#915***********80>`)
.addField('CrunchyRoll Account',`\n**${account}**`)
.setThumbnail('**************************')
.setColor("#363940")
.setFooter('Bot made by ******')
.setTimestamp();
msg.author.send(embed);
msg.reply('I\'ve sent you the account! Please check your DM!')
.then(m => {
setTimeout(() => {
m.delete();
}, 900000);
});
cooldown.add(msg.author.id);
setTimeout(() => {
cooldown.delete(msg.author.id);
}, config.COOLDOWN * 60 * 1000);
});
}
};
module.exports.help = {
name: `CrunchyRoll`,
description: `Sends you a CrunchyRoll account!`
};

Discord.js | Cannot read property 'displayName' of undefined

I am making a discord bot for a friend and everything worked until i tried to make an unban command. when i tried to unban someone it did not work. then i looked at the error. it displayed:
TypeError: Cannot read property 'displayName' of undefined
at C:\Users\user\folder_name\commands\unban.js:37:67
at processTicksAndRejections (internal/process/task_queues.js:97:5)
Unhandled promise rejection: TypeError: Cannot read property 'displayName' of undefined
at C:\Users\user\folder_name\commands\unban.js:37:67
at processTicksAndRejections (internal/process/task_queues.js:97:5)
this is my code
const Discord = require('discord.js');
module.exports = {
name: 'unban',
description: 'unban user',
aliases: [],
cooldown: 0,
args: true,
usage: '<mention> [reason]',
guildOnly: true,
execute(message, args, client) {
console.log(message.content);
const embedMsg = new Discord.RichEmbed()
.setColor('#0000ff')
.setAuthor(message.author.username, message.author.displayAvatarURL)
.setThumbnail(message.author.displayAvatarURL)
.setTimestamp()
.setFooter('botname', client.user.displayAvatarURL);
let member = message.mentions.members.first();
if (!message.member.hasPermission('BAN_MEMBERS')) {
embedMsg.setDescription(`You don't have permission to unban!`);
return message.channel.send(embedMsg);
}
if (!args.length >= 1) {
embedMsg.setDescription('^unban takes at least one argument! the proper usage is ^unban <mention> [reason]');
message.channel.send(embedMsg);
}
if (args.length < 2) {
message.guild.unban(member).then(() => {
embedMsg.setDescription(`${member.displayName} has been succesfully unbanned`);
return message.channel.send(embedMsg);
}).catch((err) => {
embedMsg.setDescription(`Could not unban ${member.displayName}`);
console.log(err);
return message.channel.send(embedMsg);
});
return;
}
newargs = "";
for (var i = 1; i < args.length; i++) {
newargs += (args[i] + " ");
}
message.guild.unban(member).then(() => {
embedMsg.setDescription(`${member.displayName} has been succesfully unbanned for reason ${newargs}`);
return message.channel.send(embedMsg);
}).catch((err) => {
embedMsg.setDescription(`Could not unban ${member.displayName}`);
console.log(err);
return message.channel.send(embedMsg);
});
return;
}
}
does anyone know what i am doing wrong?
It says in the discord.js's official docs that the unban method returns a member object https://discord.js.org/#/docs/main/stable/class/Guild?scrollTo=unban
The reason why it says 'undefined' is because the member object you are trying to access is not in the server/guild. So, therefore you need add a reference to the member object that the method returns:
message.guild.unban('some user ID').then((member) => {
embedMsg.setDescription(`${member.username} has been succesfully unbanned for reason ${newargs}`);
return message.channel.send(embedMsg);
}
Unbun method return a user promise, so user dont have property displayName, you need use .username
And you can use user.id for unban, so right way will be let member = message.mentions.members.first() || args[0]
This check doing wrong, because its not stop code execute
if (!args.length < 2) {
embedMsg.setDescription('^unban takes at least one argument! the proper usage is ^unban <mention> [reason]');
return message.channel.send(embedMsg);
}
Amm and whats this part code doing? Why its duplicate?
if (args.length < 2) {
message.guild.unban(member)
.then(() => {
embedMsg.setDescription(`${member.username} has been succesfully unbanned`);
return message.channel.send(embedMsg);
})
.catch((err) => {
embedMsg.setDescription(`Could not unban ${member.username}`);
console.log(err);
return message.channel.send(embedMsg);
});
return;
}
The edited code
const Discord = require('discord.js');
module.exports = {
name: 'unban',
description: 'unban user',
aliases: [],
cooldown: 0,
args: true,
usage: '<mention> [reason]',
guildOnly: true,
execute(message, args, client) {
const embedMsg = new Discord.RichEmbed()
.setColor('#0000ff')
.setAuthor(message.author.username, message.author.displayAvatarURL)
.setThumbnail(message.author.displayAvatarURL)
.setTimestamp()
.setFooter('botname', client.user.displayAvatarURL);
let member = message.mentions.members.first() || args[0]
if (!message.member.hasPermission('BAN_MEMBERS')) {
embedMsg.setDescription(`You don't have permission to unban!`);
return message.channel.send(embedMsg);
}
if (!args.length < 2) {
embedMsg.setDescription('^unban takes at least one argument! the proper usage is ^unban <mention> [reason]');
return message.channel.send(embedMsg);
}
let newargs = args.splice(1,args.length).join(' ')
message.guild.unban(member)
.then(() => {
embedMsg.setDescription(`${member.username} has been succesfully unbanned for reason ${newargs}`);
return message.channel.send(embedMsg);
})
.catch((err) => {
embedMsg.setDescription(`Could not unban ${member.username}`);
console.log(err);
return message.channel.send(embedMsg);
});
}
}

How wait a "Array for each" function?

I got a little problem with synchronous/asynchronous system in the function "Array.foreach".
I don't know how to force my code to wait its end.
I tried to use await/async system but my code did not wait the code in "async responseDB =>".
This is my class:
...
let responsesDTO = [];
await Array.prototype.forEach.call(await searchResponsesByQuestionAndUserId(questions[cpt].idquestion, idUser), async responseDB => {
if(responseDB !== undefined){
const responseDTO = {
response_id:0,
response_text:"",
response_type:""
}
const responseEntity = await searchResponseByResponseId(responseDB.response_id);
responseDTO.response_id = responseDB.response_id;
responseDTO.response_text= responseEntity.text;
responseDTO.response_type= responseDB.type;
responsesDTO.push(responseDTO);
}
});
questionResponse.responses=responsesDTO;
questionResponses[cpt]=questionResponse;
}
Could you help me please? Thanks in advance.
I had to mock your async functions. However, the relevant part is to use for..of instead of forEach
async function searchResponsesByQuestionAndUserId() {
let responsesDB = [];
for (let i = 0; i < 10; i++) {
responsesDB.push({
response_id: parseInt(1000 * Math.random(), 10),
type: 'whatever ' + i
});
}
return new Promise((res) => {
window.setTimeout(() => {
res(responsesDB);
}, 1500);
});
}
async function searchResponseByResponseId(response_id) {
return new Promise((res) => {
window.setTimeout(() => {
res({
text: 'text for response ' + response_id
});
}, 300);
});
}
async function getResponsesDTO() {
let responsesDTO = [],
responsesDB = await searchResponsesByQuestionAndUserId();
for (let responseDB of responsesDB) {
if (responseDB === undefined) {
continue;
}
let responseDTO = {
response_id: 0,
response_text: "",
response_type: ""
},
responseEntity = await searchResponseByResponseId(responseDB.response_id);
responseDTO.response_id = responseDB.response_id;
responseDTO.response_text = responseEntity.text;
responseDTO.response_type = responseDB.type;
responsesDTO.push(responseDTO);
console.log({responseDTO});
}
return responsesDTO;
}
getResponsesDTO().then(responsesDTO => {
console.log(responsesDTO);
});

Resources