discord.ext problems with sending in right channel and setting status - python

I'm using discord.py, and from there the discord.ext module. I have a quite long selenium code running in a while True loop. Here's part of it:
#bot.command()
async def start(ctx):
driver.install_addon(r'some_extension.xpi')
channel = bot.get_channel(791352165393498203)
user = bot.get_user(257428782233812993)
while True:
await bot.change_presence(status=Status.online)
driver.get('some_link')
driver.maximize_window()
time.sleep(5)
try:
driver.find_element_by_xpath('//*[#id="pageSize"]').click()
except NoSuchElementException:
await ctx.channel.send(f" We had an Exception, please go check")
time.sleep(60)
driver.refresh()
time.sleep(5)
driver.find_element_by_xpath('//*[#id="pageSize"]').click()
time.sleep(1)
await ctx.channel.send(f"Problem solved")
Most of this code works fine, but there are two main problems, and I don't get an exception.
Firstly, the await ctx.channel.send(f"We had an Exception, please go check") should be sent in the channel I stated above, but it
doesn't. pycharm says that the channel variable is never used,
which shouldn't be the case.
Secondly, the await bot.change_presence(status=Status.online) doesn't keep the bot
permanently displayed as online.

Just use channel.send() without ctx, ctx is a bunch of info about used command (author, channel, etc.).
You don't need to change status to online, it's automatically setting when you launch the bot.
Oh, and i recommend to use asyncio.sleep() instead of time.sleep() because, when u use time.sleep() the bot will stop working in this time, and will not responding to any command/event.

Related

Automatically sending gifs in discord

I added a bot to Discord and added various functions in Python, but just as some work without any problems, the automatic sending of gifs at a specific time and on a specific channel doesn't work. After configuring everything and starting the bot, nothing happens, no error is displayed, and the console is also silent. What could be wrong? Below I'm sharing a part of the code responsible for this function, thank you in advance for your response.
import asyncio
import datetime
import discord
from discord.ext import commands
client = commands.Bot(command_prefix='.', intents=discord.Intents.all())
async def send_gif(channel):
print(f"Sending gif to channel {channel}")
gif_id = "Here's the gif id"
gif_url = f"Here's url"
await channel.send(gif_url)
#client.event
async def on_ready():
channel_id = "Here's the text channel ID"
channel = client.get_channel(channel_id)
await client.wait_until_ready()
while not client.is_closed():
now = datetime.datetime.now()
if now.hour == sample hour and now.minute == sample minutes:
await send_gif(channel)
await asyncio.sleep(60)
I would like the bot to send specific gifs at a specified time and on a specified channel, but I'm out of ideas. I tried using chatGPT, but it was unable to help. I also checked several times to make sure I was entering the correct gif IDs, channel IDs, and URLs, but it didn't help.
Check that you didn't miss any symbols on on_ready event.
Maybe the error is in
...
if now.hour == sample_hour and now.minute == sample_minutes:
...
Also, check that you defined sample_hour and sample_minutes variables before referring them in the code.
If still doesn't work try using the ext.tasks.loop decorator, if you don't know how to, take a look to the documentation
If it's not the thing causing the error, comment in this message and I will try to edit this message as fast as possible for solving doubts.

Whats wrong in my code my code for scheduled messages on discord.py on replit

so I've been trying to make my discord bot send a message every day at 12:30 UCT but i cant seem to get my code to work I'm not sure if its not working because of incorrect code or because its on replit or whatever else the issue could be as i get no errors from this it just send the message once it loads online and that's all.
import datetime, asyncio
bot = commands.Bot(command_prefix="+")
Async def on_Ready():
await schedule_daily_message()
async def schedule_daily_message():
now = datetime.datetime.now()
then = now+datetime.timedelta(days=1)
then.replace(hour=12, minute=30)
wait_time = (then-now).total_seconds()
await asyncio.sleep(wait_time)
channel = bot.get_channel(Channel_id)
await channel.send("Enemies Spawned!")
client.run(os.getenv('TOKEN'))
await asyncio.sleep is non blocking. Your script will execute beyond that statement. You will need to use time.sleep, which that will block all execution of code until the timer has run out.
See here for a more in depth explanation and how to use this in functions:
asyncio.sleep() vs time.sleep()
A way to implement a function that posts a message to a channel after a delay could look like this:
async def send_after_delay(d, c, m):
time.sleep(d)
await c.send(m)
Calling this function asynchronously allows you to continue with code execution beyond it, while still waiting past the calling of the function to send the message.

