So i am trying to make a /broadcast command for my discord.py bot that will send a specific inserted message to every server it is into (only the bot owner can use it). I am using it to send updates and infos on error and so on. BUT... it stops after a certain amount of servers (40~) without any error, as it would have done his job and that would be all. Code keep running, /broadcast stops. I should even added a way to skip servers where it does not have permissions to write...
import discord
from discord.ext import commands
import asyncio # Import asyncio for handling asynchronous tasks
# Define the intents for the bot
intents = discord.Intents.default()
intents.messages = True
intents.guilds = True
# Initialize the bot with the specified command prefix and intents
bot = commands.Bot(command_prefix="!", intents=intents)
# Define the broadcast command with owner-only access
@commands.is_owner()
@bot.hybrid_command(name="broadcast", description="Broadcast a message to specific channels")
async def broadcast(ctx, *, input_message: str):
# Defer the response if the context is an interaction (for slash commands)
if isinstance(ctx, discord.Interaction):
await ctx.response.defer(ephemeral=True)
# Initialize the message count
message_count = 0
# Define the list of allowed channel names
allowed_channel_names = ['general-chat', 'spam-chat', 'chat-general', 'talk-general', 'chat-spam', 'talk-spam', 'chat-generale', 'bot-spam', 'bot-chat', 'bot-talk', 'bot-general', 'bot-generale','bot-test', 'bot-test-spam', 'bot-test-chat', 'bot-test-talk','spam-bot', 'spam-chat-general', 'spam-chat-talk', 'spam-chat-general-test','spam-shapes','shapes-spam', 'shapes-chat', 'shapes-talk', 'shapes-general', 'shapes-generale']
# Iterate over all guilds the bot is a part of
for guild in bot.guilds:
# Iterate over all text channels in the guild
for channel in guild.text_channels:
# Check if the channel is in the allowed list and the bot has permission to send messages
if channel.name in allowed_channel_names and channel.permissions_for(guild.me).send_messages:
try:
# Send the input message to the channel
await channel.send(input_message)
message_count += 1
print(f"Message sent to: {channel.name} in {guild.name} (Count: {message_count})")
except discord.HTTPException as e:
# Handle rate limiting by waiting and retrying
if e.status == 429:
print("Rate limited. Waiting to retry...")
await asyncio.sleep(e.retry_after) # Wait for rate limit to expire before retrying
await channel.send(input_message) # Retry sending the message
else:
print(f"An HTTPException occurred: {e}")
except Exception as e:
# Handle any other exceptions that may occur
print(f"An error occurred when sending to {channel.name} in {guild.name}: {e}")
continue # Ensures the bot continues with the next channel/server
# Print the total number of messages sent after the broadcast is completed
print(f"Broadcast completed. Total messages sent: {message_count}")
# Define the on_ready event to indicate the bot is ready and sync slash commands
@bot.event
async def on_ready():
await bot.tree.sync() # Syncs the command tree to enable slash commands
print(f"Logged in as {bot.user.name}")
# Other parts of your code...
# Directly assign the bot token
token = "TOKEN"
# Ensure the token is not empty
if token == "":
raise Exception("Please add your token to the code")
# Run the bot with exception handling
try:
bot.run(token)
except discord.HTTPException as e:
if e.status == 429:
print("The Discord servers denied the connection for making too many requests.")
else:
print(f"An HTTPException occurred: {e}")
except Exception as e:
print(f"An error occurred: {e}")