Bot won't leave voice channel when left alone - python-3.x

I have a personal music bot that plays music for me and friends, I only have a play and leave commands which both work perfectly, but I was wondering if a little upgrade to the bot automatically leaving voice channel when left in it alone was possible. After some reading in documentation, I thought I got it but this piece of my code simply doesn't work, it's almost like python is ignoring it for some reason so I guess I am missing something here...
so I was wondering if there is a reason why my code:
#client.event
async def on_voice_state_update(member):
voice_state = member.guild.voice_client
if len(voice_state.channel.members) == 1:
await voice_state.disconnect()
won't work, I don't get any error messages and literally nothing happens. Is it all as it should be here?

You are missing some arguments for this event. Simply add before and after and you should be fine.
The full event could be:
#client.event
async def on_voice_state_update(member, before, after):
voice_state = member.guild.voice_client
if voice_state is not None and len(voice_state.channel.members) == 1:
# If the bot is connected to a channel and the bot is the only one in the channel
await voice_state.disconnect() # Disconnect the bot from the channel
You can see more in the docs here:
on_voice_state_update

Related

How can I save a Message in Discord with Python, in a simple variable

Hello Stackoverflow Community,
I wanted to write a Discord-Bot in Python, which should solve simple Mathquestions, like: "Whats 55+40?". The Questions are asked from another bot and the structure of the Question is everytime the same. I wrote a Calculator and it works and i just need the input from a private message(not a server). I do not need to show any code, because I dont have some and I need to start at the described situation to save the messages in a variable, so my Question is:
How can I import private messages from Discord, to save them in a normal variable, like x?
I use Sublime Text
Thanks for answers!
Looking at the comments of the question it is clear that you don't have any code for a bot yet. Look at this quickstart guide to set up a bot. Once set up, all messages typed to the bot (also DM messages) will trigger the on_message event. You can then save the contents of the message into a variable like so
#client.event
async def on_message(message):
messageContent = message.content
i assume what you mean is waiting for a user to reply to a certain message from the bot, you can get your bot to private message someone by doing something like this:
user = ctx.author
await user.send("Hello, world!")
now, for your bot waiting for a reply for your user, in your code, you will need a check just to make sure only the bot is waiting for a message from the specific person (even in dms) by creating a check function:
def check(m):
return m.author.id == ctx.author.id
then after using user.send to send a message, or an embed, add
message = await bot.wait_for('message', check=check, timeout=120)
which means the bot waits until the user sends their answer (waits 120 seconds in this example)
then, to get the content of the message you just want to do make a variable called content or answer and set it to message.content ( content = message.content )

Playing audio files with discord.py

I've recently gotten back into coding and Python and wanted to check out how to make a discord bot. I've managed to send messages and do basic things, but now i can't figure out how to make it play audio in a voice channel.
I can get it to join and leave at will, but as soon as I try to play music, it's just silent. The audio file is already downloaded and it's in the same folder as my program. I do not get any errors, all i know is there is something wrong with the bot. The audio file is not just silence, I have checked. I do not know what is wrong.
What should happen is when i call for the bot and it joins my VC, it should start playing the song.
My code:
#client.command(aliases=['jvc'])
async def joinvc(ctx):
voice_channel = ctx.message.author.voice.channel
voice_client = discord.utils.get(client.voice_clients, guild=ctx.guild)
if voice_client:
if not voice_client.is_connected():
await voice_channel.connect()
voice_client.play(discord.FFmpegPCMAudio(executable='C:\\FFmpeg\\bin\\ffmpeg.exe', source='file.mp3'))
else:
await voice_channel.connect()
voice_client = discord.utils.get(client.voice_clients, guild=ctx.guild)
voice_client.play(discord.FFmpegPCMAudio(executable='C:\\FFmpeg\\bin\\ffmpeg.exe', source='file.mp3'))
Sorry if the code isn't great, but it was the only way I could think of without getting errors. Also I apologize if I forgot anything important or did something wrong, this is my first time using StackOverflow.
Remember to add ffmpeg to path
#client.command()
async def thisisnotacommand(ctx):
channel = ctx.author.voice.channel
vc = await channel.connect()
await ctx.send('Started playing: something')
vc.play(discord.FFmpegPCMAudio('file.mp3'), after=lambda e: print('done', e))
If you don't know how to add ffmpeg to path feel free to msg me Special unit#5323

