Reputation: 386
I am about to make a Global Chat bot and it works pretty good but since it is in 70 Servers, he really struggles with sending the Messages. At the moment my code to send the messages looks like this:
async def sendallchannel(self, embed):
for channel in fetchedchannel:
try:
await channel.send(embed = embed)
except:
pass
and as I just said, it take about 1 Minute till the Message is send to every Server. Is there a way to send the Messages faster?
the variable fetchedchannel is a list of every channel already fetched, so the Bot don't need to fetch every Channel one by one when he wants to send a Message
Upvotes: 2
Views: 1542
Reputation: 370
I think this is the faster:
def _send_in_all_channels(ctx, embed): # outside cog
channels = ctx.guild.text_channels # type: list[TextChannel]
coroutines = (channel.send(embed=embed) for channel in channels)
# types.Genetrator[typing.Awaitable[discord.Message], None, None]
return asyncio.gather(*coroutines) # type: typing.Awaitable
# usage in cog
@commands.command('big-send')
async def big_send(self, ctx, message: str):
await _send_in_all_channels(ctx, discord.Embed(discerption=message))
await ctx.send('done')
Upvotes: 0
Reputation: 4094
As I know, this is the fastest way:
@bot.command()
async def sendToAllChannels(ctx, *message):
message = ' '.join(message)
for guild in bot.guilds:
for channel in guild.channels:
await channel.send(message)
Notice that this way you are using a nested
for
loop, that obviously takes a lot of time, in particular when the outer loop (the one iterating over bot.guilds
) is executed many times (you said 70
, right?)
Since you only want to send messages to TextChannel
s, you can add this check:
if str(channel.type) == 'text':
EDIT: Since you already have a list of all the channels (fetchedchannel
), assuming this list contains all the channels the bot
can see, I would create a new list this way...
fetchedTextChannels = [channel for channel in fetchedchannel if str(channel.type) == 'text']
...in order to avoid the try
/except
block, once you know all the channel are of type 'text'
.
Then, in order to make the messages not to wait each other, you should see the solution by @Loic that suggests you to use async
hronous coroutines, and will make everything much faster.
Upvotes: 0
Reputation: 11943
This should be much faster as all coroutines will be ran concurrently :
async def sendallchannel(self, embed):
coroutines = [channel.send(embed=embed) for channel in fetchedchannel]
await asyncio.gather(*coroutines)
Upvotes: 4