Using an async function in another function - async-await

I'm trying to understand how to use an async function inside another function:
I'm trying to send messages via Telegram whenever something happens during my code.
Telegram logger:
from telethon import TelegramClient, sync
import asyncio
async def msgtelegram(entity, msg,api_id=xxx, api_hash='xx'):
client = TelegramClient('Session', api_id, api_hash)
await client.start()
if not await client.is_user_authorized():
await client.sign_in('xxx')
await client.send_message(entity, msg)
await client.disconnect()
def func():
try:
print('hello!')
except:
await msgtelegram(entity, msg)
Calling await msgtelegram() outside of a function seems to work correctly.
Am I missing something or am I using async wrong?
Thank you!

you could use either asyncio.run() or loop.run_until_complete() so for your example it would be
from telethon import TelegramClient, sync
import asyncio
async def msgtelegram(entity, msg,api_id=xxx, api_hash='xx'):
client = TelegramClient('Session', api_id, api_hash)
await client.start()
if not await client.is_user_authorized():
await client.sign_in('xxx')
await client.send_message(entity, msg)
await client.disconnect()
def func():
try:
print('hello!')
except:
asyncio.run(msgtelegram(entity, msg))

Related

How to creat a slash command in cog

I created a slash command under message cog to clean up messages, but it shows that 'the application is not responding' in discord
Here is my code:
class Message(InitCog):
# clean messages
#app_commands.command(name='clean', description='clean messages')
#app_commands.describe(num='number of message')
#commands.has_permissions(manage_channels=True)
async def clean(self, ctx, *, num: int):
await ctx.channel.purge(limit=num)
await discord.Interaction.response.defer(ephemeral=True)
await discord.Interaction.followup.send(f'deleted {num} messages')
async def setup(client):
await client.add_cog(Message(client))
and main code:
import asyncio
import discord
import os
from discord.ext import commands
client = commands.Bot(command_prefix='?', intents=discord.Intents.all())
async def setup_hook():
for Filename in os.listdir('./cmds'):
if Filename.endswith('.py'):
await client.load_extension(f'cmds.{Filename\[:-3\]}')
#client.event
async def on_ready():
sync = await client.tree.sync()
print(f"bot logged as {client.user}")
print(f'synced {len(sync)} commands')
async def main():
await setup_hook()
await client.start(jdata\['Token'\])
if __name__ == "__main__":
asyncio.run(main())
Already solved , Use interaction.channel.purge instead of ctx.channel.purge
#app_commands.command(name='clean', description='clean messages')
#app_commands.describe(num='number of message')
#commands.has_permissions(manage_channels=True)
async def clean(self, interaction: discord.Interaction, num: int):
try:
await interaction.channel.purge(limit=num)
await interaction.response.defer()
await interaction.followup.send(f'deleted {num} messages')
except Exception as e:
print(e)

Discord.py Bot wont start, getting error "Main.run' was never awaited" but i dont know why I should await it

class Main:
def __init__(self):
self.client = None
async def register_commands(self):
self.client.remove_command("help")
await self.client.add_cog(BlacklistCommand(self.client))
await self.client.add_cog(ClearCommand(self.client))
await self.client.add_cog(DoxCommand(self.client))
await self.client.add_cog(HelpCommand(self.client))
await self.client.add_cog(InfoCommand(self.client))
await self.client.add_cog(IpCommand(self.client))
await self.client.add_cog(SlayerCommand(self.client))
async def register_events(self):
await self.client.add_cog(CommandErrorListener(self.client))
await self.client.add_cog(OnMessageListener(self.client))
await self.client.add_cog(OnReadyListener(self.client))
async def run(self):
token = json.load(open('files/apikeys.json'))['discord']['bot_token']
intents = discord.Intents().all()
self.client = commands.Bot("ยง", intents=intents, case_insensitive=True)
await self.register_commands()
await self.register_events()
self.client.run(token)
Main().run()
I tried running it and it it just gave me an error message "
RuntimeWarning: coroutine 'Main.run' was never awaited
Main().run()
RuntimeWarning: Enable tracemalloc to get the object allocation traceback
Process finished with exit code 0"
but i dont know why I should await it
You should await it because you made the function async
async def run(self):
# ^^^^^ <- it's async, so it must be awaited
If you want to do any async setup, either make an async main or use the built-in setup_hook function.
The migration guide explains how to do both: https://discordpy.readthedocs.io/en/stable/migrating.html?highlight=setup_hook#asyncio-event-loop-changes

Discord.py ghost TEST command

