discord.py get webhooks of channel - discord

I'm trying to make a webhook so if anyone says 'ez' it deletes it and sends a message with the webhook with a random message. Originally what I was doing was
if "ez" in message.content:
webhook = await message.create_webhook(name=ctx.author.name)
await webhook.send(ezmessages[random.randint(0, len(ezmessages))-1], username=message.author.name, avatar_url=message.author.avatar_url)
await message.delete()
await webhook.delete()
but the problem is this gets rate limited if webhooks are created and deleted too quickly. So instead what I want to do is check if the bot already has a webhook for the text channel, and if there is one use that but if not use a different one. I thought this would work:
for webhook in message.channel.webhooks:
await webhook.send(ezmessages[random.randint(0, len(ezmessages))-1], username=message.author.name, avatar_url=message.author.avatar_url)
but I get the error
TypeError: 'method' object is not iterable
Even though it should return a list
Anyone know how to correctly iterate over this?

TextChannel.webhooks it's not an attribute, its a function and a coroutine, so you need to call it and await it
webhooks = await message.channel.webhooks()
for webhook in webhooks:
...
docs

Related

Discord API - Get a list of all the servers a bot is part of

I created a Discord bot that, once invited to a guild, is able to make API calls such as
GET/guilds/{guild.id}/members (https://discord.com/developers/docs/resources/guild#list-guild-members)
But how I do get the guild.id beforehand? Is it possible to make an API call to get a list of all the servers a bot is part of?
The client you create will have a guilds attribute you can use to access the servers it's in. This will be in the form of a GuildManager object which has a fetch() method to get a collection of guild objects.
Here is an example that gets all of a bot's guilds and prints their ids:
await bot.guilds.fetch()
.then(guilds => {
guilds.forEach(guild => {
console.log(guild.id);
});
});

How to get permissions in discord js when we do direct message

I am trying to get a list of the permission that the user has in Discord. If it sends the message in the channel, it’s fine as we can use message.member.hasPermission, etc.
But what if the message is DM? I want my users to send a DM to the bot and the bot be able to check and see if the user has certain permissions.
I cannot find anything anywhere. I keep getting redirected to message.member, or message.guild which both are null when it’s in DM.
In DM no one has permissions. All you have is the permission to see messages and send messages which aren’t shown visually, or to bots. To make sure that it isn’t DM, just return if the channel type is dm, or guild is null.
if(!message.guild) return;
//before checking "perms"
If you want the permissions for a certain guild if the message is from DM, use this code
if(message.channel.type === 'dm') {
let guild = await client.guilds.fetch('THE ID OF THE GUILD YOU WANT TO SEE THE USER’S PERMS IN')
let member = await guild.members.fetch(message.author.id);
//you can now access member.permissions
}
Keep in mind await must be in an async callback.
You did not provide any code so I cannot give any more code than this.
You can fetch the member with the guild's context.
Fetching is recommended, as Guild#member() relies on cache and is also deprecated.
Member#hasPermission() will be deprecated as well, using MemberRoleManager#has() is recommended
The following example uses async/await, ensure you're inside an async function
// Inside async function
const guild = await client.guilds.fetch('guild-id');
const member = await guild.members.fetch(message.author.id);
const hasThisPermission = member.roles.cache.has('permission');

I want a discord bot send a dm to somebody by their id

if (message.content === "!test"){
client.users.cache.get('id').send('message');
console.log("message sent")
}
This method doesn't work and I wasn't able to find any other methods that worked
Is there a spelling mistake or this method is outdated?
I've actually encountered this error myself once. There are two problems you might be facing here:
The user isn't cached by discord.js yet
There isn't a DMChannel open for that user yet
To solve the first one, you have to fetch the user before doing anything with it. Remember this is a Promise, so you'll have to either await for it to complete or use .then(...).
const user = await client.users.fetch('id')
Once you've fetched your user by their ID, you can then create a DMChannel which, again, returns a promise.
const dmChannel = await user.createDM()
You can then use your channel like you normally would
dmChannel.send('Hello!')
Try to create a variable like this:
var user = client.users.cache.find(user => user.id === 'USER-ID')
And then do this:
user.send('your message')

how to send a message to every channel in every guild?

similar to this question however I want to be able to send it to every channel it has access to!
inside the on message event after I verify myself by ID and the issued command I was using this code:
const listedChannels = [];
msg.guild.channels.forEach(channel => {
//get all channels
client.channels.get(channel.id).send("you like bred? (message) ");
//send a message to every channel in this guild
});
however I get the error that .send is not a function...
I have been told to use .send after getting the ID of the channels
If you are looping through all of the channels, you simpily need to send your content to the channel, which you've already gotten from msg.guild.channels.forEach(channel => {//code}).
Replace what you have inside the .forEach block with;
channel.send("You like bred? (message)");
Although this will send You like bred? (message)
If you're trying to get a response back, perhaps look at this answer that explains collecting responses via reactions to a discord message.
The following explanation pertains only to v11 (stable).
Client.channels is a Collection of Channels your bot is watching. You can only send messages to text channels, and this Collection will include DM channels as well. For this reason, we can use Collection.filter() to retrieve a new Collection of only text channels within a guild. Finally, you can iterate over the channels and call TextChannel.send() on each. Because you're dealing with Promises, I'd recommend a Promise.all()/Collection.map() combination (see hyperlinked documentation).
For example...
// assuming "client" is your Discord Bot
const channels = client.channels.filter(c => c.guild && c.type === 'text');
Promise.all(channels.map(c => c.send('Hello, world!')))
.then(msgs => console.log(`${msgs.length} successfully sent.`))
.catch(console.error);
You can use client.channels for this. Check if channel type is guild text channel and then try send a message.
client.channels.forEach(channel => {
if(channel.type === 'text') channel.send('MSG').catch(console.error)
})

How do I send message to different channel at the same time in discord.js?

My goal is to send a message to a channel that have the name global-chat.
I tried:
const Discord = require("discord.js")
const client = new Discord.Client();
client.on("message", async(msg) => {
if(msg.channel.name !== "global-chat")return;
let message = msg.content
await client.channels.find("name", "global-chat").send(message)
})
but when I send message in the global-chat channel in one server, it won't send to global-chat on other servers. Can anyone help me fix this?
If I understand your question correctly, you want to send a message to the channel with the same name in all other guilds.
This line will simultaneously relay the message to all of the channels the bot is watching named global-chat. Here's how it works...
Promise.all() executes Promises in a parallel manner.
Client.channels is a Collection of channels the bot is watching. Using Collection.filter(), you can form a new Collection with just the channels named global-chat.
Collection.map() returns an array of the values returned by the function provided for each value in the Collection. In this case, it returns an array of Promises for Promise.all() to use.
await Promise.all(client.channels.filter(c => c.name === 'global-chat').map(c => c.send(msg.content)))
If you use discord.js v12, you'll need to replace client.channels.filter by client.channels.cache.filter.

Resources