I have a problem with creating a channel. Here is my code:
let id = message.author.id.toString().substr(0, 4) + message.author.discriminator;
var name = `order-${message.author}-${id}`
message.createChannel(name);
This is the error I am getting:
TypeError: message.createChannel is not a function
I hope someone could help me! :-)
message.createChannel() is not a thing. You need to use guild.channels.create().
For a full list of permissions, click here.
const category = message.guild.channels.cache.get(CATEGORY_ID)
message.guild.channels.create(name, {
parent: category,
permissionOverwrites: [
{
id: message.author.id, // Takes either user ID or role ID
deny: ['VIEW_CHANNEL', 'SEND_MESSAGES'], // Denies permission(s)
allow: ['ATTACH_FILES'] // Allows permission(s)
},
{
id: message.guild.id, // guild.id doubles as the role id for the default role `#everyone`
deny: ['VIEW_CHANNEL']
}
]
})
Related
I Have defined this mongoose schema in node
`const bookingSchema = new mongoose.Schema({
tour: [
{
type: mongoose.Schema.ObjectId,
ref: 'Tour',
required: [true, 'Booking must belong to Tours!'],
},
],
user: {
type: mongoose.Schema.ObjectId,
ref: 'User',
required: [true, 'Booking must belong to User!'],
},
price: {
type: Number,
required: [true, 'Booking must have a price'],
},
createdAt: {
type: Date,
default: Date.now(),
},
paid: {
type: Boolean,
default: true,
},
});
bookingSchema.pre(/^find/, function (next) {
this.populate('user').populate({
path: 'tour',
select: 'name',
});`your text`
});
Then when i try to create a booking i use the create function
await Booking.create({ tour, user, price });`
the tour param is an array of ids
but i get this error
"Booking validation failed: tour.0: Cast to [ObjectId] failed for value "["5c88fa8cf4afda39709c295a,5c88fa8cf4afda39709c2951"]" (type string) at path "tour.0"
I can do it with only one tour if the tour property wasnt an array of objects. My main issue is that a booking can be related to many tour objects in my database
*edit after some modifications the error become
"Unexpected token u in JSON at position 0"
My front end code(angular) is this. I am making a get request to my backend(node)
createBookingCheckout(params: any): Observable<any> {
console.log('serv');
return this.http.get<any>(`${CREATE_BOOKING_CHECKOUT}`, {
params,
withCredentials: true,
});
}
So i pass the ids as query param
And this is the backend where i am trying to create the booking
exports.createBookingCheckout = catchAsync(async (req, res, next) => {
const { order, tour: strTour } = req.query;
const user = req.user._id;
const parsedOrder = JSON.parse(order);
const tour = JSON.parse(strTour);
console.log(tour);
// const tours = await tour.forEach((id) => {
// Tour.find({ id });
// });
// console.log(tours);
let price = 0;
parsedOrder.forEach(
(obj) => (price = price + obj.price_data.unit_amount * obj.quantity)
);
if (!parsedOrder && !user) return next();
await Booking.create({ tour, user, price });
res.redirect(req.originalUrl.split('?')[0]);
res.status(200).json({
status: 'success',
});
});
I think the quick solution to this is that whenever you are going to add more than a tour you should create an array push all tours IDs to the array and then add the tourArray to the new Booking that you are going to create, and when you are going to update an existing Booking, you should repeat the process.
When you are going to create a new Booking document.
Scenario 1 : with one Tour
You just pass the id of the tour {always check if the tour exist}, that's obvious and simple, at the same time mongo is going to create a table referring to the model as Tour is defined as many within your Booking model
Scenario 2 : with more than one Tour
You need to define all the Tour's IDs in an array within the body
{
"tour": [ "id-1", "id-2", ...]
}
Updating a Booking
say that you are going to add a new Tour to an existing Booking,
Booking.findByIdAndUpdate(
{_id: id},
{
// ! here all your other data
$push: {tour: new_tour}
},
// this is just to return the updated booking
{new: true, runValidators: true}
}
=> the operator $push in mongoose is what you need to push into the existing array or tour that's already in your existing Booking
The new_tour is coming from your req.body
as for sure in some cases you are going to delete a Tour ID from a Booking,
=> in that case you are going to use the operator $pull
I'm trying to script a Ticket System. I sucessfully can create a ticket but i don't know how to close it (delete it) i tried looking up stuff but i couldn't find a solution for my code.
My Code:
case 'ticket':
case 'Ticket':
var guild = client.guilds.cache.get('877207084251369512')
guild.channels.create(message.author.username + '-ticket', {
type: 'text',
topic: 'Ticket' + message.author.id,
parent: '896402801428456046',
permissionOverwrites: [
{
id: message.author.id,
allow: ['SEND_MESSAGES', 'VIEW_CHANNEL', 'READ_MESSAGE_HISTORY', 'EMBED_LINKS', 'ATTACH_FILES'],
},
{
id: message.guild.roles.everyone,
deny: ['VIEW_CHANNEL'],
},
{
id: "877570054710001735",
allow: ['SEND_MESSAGES', 'VIEW_CHANNEL'],
},
],
})
let created = new Discord.MessageEmbed()
.setTitle("Ticket-System")
.setDescription("You're Ticket was created!")
.setTimestamp()
.setFooter('Ticket System')
.setColor("GREY")
message.channel.send({embeds: [created]});
let channel = message.guild.channels.cache.find(channel => channel.name === `${message.author.username}-ticket`);
message.guild.channels.cache.get(`${channel}`)
In here
guild.channels.create(message.author.username + '-ticket', {
You used <someusername>-ticket
and in
.find(channel => channel.name === `ticket-${message.author.username}`);
You used ticket-<someusername>
Either choose to put ticket-<someusername> in both of your lines or <someusername>-ticket
PS : I recommend you using IDs instead of usernames since you know the id has only numbers when usernames can have special and annoying characters.
Also to fix some potential issues you can change channel to channel.id
message.guild.channels.cache.get(`${channel.id}`)
There will be special symbols in the channel name. You can use the following program to delete special symbols and blanks
const channelname1 = removeSpaces(`${message.author.username}`)
const channelname = channelname1.replace(/[`~!##$%^&*()_|+\-=?;:'",.<>\{\}\[\]\\\/]/gi, '');
Delete channel
Then I’m not sure how you want to delete the channel, I can only give you a way to delete the channel
channel.delete();
In addition, I suggest you can delay 0.5 seconds when defining the channel
I have a bot which is supposed to create a channel under a specific category and then add two users to this channel.
The following bit of code is "supposed" to work and add user two, but fails with DiscordAPIError: Missing Permissions.
What I can't figure out is the actual permission required for this?
function addUserToChannel(ch, user, altCh) {
console.log(user.username,"sendmsg",ch.permissionsFor(client.user).has("MANAGE_CHANNELS", false)); //returns true
if (!ch.permissionsFor(user).has("SEND_MESSAGES", false)) {
console.log("User", user.username, "lacks view-channel permission");
ch.updateOverwrite(user, { //fails here obviously
SEND_MESSAGES: true,
VIEW_CHANNEL: true
});
} else {
console.log("WARN:", user.username, " already in channel ", ch.name);
altCh.send(user.toString() + " join conversation here: " + ch.toString());
}
}
The channel is created using the following code:
function createPrivateChannel(guild, convo, user) {
let everyoneRole = guild.roles.cache.find(r => r.name === "#everyone");
let parent = guild.channels.cache.find(ch => {
//console.log(ch.id,secret.convoCat.id);
return ch.id == secret.convoCat.id;
});
return guild.channels.create(convo.chName, {
type: "text",
parent: parent,
permissionOverwrites: [
{
id: everyoneRole.id, //private channel
deny: ["VIEW_CHANNEL", "SEND_MESSAGES"]
},
{
id: client.user.id, //bot permissions
allow: [ "VIEW_CHANNEL", "SEND_MESSAGES", "READ_MESSAGE_HISTORY", "MANAGE_CHANNELS" ]
},
{
id: user.user.id, //a different user
allow: ["VIEW_CHANNEL", "SEND_MESSAGES", "READ_MESSAGE_HISTORY"]
}
]
});
}
According to the Discord documentation for the 'Edit Channel Permissions' route (which is what updateOverwrite ultimately uses):
Requires the MANAGE_ROLES permission. Only permissions your bot has in the guild or channel can be allowed/denied (unless your bot has a MANAGE_ROLES overwrite in the channel).
So I am trying to make it so when someone opens a temp channel with my command it creates a channel and then it will change the permissions of it. Here is my current code:
bot.on('message', msg =>{
if(msg.content === (`${prefix}tempchannel`)) {
var server = msg.guild;
var name = msg.author.username;
const Welcome = new Discord.MessageEmbed()
.setTitle(`Welcome, Here is your temp channel.`)
.setDescription(`<#${msg.author.id}> Ask an admin at any time to close the temp channel. \n You cannot close one yourself due to safety reasons.`)
server.channels.create(`${name} temp channel.`, { reason: `Temp channel for ${name}` })
.then((channel) => channel.send(Welcome))
msg.channel.send('Created a temp channel for you! Check your unreads.')
}})``` Could someone help please?
You can use the permissionOverwrites option like so
server.channels.create(`${name} temp channel.`, {
reason: `Temp channel for ${name}`,
permissionOverwrites: [
{
id: msg.author.id,
deny: ['VIEW_CHANNEL'],
},
],
})
https://discord.js.org/#/docs/main/stable/class/GuildChannelManager?scrollTo=create
All the permissions: https://discord.js.org/#/docs/main/stable/class/Permissions?scrollTo=s-FLAGS
This bot I am making is tasked with logging when a user receives a role and when a user has a role removed. It prints that to a desired channel. Additionally I want the bot to send data to a database for the user when they receive a certain role. This part is working. I want the code to IGNORE the database addition/removal when the bot is the one adding or removing roles. This part is not working correctly. The way I have it setup is to check the audit logs to see who the executor of the action was. The intended effect is that if the executor's username matches my bot's username, the code does not run. However, even when the bot adds or removes a user's role, and the audit log visibly shows the bot as the one completing the action, when logging the entry to the console it displays myself, not the bot, as the executor.
client.on("guildMemberUpdate", async function(oldMember, newMember){ //When a user has their roles changed (added or removed)
const entry = await oldMember.guild.fetchAuditLogs({type: 'MEMBER_UPDATE'}).then(audit => audit.entries.first()) //Find audit logs pertaining to member update
console.log(entry) //Print the data to the console
if (entry.executor.username == "PolarBot") { //If the executor of the role addition is the bot then do nothing
return;
}
else { //Otherwise execute the code
if (oldMember.author == client.user) { // Prevent bot from responding to its own messages
return
}
if (oldMember.roles.size < newMember.roles.size) { //If the old member has less roles than the new member
currency.add(oldMember.user.id, 1); //Establish user in the database
const target = oldMember.user.id //Establish target ID for the database
for (const role of newMember.roles.map(x => x.id)) { //Find the new role
const item = await CurrencyShop.findOne({ where: { name: { [Op.like]: `${oldMember.guild.roles.get(role).name}` } } }); //Set item to be the role added
const user = await Users.findOne({ where: { user_id: target } }); //Find the target location in the database and name it user
const items = await user.getItems(); //Ignore this
user.addItem(item); //Add role to the database for that uesr
if (!oldMember.roles.has(role)) { //Check to see if the old member does not have the role
oldMember.guild.channels.find(channel => channel.name === "change-logging").send({embed: { //Send log message to the correct channel
color: 16723502,
title: "**User Roles Updated:**",
description: oldMember.user.tag,
fields: [
{
name: "**New Role(s)**",
value: `${oldMember.guild.roles.get(role).name}`,
inline: true
}
],
timestamp: new Date(),
}})
}
}
}
if (oldMember.roles.size > newMember.roles.size) {
currency.add(oldMember.user.id, 1);
const target = oldMember.user.id
for (const role of oldMember.roles.map(x => x.id)) {
const item = await CurrencyShop.findOne({ where: { name: { [Op.like]: `${oldMember.guild.roles.get(role).name}` } } });
const user = await Users.findOne({ where: { user_id: target } });
const items = await user.getItems();
user.removeItem(item); //Subtract role from the data base
if (!newMember.roles.has(role)) {
oldMember.guild.channels.find(channel => channel.name === "change-logging").send({embed: {
color: 16723502,
title: "**User Roles Updated:**",
description: oldMember.user.tag,
fields: [
{
name: "**Removed Role(s)**",
value: `${oldMember.guild.roles.get(role).name}`,
inline: true
}
],
timestamp: new Date(),
}})
}
}
}
}
});
Expected Result: When logging "entry" to the console the executor section should read my bot's username.
Actual Result: I am listed as the executor.
Link to console output:
Turns out I’m a bit silly and the actual audit log event I wanted to call was MEMBER_ROLE_UPDATE not MEMBER_UPDATE