How to send a welcome message in server using discord.py in a server

I would like my bot to send a msg when someone joins the server (also mention them)
#client.event
async def on_member_join(member):
print('welcome!'f'{member}')
the only thing i want to change is this should be displayed in the general channel (its printing it in the terminal now) and that instead of only displaying the person's name i want it to mention them.
Thank you for your help!
to send a message to a channel you need to get the channel and then send the message to there, you can get the channel using get_channel
client.get_channel(1234567890)# change to your channel id
or using discord.utils.get incase you want to use name instead
discord.utils.get(member.guild.channels, name="welcome")
and for mention, discord.py has provided us with member.mention
await channel.send(member.mention)
and combining both things we can make this
#client.event
async def on_member_join(member):
channel = client.get_channel(1234567890) # change to your channel id
await channel.send(f"Welcome {member.mention}!")
print(f'{member.name} joined the server')

Input Messages in Discord.py

I'm trying to find a way to program my bot to clear a specific amount of messages in a channel. However, I do not know how to get my bot to run it's code based on the user's input data. For example, let's say I'm a user who wants to clear a specific amount of messages, like let's say 15 messages. I want my bot to then clear 15 messages exactly, no more, no less. How do I do that?
if message.content == "{clear":
await message.channel.send("Okay")
await message.channel.send("How many messages should I clear my dear sir?")
This is legit all I got lmao. I'm sorry that I'm such a disappointment to this community ;(
Using a on_message event, you'd have to use the startswith mehtod and create a amount variable which takes your message content without {clear as a value:
if message.content.startswith("{clear"):
amount = int(message.content[7:])
await message.channel.purge(limit=amount+1)
However, I don't recommend using on_message events to create commands. You could use the commands framework of discord.py. It will be much easier for you to create commands.
A quick example:
from discord.ext import commands
bot = commands.Bot(command_prefix='{')
#bot.event
async def on_ready():
print("Bot's ready to go")
#bot.command(name="clear")
async def clear(ctx, amount: int):
await ctx.channel.purge(limit=amount+1)
bot.run("Your token")
ctx will allow you to access the message author, channel, guild, ... and will allow you to call methods such as send, ...

Discord Python: How to add cooldown command under an event

I have looked at other posts in regards to how to make a cooldown command. One answer did exactly what I wanted, but that was only because I did exactly what they did. Now I want to officially implement the command into my Discord bot. I noticed that the cooldown command that I tested only worked under #client.command rather than #client.event (client is the object). I have all of my commands listed under the event thing, so I need help on how to add the cooldown command without having to rewrite a lot of things. This is what I have so far regarding the cooldown command.
from discord.ext.commands import Bot
from discord.ext import commands
client = Bot(command_prefix="?")
#client.event
#command.cooldown(5, 30, commands.BucketType.user)
async def on_message(message):
if message.content.upper().startswith("?HELLO"):
msg = 'Hello {0.author.mention} :banana:'.format(message)
await client.send_message(message.channel, msg)
#on_message.error
async def on_message_error(self, error, ctx):
if isinstance(error, commands.CommandOnCooldown):
msg = ':exclamation: This command is on cooldown, please try again in {:.2f}s :exclamation:'.format(error.retry_after)
await self.send_message(ctx.message.channel, msg)
I'm just using one command as an example to show what kind of format I have. I get the error with the #on_message.error (it was a trial an error thing, so I didn't expect it to work). I want to set a cooldown for 30 seconds after 5 consecutive attempts of the same command as well as an error message for the bot to say in response with the timer. I don't really want to have to rewrite the whole thing just for one command to work considering how far I've come to make this bot :/
You should add:
#commands.cooldown(1, 30, commands.BucketType.user)
This will add a ratelimit of 1 use per 30 seconds per user.
You can change the BucketType to default, channel or server to create a global, channel or server ratelimit instead, but you can only have 1 cooldown on a command.
This will also cause a CommandOnCooldown exception in on_command_error

Resources