Discord.py - await allowed only within async function python - python

With the next code:
intents = discord.Intents.all()
bot = commands.Bot(command_prefix='!!')
online=####
#tasks.loop(seconds=1)
async def thatloop():
def sendmsg():
channel = bot.get_channel(online)
await channel.send("Hi")
sendmsg()
#bot.event
async def on_ready():
print("Comienza el scrap.")
try:
thatloop.start()
except RuntimeError:
pass
bot.run('####')
I'm trying to message a discord channel from a function to understand how to fix a bigger issue.
What I'm really looking for is to send a embed from a predefined function INSIDE the loop function (The simplest simile is the code above).
The error is in the title.
I have read everything on this site, but maybe my poor understanding of English is working against me.
I tried to put the function outside the loop but the error persists.

Related

How to delete number of chat in discord by python

I would like to create a bot which can delete number of recently chat and history chat
import discord
import random
class MyClient(discord.Client):
async def on_ready(self):
print('Logged on as {0}!'.format(self.user))
async def on_message(self, message):
channel = message.channel.name
restricted_channels = ["command-bot"]
prefix = "-" # Replace with your prefix
# If the message starts with the prefix
if message.content.startswith(prefix):
if channel in restricted_channels:
command = message.content[len(prefix):]
if command.startswith("clear"):
await message.delete()
I have try this
if command.startswith("clear"):
await message.delete()
But it only delete the chat which have command "clear"
First off, personally, I would change the structure/ layout of your code. This is so that it is easier to read, and easier to change and add commands/ different functions to. This is the way I have my bot setup and how I have seen many other bots setup as well:
import discord
client = commands.Bot(command_prefix='your prefix', intents=discord.Intents.all()) # creates client
#client.event # used commonly for different events such as on_ready, on_command_error, etc...
async def on_ready():
print('your bot is online') # basic on_ready event and print statement so you can see when your bot has gone online
Now that we've gone through that part, let's get onto the purge/ clear command you're trying to make. I have one in my bots which generally looks something like this:
#client.command() # from our client declaration earlier on at the start
#commands.has_permissions(moderate_members=True) # for if you want only certain server members to be able to clear messages. You can delete this if you'd like
async def purge(ctx, amount=2): # ctx is context. This is declared so that it will delete messages in the channel which it is used in. The default amount if none is specified in the command is set to 2 so that it will delete the command call message and the message before it
await ctx.channel.purge(limit=amount) # ctx.channel.purge is used to clear/ delete the amount of messages the user requests to be cleared/ deleted within a specific channel
Hope this helps! If you have any questions or issues just let me know and I'll help the best I can

TypeError: 'async_generator' object is not subscriptable in discord.py

Im trying to make a command for my discord bot that gets the message content from a specific channel without using discord.ext, I have tried putting it inside my async def on_message(message) function and it doesnt want to work. I know discord.ext will be better for this but I still want to what I have been using.
Heres my code:
TOKEN = 'MY_BOTS_TOKEN'
import discord
intents = discord.Intents.all()
client = discord.Client(intents=intents)
#client.event
async def on_message(message):
mychannel = client.get_channel(MYCHANNELID)
content = (mychannel.history(limit=1))[0].content
if message.content.startswith('.content'):
await message.channel.send(content)
client.run(TOKEN)
I tried putting the mychannel = client.get_channel(MYCHANNELID) content = (m7channel.history(limit=1))[0].content into a different function and then calling onto it in message.channel.send(). I wasnt expecting it to work and I guessed correctly.
I also tried putting (await mychannel.history(limit=1))[0].content) inside of message.channel.send() but it returned the same error as the title.

Discord.py: How to send a message without using async and await

How can I create a function (without async) that sends a message to a specific channel every time it (the function) gets executed somewhere in the code?
def sendMsg():
channel = client.getChannel(Channel id)
message.channel.send("example message")
#excecuting the function
sendMsg()
Doesn't do anything
async def on_message():
await message.channel.send("example message")
Only this one works
So my question is if I can modify the code on the top make it work?
If you need to send the message outside of an async context, you need to add the task into the event loop. Note that when you "call" a coroutine, you get the actual coroutine object. "Calling" it doesn't actually run the coroutine, you need to put it in the event loop for it to run.
asyncio.get_event_loop().create_task(<coro>)
# use it like this
asyncio.get_event_loop().create_task(ctx.send('test'))
asyncio.get_event_loop().create_task(message.channel.send("example message"))
Eric's answer is correct. Moreover, in order to get the loop event from discord.py, you can use client.loop to get discord.py's asyncio eventloop
that said, use asyncio.run_coroutine_threadsafe(def,loop) to safely submit task to event_loop
client = discord.Client()
async def send_message_to_specific_channel(message='abc',id=123):
channel = client.get_channel(id)
await channel.send(message)
asyncio.run_coroutine_threadsafe(send_message_to_specific_channel('abc',123),client.loop)
Async is really needed for synchronize the message
If your wanna make it as selfbot response message, do
# Import's here
from discord.ext import commands
bot = commands.Bot(command_prefix='!', help_command=None, self_bot=True)
#bot.event
async def on_message(message):
if message.content.startswith("Hello"):
await message.channel.send(f"Hi #{message.author}")
bot.run('token ofc', bot=False)
Anyways this for selfbot if you wanna do it with bots, delete self_bot=True and bot=False

Unable to send a message to Discord using discord.py

I'm trying to simply create a function that sends a discord message to a specific channel when the bot runs. I want to later call this function in a separate python script.
The code below seems to run fine, and the bot appears online - but it is fails to send the message:
import discord
client = discord.Client()
client.run("ABCDeFGHIjklMNOP.QrSTuV-HIjklMNOP") # the token
#client.event
async def on_ready():
logs_channel = client.get_channel(12345689123456789) # the channel ID
await logs_channel.send("Bot is up and running")
on_ready()
I'm sure I'm missing something basic but I cannot figure out what it is. I've tried a similar function in Node.js and it works fine however, I would prefer the bot to work in python. Discord.py is up to date, python is v3.10.
Any help would be greatly appreciated.
Client.run is a blocking call, meaning that events registered after you call it won't actually be registered. Try calling Client.run after you register the event, as in:
import discord
client = discord.Client()
#client.event
async def on_ready():
logs_channel = client.get_channel(12345689123456789) # the channel ID
await logs_channel.send("Bot is up and running")
client.run("ABCDeFGHIjklMNOP.QrSTuV-HIjklMNOP") # the token
You also probably do not want to be manually calling an event handler. If you want to send a message by calling a function, you probably want to consider writing a separate function to the event handler.

Is it possible to send messages outside a function?

I'm writing a discord.py script and I wanted to make alerts for my original code but I'm not sure how to write it properly:
#client.event
async def on_ready():
print('Client is ready.')
channel = client.get_channel(00000000000000)
await channel.send(f'example')
this works fine but when I write this outside it doesn't want to work. Is there any way writing this section?
channel = client.get_channel(000000000000000)
await channel.send(f'message')
Everything has to be async so it has to be in a function
async def sendmsg():
channel = client.get_channel(000000000000000)
await channel.send(f'message')
Then you can do await sendmsg() in the on_ready or another async function.
The code outside the functions is getting called when you start the file. So as the bot isn't ready there, you can't say it to get a channel and send a message to it.
So you have to put the channel = ... await channel.send in another function, you call when a specific thing happens.
Also as FluxedScript said, you have to put it into an async function, because it has an await in it and then you have to call it with await FUNCTION_NAME.

Categories

Resources