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')
Related
So I want to make it so that every time a new ticket is made it will add a number example: ticket-1 | ticket-2 | ticket-3, ect. And then I want the bot to send the channel in a chat
module.exports = {
data: {
name: `GT1`
},
async execute(interaction, client, message) {
const guild = client.guilds.cache.get("1057116059750117426");
const ticketId = Math.floor(Math.random() * 9000);
await guild.channels.create({
name: `TICKET-${ticketId}`,
parent: '1057370813357109308',
})
interaction.reply({ephemeral: true, content: `Your ticket has been submited \n You can view it here -> ${guild.channels.id}` });
}
}
What you need is a way to persist data after every command. This would require some sort of data storage. I've listed a few options below:
Use a database, (On the discord.js guide they recommend using an ORM)
Store the files in a JSON object on your file system.
Here is an example for 2:
module.exports = {
data: {
name: 'GT1',
},
async execute(interaction, client, message) {
const guild = client.guilds.cache.get('1057116059750117426');
const storageBuffer = fs.readFileSync('./storage.json'); // you will input your file path here.
const storageData = JSON.parse(storageBuffer.toString());
storageData.ticket_id++; // adds one to the ticket number?
const ticketId = storageData.ticket_id;
await guild.channels.create({
name: `TICKET-${ticketId}`,
parent: '1057370813357109308',
});
interaction.reply({
ephemeral: true,
content: `Your ticket has been submited \n You can view it here -> ${guild.channels.id}`,
});
fs.writeFileSync('./storage.json', JSON.stringify(storageData)); // updates the data to your storage file
},
};
You will need to create the json file before using it.
storage.json
{
ticket_id: 0
}
As for sending to a channel you can take a look at this: https://discord.js.org/#/docs/main/stable/class/Interaction?scrollTo=channel
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}
So I've been working on a discord music bot, but whenever I try to get the bot to join a voice channel, nothing happes and I have no errors. I used console.log(getVoiceConnections()) to try and find what was wrong, and it says status: "signalling". I think it's is stuck in signalling, but I have no idea how to fix it. These are all my intents:
({ intents: [
Intents.FLAGS.GUILDS,
Intents.FLAGS.GUILD_MESSAGES,
Intents.FLAGS.GUILD_VOICE_STATES,
Intents.FLAGS.GUILD_PRESENCES
] });
and this is the code I'm using to join:
const {
joinVoiceChannel,
createAudioPlayer,
createAudioResource,
getVoiceConnections
} = require('#discordjs/voice')
module.exports = {
name: 'join',
description: "attempts to join a voicechannel",
execute(message, args) {
const connection = joinVoiceChannel({
channelId: message.member.voice.channel.id,
guildId: 828953538952298517,
adapterCreator: message.channel.guild.voiceAdapterCreator,
});
let audioPlayer = createAudioPlayer();
connection.subscribe(audioPlayer);
console.log(getVoiceConnections())
const resource = createAudioResource('')
audioPlayer.play(resource)
message.reply('Joining!');
}
}
Here's the official documentation if anyone can find my solution in there
The guildId field in your joinVoiceChannel() should not be an integer, but a String. Due to you having it as an integer it probably doesn't know what guild to connect to and is just signaling for the channel to find.
(For reference I have admin_consent for the organization with a auth scope of offline_access User.ReadWrite.All Group.ReadWrite.All AppCatalog.ReadWrite.All for my token that I use to interact with the Teams instance.)
After installing the app via POST /teams/{id}/installedApps it sends an conversationUpdate event that I respond to and save the entire ConversationReference object. It has a lot of stuff I don't need but I'm not sure what is necessary. The immediate response goes to the General channel of the specified Team.
Now I want to use that ConversationReference to post proactive notification messages to a channel that the user has designated outside of Teams. So the user has not interacted with the bot in this channel, but I can list the channel and have its ID.
I can post the message into the General channel utilizing the entire ConversationReference I captured, or message the user directly in chat via ommiting the channel speicifc fields, but I can't seem to get the message sent to a specific channel if I specify it as the channelId
const msBotAdapter = new BotFrameworkAdapter({
appId: TEAMS_CLIENT_ID,
appPassword: TEAMS_CLIENT_SECRET,
});
//Paired down the saved reference to look like this
const conversationReference = {
"user" : {
"id" : "9:1rafmaopfopakdfafMzCYlCtg",
"aadObjectId" : "fffffff-ffff-ffff-ffff-ffffffff"
},
"bot" : {
"id" : "8:sdfsfsdf-dddd-ddddd-aaaaa-vvvvvvv",
"name" : "Bot Name"
},
"conversation" : {
"isGroup" : true,
"conversationType" : "channel",
"tenantId" : "ffffffff-ssssss-ssssss-ss-ssssss"
},
"channelId" : "msteams",
"serviceUrl" : "https://smba.trafficmanager.net/amer/"
}
const heroCard = CardFactory.heroCard(label, text, undefined, undefined, {
subtitle: fromUser?.name ? `From: ${fromUser.name}` : undefined,
});
const channelId = {...retrieve channel Id}
const activity = {
recipient: {
id: channelId,
name: 'Test channel 2',
},
type: ActivityTypes.Message,
timestamp: new Date(),
localTimezone: 'America/New_York',
callerId: TEAMS_CLIENT_ID,
serviceUrl: conversationReference.serviceUrl!,
channelId,
from: conversationReference.bot as { id: string; name: string },
valueType: 'text',
attachments: [heroCard],
};
await msBotAdapter.createConversation(
conversationReference,
async turnContext => {
await turnContext.sendActivity(activity);
}
);
SUCCESS! Turns out directing the message to another channel requires manipulating the ConversationReference not (as I thought) specifying it in the Activity being sent. I'm showing this by removing the Activity I created in the original question and just sending plain text via await turnContext.sendActivity('Test Message');
const channelId = //retrieve desitnation channelId I use the graph api `/teams/${teamId}/channels`
const msBotAdapter = new BotFrameworkAdapter({
appId: TEAMS_CLIENT_ID,
appPassword: TEAMS_CLIENT_SECRET,
});
//Paired down the initial conversation reference to bare necessities, the important part is setting the `conversationReference.conversation.id` to the `channelId` that you wish the message to go to.
const conversationReference = {
"bot" : {
"id" : "8:sdfsfsdf-dddd-ddddd-aaaaa-vvvvvvv",
},
"conversation" : {
//This is where you dictate where the message goes
id: channelId
},
"serviceUrl" : "https://smba.trafficmanager.net/amer/"
}
await msBotAdapter.createConversation(
conversationReference,
async turnContext => {
await turnContext.sendActivity('Test Message');
}
);
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.