I need to set users permissions, i tried
chanel2.overwritePermissions(message.member,{'SEND_MESSAGES': true,'READ_MESSAGES': true})
but it overwrited all permissions (for everyone not just message.member), not just add specific permissions for message.member (but for the 1 member, it does what i need)
Its best if you refer to this guide for all of the information you need to know about setting user permissions in a channel. It looks like it is erroring because message.member is not grabbing the user id to set in the overwritePermissions. Ill explain it all here, but next time try adding some error information and context to your question and code :)
You need to make sure that you have a channel object, so you can grab that like so:
const channelID = message.channel.id //alternatively you can hardcode one like so: "588868740980932620"
const channel = message.guild.channels.find(c => {return c.id === channelID})
After you grab the channel object, you can now set the channel permissions like so:
// channel is whatever your constant variable is in the section above
// message.member.user.id is identical to message.author.id
channel.overwritePermissions(message.member.user.id, {
SEND_MESSAGES: true,
READ_MESSAGES: true,
ATTACH_FILES: true
});
You can find permission flags here.
Hopefully, this helps you. DiscordJS Guide and Discord JS Docs are very helpful areas to look for help.
Related
What I'm trying to achieve is simple:
send a message like links: [link1](https://example.com/1), [link1](https://example.com/2) via a bot
get it displayed as "links: link1, link1"
In a ephemeral follow up, it works as expected:
const content = "links: [link1](https://example.com/1), [link1](https://example.com/2)"
await interaction.followUp({
ephemeral: true,
content,
})
But when I send this to a public channel like this:
await channel.send(content)
I'm getting it as plain text (links: [link1](https://example.com/1), [link1](https://example.com/2)) except the links are clickable.
Is it possible to get the same result as in an ephemeral message?
I've checked the permissions, there's only "embed" links (which sounds like "allow links in embeds", and not "allow links in messages) and it is enabled anyway on server for everyone, for the bot and in the channel. So what am I missing here?
PS Here they say that "it's only possible if the message was sent with webhook though", but I'm not quite sure what does this mean (can this be different for a public and an ephemeral message?)
You cannot use hyper links in normal messages sent by a bot. You need to use a Webhook. Considering you're using discord.js, see this guide on their documentation. When using something like that it will work as expected
const { WebhookClient } = require('discord.js');
const webhookClient = new WebhookClient({ url: "WEBHOOK_URL" });
webhookClient.send({
content: "[Hello world](https://github.com)",
username: "Webhook Username",
});
Otherwise you may use embeds and send one of these with your bot and the content you wish to have.
Right, so I've found a solution based on suggestion by Krypton. As an embed doesn't look nice and manual creation of a webhook is not an option for me, I've found that I can create a webhook on the go and use it.
After some testing, I've figured that such webhooks are also permanent (although they can be found in another part of settings than the manually created ones); they should be deleted as there's a limit of 15 webhooks – an attempt to create more fails (with DiscordAPIError[30007]: Maximum number of webhooks reached (15)).
Instead of doing
await channel.send(content)
I've put
// a guard, TypeScript requires us to be sure
if(channel instanceof TextChannel) {
const webhook = await channel.createWebhook({
// a message from a webhook has a different sender, here we set its name,
// for instance the same as the name of our bot (likewise, we can set an avatar)
name: "MyBot",
})
await webhook.send(content)
await webhook.delete()
}
This seems to be a minimal code change to get the links working.
I'm trying to get all online members (with Bots) via this Code:
#client.command() async def printstats(ctx):
#define the variables
oc = 0
for user in ctx.guild.members:
if user.status != discord.Status.offline:
oc+=1
However, all as I get a result, is the number 1, even though there are 200 members online.
I already searched through the whole internet amd couldn't find a solution that worked. Could you please help me?
You have this issue because your bot is not using the presence intent, hence the bot can only see itself as online, and no other users, hence the value of 1. To fix this, you need to:
Enable the presence intent and server members in the developer portal
Then make sure to enable this intent in your code like so:
intents = discord.Intents()
intents.presences, intents.members = True, True
bot = commands.Bot(command_prefix="?", intents=intents) # whatever your prefix is etc, or client = discord.Client(intents=intents)
I just began trying to learn how to write my first Discord bot this morning so I am very inexperienced with discord.js, but I am familiar with JavaScript. However I have been searching for a couple of hours trying to find a way to call a function whenever a user in my server receives or loses a role.
In my server I have added the Patreon bot which assigns a role to users who become patrons. And I would like to create a custom bot that posts "hooray username" in my general channel when a user receive the patron role.
I can not find any example that shows how to detect when a user gains or loses a role. Is it possible to do this simply using an event? Or would I possibly need to periodically iterate over all users and maintain a list of their current roles while checking for changes?
I apologize that my question doesn't include any code or examples but I haven't made any progress and am reaching out to the SO community for guidance.
You want to use the event guildMemberUpdate.
You can compare the oldMember state to the newMember state and see what roles have changed.
This is not the most elegent solution but will get the job done.
client.on('guildMemberUpdate', (oldMember, newMember) => {
// Roles
const oldRoles = oldMember.roles.cache,
newRoles = newMember.roles.cache;
// Has Role?
const oldHas = oldRoles.has('role-id'),
newHas = newRoles.has('role-id');
// Check if removed or added
if (oldHas && !newHas) {
// Role has been removed
} else if (!oldHas && newHas) {
// Role has been added
}
});
https://discord.js.org/#/docs/main/stable/class/Client?scrollTo=e-guildMemberUpdate
This is simple with Client#guildMemberUpdate. Here’s some simple code that may help you
(This is the shortest code I could come up with)
client.on('guildMemberUpdate', async (oldMember, newMember) => {
if(oldMember.roles.cache.has('patreonRoleId')) return;
if(newMember.roles.cache.has('patreonRoleId')) {
//code here to run if member received role
//Warning: I didn’t test it as I had no time.
}
})
To see the removed role, just put the logical NOT operator (!) in front of both of the if statements like this:
if(!oldMember.roles.cache.has('patreonRoleId'))
if(!newMember.roles.cache.has('patreonRoleId'))
Note: make sure you have guildMembers intent enabled from the developers portal
I am trying to make my bot's role a pink color for the current server using the Client.on("ready") However whenever I run the bot with what I currently have the console returns:
(node:6504) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'cache' of undefined
Here is my code I am currently using. I know I need to for loop on every guild but I'm not sure how I would do that, I could use a for or just a .forEach however I can't find the correct way to do such.
const role = client.guild.roles.cache.get('Aiz Basic+');
role.edit({ name: 'Aiz Basic+', color: '#FFC0CB' });
In advance thank you to anybody who replies and helps with my message.
Client#Guild Isn‘t existing. Only Client#Guilds. You can fix this problem by looping through the cache of all your guilds with:
client.guilds.cache.forEach((g) => { })
And inside the loop you can use your code after fixing the .get function, because the get function needs a role id not a role name. You could find the role via the name by writing:
const role = <Guild>.roles.cache.find((r) => r.name === /* The role name */);
Make sure you replaced <Guild> with your guild variable.
Try this code if client.guild is not defined, it could also be because you are using bot instead of client
let role = message.guild.roles.cache.find(role => role.name === "Aiz Basic+");
I'm coding a server-info command for my discord bot, and I want to get the owner username or tag from the actual guild. I found a way to do it in discord js 11, but it's not working anymore under 12th version :
const guild = client.guilds.get(message.guild.id);
message.channel.send(message.guild.member(guild.owner) ? guild.owner.toString() : guild.owner.user.tag);
// if the user is in that guild it will mention him, otherwise it will use .tag
So in discord js 12, client.guilds.get isn't a function, and guild.owner returns null.
message.guild.owner.user.usernameis also returning Cannot read property 'user' of null.
I took a look at the documentation, and message.guild.owner seems to be a real property (https://discord.js.org/#/docs/main/stable/class/Guild?scrollTo=owner). So I don't know why it's returning null.
I'd recommend that you first get the guild and make sure that it's available before trying to modify or access it. Therefore, your bot won't hit any errors. Additionally, as far as I know, guild.owner returns null but there is a way around this. You can get the guild owner ID through guild.ownerID and fetch the member as a guildMember. Here is the code:
const guild = message.guild; // Gets guild from the Message object
if(!guild.available) return; // Stops if unavailable
await message.guild.members.fetch(message.guild.ownerID) // Fetches owner
.then(guildMember => sOwner = guildMember) // sOwner is the owner
message.channel.send(guild.member(sOwner) ? sOwner.toString() : guild.owner.user.tag);
This is how you would get the owner's tag when you have the guild. This also does not rely on the cache, so if your bot restarts or the cache is cleared, it will work regardless.
let ownerTag = undefined;
<client>.users.fetch(<guild>.ownerID).then(user => ownerTag = user.tag);
.fetch() returns a promise, which is why I declared a variable and then assigned the value to it.
Make sure you enable these intents in your discord developer portal so your bot could access your server
After that, you could access your user owner tag.