The bot has a "ghost" test command. I do not create it anywhere, yet still it shows up in the slash command menu. If I try to run it I get an error, that the command doesn't exist.
import asyncio
import discord
from discord.ext import commands
class Bot(commands.Bot):
def __init__(self):
intents = discord.Intents.all()
super().__init__(command_prefix="$", intents=intents)
async def setup_hook(self):
await self.tree.sync()
print(f"Synced slash commands for {self.user}.")
async def on_command_error(self, ctx, error):
print(error)
await ctx.reply(error, ephemeral=True)
bot = Bot()
async def main():
async with bot:
await bot.start('Token')
asyncio.run(main())
If I try to create it I get two /test commands
import asyncio
import discord
from discord.ext import commands
class Bot(commands.Bot):
def __init__(self):
intents = discord.Intents.all()
super().__init__(command_prefix="$", intents=intents)
async def setup_hook(self):
await self.tree.sync()
print(f"Synced slash commands for {self.user}.")
async def on_command_error(self, ctx, error):
print(error)
await ctx.reply(error, ephemeral=True)
bot = Bot()
#bot.hybrid_command(name="test", with_app_command=True, description="Testing")
async def test(ctx: commands.Context):
await ctx.defer(ephemeral=True)
await ctx.reply("hi!")
async def main():
await bot.start('Token')
asyncio.run(main())
Where does the first test command come from?
Showing in the menu\Two /test commands

Discord.py echo command

So I am trying to make a discord.py echo/say command, but no response or errors are happening, if you know how to fix this please help me out!
import discord, os, keep_alive, asyncio, datetime, pytz, requests
from discord.ext import tasks, commands
client = commands.Bot(
command_prefix=':',
self_bot=True
)
async def on_ready():
client.remove_command('help')
await client.change_presence(status=discord.Status.online, activity=discord.Game("TEST"))
#client.command()
async def echo(ctx, *,args):
if ctx.message.author.id in [782258096210051102]:
await ctx.send(args)
await ctx.message.delete()
else:
await ctx.send("Bot developers only :<")
keep_alive.keep_alive()
client.run(os.getenv("TOKEN"), bot=False)
It's not working because the ctx.author is None, to fix that enable intents.members
intents = discord.Intents.default()
intents.members = True
client = commands.Bot(..., intents=intents)
Also make sure to enable them in the developer portal
Reference
Uhhhhhh it is better to do something like
#bot.command()
async def echo(ctx,*,arg):
#the star is required
if ctx.authir.id==782258096210051102:
await ctx.send(arg)
else:
await ctx.send("devs only :<")
You can use ' '.join(ctx.message.content.split()[1:]) to join all words after the first space. So something like:
#client.command()
async def echo(ctx, *args):
await ctx.send(' '.join(ctx.message.content.split()[1:]))
To See Where The Problem Is From First Try:
#client.command()
async def echo(ctx, *,args):
await ctx.send(args[0])
await ctx.message.delete()
Ok so actually you have need to do this:
#client.command(name='echo')
async def echo(ctx, *, what_bot_need_to_say: str):
if ctx.message.author.id == 782258096210051102:
await ctx.channel.purge(limit=1) # This delete an message in the channel
await ctx.send(what_bot_need_to_say) # This the echo
else:
await ctx.send("Bot developers only :<")
#bot.command()
async def say(ctx, *, msg):
await ctx.send(msg)
Just copy me it is the simplest and gives the correct format
import discord
from discord.ext import commands
bot = commands.Bot('?')
#bot.command()
async def repeat(ctx,*,repeat:str):
if ctx.author.id == 782258096210051102:
await ctx.send(f"{repeat}")
await ctx.message.delete()
return
else:
await ctx.send("Only devs")
return
#bot.event
async def on_ready():
print("bot online")
bot.run("YOUR_TOKEN_HERE")
try this:
import discord, os, keep_alive, asyncio, datetime, pytz, requests
from discord.ext import tasks, commands
client = commands.Bot(
command_prefix=':',
self_bot=True
)
async def on_ready():
client.remove_command('help')
await client.change_presence(status=discord.Status.online, activity=discord.Game("TEST"))
#client.command()
async def echo(ctx, *,args):
if ctx.author.id in [782258096210051102]:
await ctx.send(args)
# await ctx.message.delete() # i am not sure of delete you can add it if you want
else:
await ctx.send("Bot developers only :<")
keep_alive.keep_alive()
client.run(os.getenv("TOKEN"), bot=False)

"Error 'Self' is not defined" in member.edit

I'm having issues with my code saying
discord.ext.commands.errors.CommandInvokeError: Command raised an exception: TypeError: edit() missing 1 required positional argument: 'self'
when I run the command. Self shouldn't need to be defined, right?
Also, when I do add self I get an issue with ctx.
The code:
import discord
from discord.ext import commands
client = commands.Bot(command_prefix="/")
#client.command(pass_context=True)
async def join(ctx, member=discord.Member):
channel = ctx.author.voice.channel
await channel.connect()
await member.edit(mute=True)
#client.command(pass_context=True)
async def leave(ctx):
await ctx.voice_client.disconnect()
client.run("Token")
I Managed to find the problem and fixed it.
import discord
from discord.ext import commands
client = commands.Bot(command_prefix="/")
#client.command()
async def join(ctx):
channel = ctx.author.voice.channel
await channel.connect()
await ctx.author.edit(mute=True)
#client.command()
async def leave(ctx):
await ctx.voice_client.disconnect()
client.run("Token")
the problem is, you included member on your funcion. If you want it to send, edit, or do something with the message author just do ctx.author and it will be set on the author of the message.

Resources