Python - How do I make a join command - python-3.x

I'm trying to create a ".join" command for my bot but everything I've tried didn't work & I tried a ton of things
Here's something I've tried, I tried it in a few other ways too:
#client.command(pass_context=True)
async def join(ctx):
channel=ctx.message.author.voice.VoiceChannel
await client.join_VoiceChannel(channel)
It gives this error:
discord.ext.commands.errors.CommandInvokeError: Command raised an exception: AttributeError: 'VoiceState' object has no attribute 'VoiceChannel'

join_voice_channel
works for older versions of discord.py
This code block should work:
#client.command(pass_context=True)
async def join(ctx):
message = ctx.message
channel_id = ctx.message.author.voice.channel.id
channel = client.get_channel(channel_id)
await channel.connect()

You use join_voice_channel to make the bot join a voice channel as it says in the Async docs
Try this:
#client.command(pass_context=True)
async def join(ctx):
author=ctx.message.author
await bot.join_voice_channel(author.voice_channel)

Related

Pycord mute command doesn't throw error but doesn't add role

I am using pycord for this so I can use slash commands.
Here is my code:
import discord, os
from dotenv import load_dotenv
from discord.ext import commands
load_dotenv(f'{os.getcwd()}/token.env')
bot = commands.Bot()
token = str(os.getenv('TOKEN'))
#bot.slash_command(description = 'mutes member of choice')
#commands.has_permissions(administrator = True)
async def mute(ctx, member: discord.Member):
guild = ctx.guild
mutedRole = discord.utils.get(guild.roles, name="Muted")
if not mutedRole:
mutedRole = await guild.create_role(name="Muted")
for channel in guild.channels:
await channel.set_permissions(mutedRole, speak=False, send_messages=False, read_message_history=True, read_messages=False)
await member.add_roles(mutedRole)
await ctx.send(f"Muted {member.mention}")
#mute.error
async def permserror(ctx, error):
if isinstance(error, commands.MissingPermissions):
ctx.respond('Sorry! You dont have permission.')
#bot.event
async def on_ready():
print(f'Client ready as {bot.user}')
bot.run(token)
This isn't my full code, but the other commands don't seem necessary for my problem.
Anyway, when I try to use this command, it doesn't throw an error in the console, but the application doesn't respond and it doesn't add the role.
I put a print statement between each line of code, and it seems to stop just before it adds the role.
How can I fix this?
Update: My previous code did not run so I have updated it.
This doesn't actually have to do with the code of the program. All you have to do is move the bot role to the top and it'll work. The error is 403 Forbidden (error code: 50013): Missing Permissions. Also, you have to reinvite the bot and add applications.commands if you haven't already.

Discord.py running an async function on demand

I want to run the following async function at a certain time.
async def test(ctx):
channel = bot.get_channel(730099302130516058)
await channel.send('hello')
I am testing it with
asyncio.run(test(bot.get_context)). But when I run it I get 'NoneType' object has no attribute 'send' And I have tested this and it means channel is equal to none so it cant send the message as channel = "None".
Now when I do the following it works. But of course I have to run the command test
#bot.command()
async def test(ctx):
channel = bot.get_channel(730099302130516058)
await channel.send('hello')
I plan to use schedule to run it at the times I required but will still call the function in a similar way.
Is there a way to call an async function and pass ctx correctly?
Entire Code:
import discord
from discord.ext import commands
import asyncio
TOKEN = "Token Would Be Here"
bot = commands.Bot(command_prefix='+')
async def test(ctx):
channel = bot.get_channel(730099302130516058)
await channel.send('hello')
asyncio.run(test(bot.get_context))
bot.run(TOKEN)
bot.get_channel() is returning None because the bot has not yet connected, meaning it cannot see any channels. You need to add await bot.wait_until_ready(), which will force the bot to wait until it is connected before continuing.
You also don't need to pass ctx as you never use it.
discord.py also already has it's own event loop that you can use. You can add the coroutine to the loop using bot.loop.create_task().
from discord.ext import commands
TOKEN = "Token Would Be Here"
bot = commands.Bot(command_prefix='+')
async def test():
await bot.wait_until_ready()
channel = bot.get_channel(370935329353367568)
await channel.send('hello')
bot.loop.create_task(test())
bot.run(TOKEN)

How can I delete bot message in DM?