Instantly delete discord messages using python discord.py

Hello I'm trying to make this code unsend my messages without having the permission or role to delete/manage messages in a server
I have tried using "delete_after" argument but most of the times messages doesn't get deleted and I'm not sure why
This is my code:
#client.command(pass_context=True)
async def hello(ctx):
while True:
time.sleep(int(timer))
await ctx.send("HELLO", delete_after=1)
The deletions can fail sometimes if you hit ratelimits, the message falls out of cache, etc.
See the docs. If the deletion fails, it will be silently ignored.
If you want to be completely sure they are deleted, you need to save the messages and delete them manually. If this fails, then you will get an error rather than nothing.
while True:
await asyncio.sleep(int(timer-DELETE_AFTER_DURATION))
message = await ctx.send("HELLO")
await asyncio.sleep(DELETE_AFTER_DURATION)
await message.delete()
Sidenote: use asyncio.sleep, which won't block the rest of your code, rather than time.sleep, anywhere in a coroutine.

Better alternative to time.sleep() for discord.py?

I am a new developer trying to learn by making a Discord bot with python. For a part of my bot, I want it to reply to a message, wait 10 seconds and then delete both the reply and the referenced message. Instinctively, I used time.sleep() for the delay, however, this puts my entire bot on hold for 10 seconds, so I tried looking for an alternative with no luck. Any helpful code with explanations for the changes is very much appreciated!
Current code:
# Delete the referred to message
#client.event
async def on_reaction_add(reaction, user):
# <A bunch of other irrelevant code>
if successCounter == 1:
await reaction.message.reply("Image successfully added!")
time.sleep(10)
await reaction.message.delete()
# Delete the "Image successfully added!" message
#client.event
async def on_message(message):
if message.author.id == botID:
if message.reference is not None:
time.sleep(10)
await message.delete()
Thanks heaps in advance!
asyncio has a function called sleep() too, which does work asynchronously. So just use await asyncio.sleep(10) instead of time.sleep()

Discord.py || How to loop a part of Program infinite times without crashing it eventually?

I am Trying to Make a 24/7 Streaming Discord Bot using while(True): Infinite Loop,
But I think that the while(True): will get crashed by the OS (Using Heroku for Hosting) or Some kind of threads problem
#commands.command(name='play',aliases=["p"])
async def _play(self, ctx: commands.Context):
i = 0
while(True): #Infinite While Loop
search = URL[i] #URL is the List of Musics I What to Stream 24/7
if not ctx.voice_state.voice:
await ctx.invoke(self._join) #joins the voice channel if not in voice channel previously
async with ctx.typing():
try:
source = await YTDLSource.create_source(ctx, search, loop=self.bot.loop)
#Sets the Status of the Bot to What Music it is Playing Currently
await self.bot.change_presence(activity=discord.Activity(type=discord.ActivityType.listening, name=f"{source.title}"))
except YTDLError as e:
await ctx.send('An error occurred while processing this request: {}'.format(str(e)))
else:
song = Song(source)
await ctx.voice_state.songs.put(song) #Enqueue the Song
i = (i + 1) % len(URL) # Updates the Index of URL
await asyncio.sleep(source.DURATION) #Gets the Lenght of the Music in int and Sleeps
I thought of using Asyncio Event Loops but Can't Figure it Out How to Use it Because my Function Has Parameters/Arguments like context (ctx)
I have Also thought of Cleaning the Memory stack after each songs play... But is it possible ??? If yes can we use it to fix my problem
So Is there anyway to Loop The above Mentioned Block or Code Infinitely without crashing it eventually
Thanks in advance !!!
I have a Out of Topic Query... Can we Use the ability of Context (ctx) without passing it as a Argument.
If we Can then I might be able to use asyncio_event_loop, I suppose

Categories