I have a command in which one user virtually kisses another
The output is a message #User1 kissed #User2
But I want that instead of tags on the user, only names were written, like this so that it was user1 kissed user2
In theory, everything should work like this
`**${message.author.username}** kissed **${userToKiss.username}**`
But if the name for message.author is defined, then there is none for userToKiss and I end up with this
user1 kissed undefined
How can I get the name for the second user?
const { Command } = require('discord.js-commando');
const Discord = require('discord.js');
module.exports = class KissCommand extends Command {
constructor(client) {
super(client, {
name: 'kiss',
memberName: 'kiss',
group: 'reywl',
description: 'Kiss the mentioned user',
guildOnly: true,
args: [
{
key: 'userToKiss',
prompt: 'Please select the member you want to kiss.',
type: 'member',
default: 'isempty',
wait: 0.0001
}
]
});
}
run(message, { userToKiss }) {
if (userToKiss == 'isempty') {
return message.channel.send('Please select the member you want to kiss.')}
if (userToKiss.id == message.author.id) {
return message.channel.send('You cant kiss yourself!');
}
else {
const embed = new Discord.MessageEmbed()
.setDescription(`**${message.author}** kissed **${userToKiss}**`)
message.channel.send(embed)
}
setTimeout(() => message.delete(), 1000)
}};
For deep explanation for your work, to do this you need to code first about the member, we always do about member and author
Author is for the author itself and the member for your members who are you going to call
I don't know if commando and normal command handlers are the same but here's the code what you wanted.
const member = message.mentions.members.first() //this is the way how you ping a member
${member.user.username} //the word user is the user member
for the author you can only do this
${message.author.username}
You can also ping a member using their Id's
const member = message.guild.members.cache.get(args[0])
${member.user.username}
So the main output is
${message.author.username} kissed ${member.user.username}
This is how it works
const kissed = await message.guild.members.fetch(userToKiss.id);
${kissed.user.username}
Related
Following the discord.js guide for creating a currency system. I'm getting this error: WHERE parameter "user_id" has invalid "undefined" value
I can run my !balance command fine and I'm getting currency per message. This is for the !inventory command. My code:
index.js
client.on('messageCreate', async message => {
if (message.author.bot) return;
if (!message.content.startsWith(prefix)) return;
const commandBody = message.content.slice(prefix.length);
const args = commandBody.split(' ');
const command = args.shift().toLowerCase();
if (command === 'balance') {
const target = message.author;
return message.reply(`${target.tag} has ${currency.getBalance(target.id)}🍰!`);
}
if (command == "inventory") {
const target = message.author;
const user = await Users.findOne({where: {user_id: target.id}});
const items = await user.getItems();
if (!items.length) return message.reply(`${target.tag} has nothing!`);
return message.reply(`${target.tag} currently has ${items.map(i => `${i.amount} ${i.item.name}`).join(' , ')}`);
}
});
Users.js
module.exports = (sequelize, DataTypes) => {
return sequelize.define('users', {
user_id: {
type: DataTypes.STRING,
primaryKey: true,
},
balance: {
type: DataTypes.INTEGER,
defaultValue: 0,
allowNull: false,
},
}, {
timestamps: false,
});
};
I made sure to run the dbInit.js file.
I'm a bit lost on what to try, honestly. This is my first time working with Discord.js; I expected to see the user inventory, but it seems like the user_id is undefined and I don't know how to fix that.
The problem is not the WHERE-clause in the main code, but the WHERE-clause within the code of getItems().
I managed to find a solution here:
https://github.com/discordjs/guide/discussions/1085
It relates to the final code published on github by the creators of the guide. I don't know why it's different than in the guide, but it is:
https://github.com/discordjs/guide/blob/main/code-samples/sequelize/currency/14/dbObjects.js
Other than the 3 attributes hf.EnrollmentId, hf.type and hf.Affiliation, I've created a custom attribute named email and added it as attrs:[{name: 'email', value: rahul18#gmail.com, ecert: true}] and it was successfully added to the attribute list.
In my chaincode, i'm able to get the enrollmentId by using the following command : cid.GetAttributeValue(ctx.GetStub(), "hf.EnrollmentID") but i'm not able to get the email using the same method cid.GetAttributeValue(ctx.GetStub(), "email")
Any help would be appreciated regarding why the first one is working and the second isn't
Does getAttributeValue not support custom made attributes?
Here is an example that may be helpful. A previous stackoverflow contribution helped me with a similar situation. I don't have the link for it right now, but thanks anyway.
First of all, you state that you have added attributes successfully. Here is some code as an example which I had placed in the code file for registering users.
//create user attr array
let registerAttrs = [];
let registerAttribute = {
name: "recycler",
value: config.recycler,
ecert: true,
};
registerAttrs.push(registerAttribute);
const secret = await ca.register({
affiliation: config.affiliation,
enrollmentID: config.recycler,
role: "client",
attrs: registerAttrs,
},
adminUser
);
The contract code is able to find the value of "recycler" using the following code. Of particular importance is the getCurrentUserId() function.
async getCurrentUserId(ctx) {
let id = [];
id.push(ctx.clientIdentity.getID());
var begin = id[0].indexOf("/CN=");
var end = id[0].lastIndexOf("::/C=");
let userid = id[0].substring(begin + 4, end);
return userid;}
async getCurrentUserType(ctx) {
let userid = await this.getCurrentUserId(ctx);
// check user id; if admin, return type = admin;
// else return value set for attribute "type" in certificate;
if (userid == "admin") {
return userid;
}
return ctx.clientIdentity.getAttributeValue(userid);}
The user type returned from the getCurrentUserType function is subsequently examined further up in the contract code, as shown in the following example.
async readTheAsset(ctx, id) {
let userType = await this.getCurrentUserType(ctx);
const buffer = await ctx.stub.getState(id);
const asset = JSON.parse(buffer.toString());
asset.userType = userType;
asset.userID = ctx.clientIdentity.getID();
if (asset.userType === "recycler") {
throw new Error(`The record cannot be read by ${asset.userType} `);
}
return asset;}
I feel sure that this code should solve your issue, as there is a lot of similarity.
const updateObj = {
enrollmentID : userName,
type:'client',
affiliation:'' ,
attrs: [{name: 'email', value: email, ecert: true}, {name: 'orgId', value: orgId, ecert: true}, {name: 'userId', value: userName, ecert: true}] ,
}
const response = await identityService.update(userName, updateObj ,adminUser)
const clientUser = await provider.getUserContext(userIdentity, userName);
const reenrollment = await caClient.reenroll(clientUser,
[{
name: 'email',
optional: false
},
{
name: 'orgId',
optional: false
},
{
name: 'userId',
optional: false
}
]);
So what I am trying to do here is when the command is used, the new channel is created, then the user mentions the channel and puts their word, then the hangman is sent within the channel they mentioned. But I get lost cause rn it's running everything at once, how do I make it listen for a new "command"?
const { hangman } = require('reconlx')
module.exports = {
name : 'hangman',
description: "Wanna play hangman?",
aliases: ['hang'],
execute(client, message, args, Discord) {
if(!message.member.hasPermission("MANAGE_MESSAGES")) return message.channel.send('You need manage messages permission.')
const channel = message.mentions.channels.first() || message.guild.channels.cache.get(args[0])
message.guild.channels.create(`HangMan`, {
type: 'text',
permissionOverwrites: [
{
id: message.guild.id,
deny: ['VIEW_CHANNEL']
},
{
id: message.author.id,
allow: ['VIEW_CHANNEL', 'SEND_MESSAGES', 'ADD_REACTIONS', 'ATTACH_FILES']
}
]
}).then(async channel => {
channel.send("Please mention a channel, then add your word. It should look something like this `#the game channel (your word)`")
message.reply(`Scroll to the very top of the server to add your word! <#${channel.id}>`)
})
if(message.content.includes('#')) {
message.reply('Hangman has started!')};
if(!channel) return message.channel.send('Please specify a channel')
const word = args.slice(1).join(" ")
if(!word) return message.channel.send('Please specify a word to guess.')
const hang = new hangman({
message: message,
word: word,
client: client,
channelID: channel.id,
})
hang.start();
}
}
I'm creating a discord bot using node.js and i want it to create a private text channel on a server and add to it the user sending the command "!create" and the bot itself.
I have found a way to make a text channel using this answer: How to create a text channel
but i can't find a way to make it private and add people to it.
I do it always like this:
const everyoneRole = client.guilds.get('SERVER ID').roles.find('name', '#everyone');
const name = message.author.username;
message.guild.createChannel(name, 'text')
.then(r => {
r.overwritePermissions(message.author.id, { VIEW_CHANNEL: true });
r.overwritePermissions(client.id, { VIEW_CHANNEL: true });
r.overwritePermissions(everyoneRole, { VIEW_CHANNEL: false });
})
.catch(console.error);
First, we define the everyoneRole. Then we use the method overwritePermissions() to overwrite the permissions of the newly created guild textchannel. There we give the message author and the bot the permission to view the channel and we revoke the everyone role the permission to view this channel.
Thanks to #gilles-heinesch for the lead. The API of discord.js got drastically changed over time, so here is an updated version:
const { Client, Permissions } = require('discord.js');
/** #param {string|number} serverId - a "snowflake" ID you can see in address bar */
async function createPrivateChannel(serverId, channelName) {
const guild = await client.guilds.fetch(serverId);
const everyoneRole = guild.roles.everyone;
const channel = await guild.channels.create(channelName, 'text');
await channel.overwritePermissions([
{type: 'member', id: message.author.id, allow: [Permissions.FLAGS.VIEW_CHANNEL]},
{type: 'member', id: client.user.id, allow: [Permissions.FLAGS.VIEW_CHANNEL]},
{type: 'role', id: everyoneRole.id, deny: [Permissions.FLAGS.VIEW_CHANNEL]},
]);
}
https://discord.js.org/#/docs/main/stable/class/ChannelManager
Use cache collection
const channels = message.guild.channels.cache
const myChannel = channels.find(channel => channel.name === 'channel name')
So, I having an issue of sending a DM to a specific person without an author tag, and without a mention of the person. I tried duplicating the mention array:
/*jshint esversion: 6*/
const commando = require('discord.js-commando');
class Msgowner extends commando.Command {
constructor(client) {
super(client, {
name: 'msgowner',
group: 'info',
memberName: 'msgowner',
description: 'Gives rules on mock or legit duels.',
examples: ['ladderrules type'],
});
}
async run(message) {
var user = {
id: '12345',
username: 'Bloodmorphed',
discriminator: '12345',
avatar: 'd510ca3d384a25b55d5ce7f4c259b2d0',
bot: false,
lastMessageID: null,
lastMessage: null,
};
user.send('Test');
}
}
module.exports = Msgowner;
There is a reason why I need to send DMs this way, but I can't seem to figure out how. (The error it gives now is a unknown function). Also replacing id and discriminator with generic numbers, but they are correct in my code.
Try something like this - get the member you're looking for using message.channel.members.find() method:
async run(message) {
// get Collection of members in channel
let members = message.channel.members;
// find specific member in collection - enter user's id in place of '<id number>'
let guildMember = members.find('id', '<id number>');
// send Direct Message to member
guildMember.send('test message');
}
Edit: It looks like it's also possible to find users outside the current channel by doing something like this:
async run(message) {
// get client from message's channel
let client = message.channel.client;
// fetch user via given user id
let user = client.fetchUser('<id number>')
.then(user => {
// once promise returns with user, send user a DM
user.send('Test message');
});
}
Okay, found my answer:
async run(message) {
var user = {
id: '12345,
username: 'Bloodmorphed',
discriminator: '12345',
avatar: 'd510ca3d384a25b55d5ce7f4c259b2d0',
bot: false,
lastMessageID: null,
lastMessage: null,
};
console.log(user);
message.member.user.send('Test');
}
}
module.exports = Msgowner;
EDIT: This was NOT the answer, still looking for one.