I'm making a bot with a command that send a file with all the previously executed commands in DM but I can't find a way to delete bot messages. Is there a way to do it or it's just impossible ?
I've tried to make a clear command for this specific case, I've tried this : https://www.reddit.com/r/Discord_Bots/comments/c1tf6t/dm_message_deletion_scriptbot/
but it didn't work for me.
The reddit code :
#client.command()
async def clear_dm(ctx):
user_dm = (client.get_user(610774599684194307)).dm_channe
messages_to_remove = 1000
async for message in user_dm.history(limit=messages_to_remove):
if message.author.id == client.user.id:
await message.delete()
await asyncio.sleep(0.5)
The bot messages should be deleted but when I run the command I get an exception AttributeError: 'ClientUser' object has no attribute 'dm_channel' the others methodes that I've tried raised similar errors (but I can't show you the code since I've delted it :c)
Users have a User.history attribute that you can use directly.
#client.command()
async def clear_dm(ctx):
messages_to_remove = 1000
async for message in client.get_user(610774599684194307).history(limit=messages_to_remove):
if message.author.id == client.user.id:
await message.delete()
await asyncio.sleep(0.5)

Deleting specific messages that was sent by the bot and sent by the user. Discord.py rewrite

I'm having a lot of trouble with discord.py rewrite and its migration. I looked at the migrating to v1.0 site and it said to put in message.delete() and so I did but I realised that wasn't working so I put in ctx aswell. But that put it to an error. There are two commands with this error at the moment.
I have already tried putting the message into a variable.
#client.command()
async def clear(ctx, amount=100):
message = ctx.message
channel = ctx.message.channel
messages = []
await ctx.channel.purge(limit=int(amount+1))
mymessage = await channel.send('Messages deleted')
await ctx.message.delete(mymessage)
#client.command()
async def verify(ctx, *, arg):
print(ctx.message.channel.id)
print(ctx.message.author)
if ctx.channel.id == 521645091098722305:
role = await ctx.guild.create_role(name=arg)
await ctx.message.author.add_roles(role)
mymessage = await ctx.send('Done! Welcome!')
await ctx.message.delete(mymessage)
await ctx.message.delete(ctx.message)
I expected the output to delete the message. For the clear one it deletes it and then gives it back. for the verify one it just keeps it as the same and shows the error:
raise CommandInvokeError(exc) from exc
discord.ext.commands.errors.CommandInvokeError: Command raised an exception: TypeError: delete() takes 1 positional argument but 2 were given
Also my role giving verify sometimes goes 3 times. I have went into task manager and killed all of the python too but it still did that. Once when I was clearing it said Done! Welcome as well. If you can answer this question as well, I would be pleased! Thank you in advance.
Message.delete doesn't take any arguments. It's a method that you call on the message you want to delete. Change
await ctx.message.delete(mymessage)
await ctx.message.delete(ctx.message)
to
await mymessage.delete()
await ctx.message.delete()
#client.command(pass_context=True)
async def delete(ctx, arg):
arg1 = int(arg) + 1
await client.purge_from(ctx.message.channel, limit=arg1)
!delete 10 - delete the last 10 posts

discord.py not able to delete author messages

I am using Discord.py version 1.0.0. I am trying to write an echo command that, when given a message, will echo the message and delete the command from the chat. Here is an example of my code.
client = Bot(description="Test bot", command_prefix="&", pm_help = False)
#bot.command(pass_context=True)
async def echo(ctx):
await client.send(ctx.message)
await client.delete_message(ctx.message)
The errors I receive tell me that ctx does not have an attribute called "delete_message". I have tried with just delete(). I have looked at others having something of a similar issue, however the solutions did not help me.
Any suggestions would be greatly appreciated.
In discord.py/rewrite (1.0.0), Delete is a method on the message, not on the client. This is the same for every function affecting a message/channel/guild etc.
Instead of doing
await client.delete_message(ctx.message)
try doing
await ctx.message.delete()
If you're on 1.0, you can lose pass_context and client.send should be ctx.send. You can also write the function signature of the command, using Keyword-Only Arguments, so that you only echo the message, ignoring the &echo
from discord.ext.commands import Bot
client = Bot(description="Test bot", command_prefix="&", pm_help = False)
#client.command()
async def echo(ctx, *, msg):
await ctx.send(msg)
await ctx.message.delete()
client.run('token')

Resources