Discord bot disconnects before finishing music - discord.py

I'm using DiscordUtils for this exact bot. The music plays somewhere around halfway (every song) and stops with the bot displaying information that there is no song playing. Here is my code (no errors show up).
I cannot seem to find any information regarding this that contains information regarding DiscordUtils. I only get results for YouTube-DL and sadly it works differently. Is there any exact solution to this problem, is this an FFMPEG error?
import discord
from discord.ext import commands
from discord.ext.commands import has_permissions
from discord import Client, Intents, Embed
from discord.ext.commands.core import command
from discord_slash import SlashCommand, SlashContext
from discord_slash.utils.manage_commands import create_choice, create_option
import DiscordUtils
import ffmpeg
music = DiscordUtils.Music()
activity = discord.Game(name="around. Use /help")
client = commands.Bot(command_prefix='?', activity=activity)
slash = SlashCommand(client, sync_commands=True)
#client.command()
async def join(ctx):
voicetrue = ctx.author.voice
if voicetrue is None:
return await ctx.send('You are not currently in a voice channel. :exclamation:')
await ctx.author.voice.channel.connect()
await ctx.send('Joined the voice chat you are in. :white_check_mark:')
#client.command()
async def leave(ctx):
voicetrue = ctx.author.voice
mevoicetrue = ctx.guild.me.voice
if voicetrue is None:
return await ctx.send('You are not currently in the same voice channel as I am.')
if mevoicetrue is None:
return await ctx.send('Im not currently in any voice channel!')
await ctx.voice_client.disconnect()
await ctx.send('I have disconnected from the voice channel.')
#client.command()
async def play(ctx, *, url):
player = music.get_player(guild_id=ctx.guild.id)
if not player:
player = music.create_player(ctx, ffmpeg_error_bettercix=True)
if not ctx.voice_client.is_playing():
await player.queue(url, search=True)
song = await player.play()
await ctx.send(f'Playing **{song.name}** :notes:')
else:
song = await player.queue(url, search=True)
await ctx.send(f'Ive added **{song.name}** to the queue!')
#client.command()
async def queue(ctx):
player = music.get_player(guild_id=ctx.guild.id)
await ctx.send(f"The music queue currently is: **{', '.join([song.name for song in player.current_queue()])}**")
#client.command()
async def pause(ctx):
player = music.get_player(guild_id=ctx.guild.id)
song = await player.pause()
await ctx.send(f'Paused **{song.name}** :pause_button:')
#client.command()
async def resume(ctx):
player = music.get_player(guild_id=ctx.guild.id)
song = await player.resume()
await ctx.send(f'Resumed **{song.name}** :arrow_forward:')
#client.command()
async def loop(ctx):
player = music.get_player(guild_id=ctx.guild.id)
song = await player.toggle_song_loop()
if song.is_looping:
return await ctx.send(f'{song.name} will now start looping. :repeat:')
else:
return await ctx.send(f'{song.name} will no longer loop. :no_entry:')
#client.command()
async def nowplaying(ctx):
player = music.get_player(guild_id=ctx.guild.id)
song = player.now_playing()
if song.name is None:
await ctx.send(song.name + ' is currently playing.')
#client.command()
async def remove(ctx, index):
player = music.get_player(guild_id=ctx.guild.id)
song = await player.remove_from_queue
await ctx.send(f'Removed {song.name} from the song queue!')
#slash.slash(
name="hello",
description="Hello there!",
guild_ids=[822512275331219517, 708384142978711582, 747869167889285180]
)
async def _hello(ctx:SlashContext):
await ctx.send("Hi! test command")
#slash.slash(
name="help",
description="Recieve help using Anix",
guild_ids=[822512275331219517, 708384142978711582, 747869167889285180]
)
async def _help(ctx:SlashContext):
embed=discord.Embed(title="Commands to get you going", description="", color=0xff131a)
embed.set_author(name="Anix Help")
embed.add_field(name="?play", value="use this command whilst in a voice channel to start music", inline=False)
embed.add_field(name="?join", value="make Anix join your voice channel", inline=False)
embed.add_field(name="?leave", value="make Anix leave your voice channel", inline=False)
embed.add_field(name="?queue", value="check the music queue", inline=False)
embed.add_field(name="?pause", value="pauses the current song that's playing", inline=False)
embed.add_field(name="?resume", value="resumes a paused song", inline=False)
embed.add_field(name="?loop", value="loops the current song (type again to stop loop)", inline=False)
embed.add_field(name="?nowplaying", value="check the song that's currently playing", inline=True)
embed.add_field(name="?remove", value="removes the currently playing song from the queue", inline=True)
await ctx.send(embeds=[embed])
client.run('token')

By removing import ffmpeg the disconnecting problem no longer occurs. All of the commands work with no problems whatsoever.

Related

How do i remove a command message in discord.py

I am trying to delete the command message (the one sent by the user not by bot)
Ive tried it like this.
#bot.event
async def on_message(message):
if message.author == bot.user:
return
if message.content.startswith("-"):
wait(5)
await message.delete()
and this
#bot.command()
async def creator(ctx, message):
await ctx.send(f"Example text")
wait(5)
await message.delete()
but none of them work. If you know why please post a solution. Thanks!
In the first code :
import time
#bot.event
async def on_message(message):
if message.author.bot : return
if message.content.startswith("-"):
time.sleep(5)
await message.delete()
Second Code
import time
#bot.command()
async def creator(ctx):
await ctx.send("Example text")
time.sleep(5)
await ctx.message.delete()
If you are using the both of on_message and commands in your bot,
You may want to add this in the end of on_message Event So your bot will handle the on_message event, Then it goes to process commands.
Without it the bot commands wont work .
await bot.process_commands(message)
Eg :
#bot.event
async def on_message(message) :
await message.channel.send("Example")
await bot.process_commands(message)

How to make multiple reaction roles

So I'm working on a reaction role cog, and the commands work so far. There's just one problem. When I create two different reaction roles, it only works for the second one. It's because I only have one dictionary and it updates that every time. I think I've seen people use a payload for reaction roles, but I have no idea what that does and if it would fix my problem. Is there a way to use payload to fix my problem? Thanks!! Here's my code:
import discord
from discord.ext import commands
from discord.ext.commands import BucketType, cooldown, CommandOnCooldown
import random
import json
reaction_title = ""
reactions = {}
reaction_message_id = ""
class ReactionRoles(commands.Cog):
"""Reaction roles!!\nYou need manage roles permissions to use these"""
def __init__(self, bot):
self.bot = bot
# Bot Commands
#commands.command(aliases=['rcp'])
async def reaction_create_post(self, ctx):
"""Creates an embed that shows all the reaction roles commands"""
embed = discord.Embed(title="Create Reaction Post", color=discord.Colour.dark_purple())
embed.set_author(name="Botpuns")
embed.add_field(name="Set Title", value=".rst [New Title]", inline=False)
embed.add_field(name="Add Role", value=".rar [#Role] [EMOJI]", inline=False)
embed.add_field(name="Remove Role", value=".rrr [#Role]", inline=False)
embed.add_field(name="Reaction Send Post", value=".rsp", inline=False)
await ctx.send(embed=embed)
await ctx.message.delete()
#commands.command(aliases=['rst'])
async def reaction_set_title(self, ctx, *, new_title):
global reaction_title
reaction_title = new_title
await ctx.send(f"The title for the message is now `{new_title}`")
await ctx.message.delete()
#commands.command(aliases=['rar'])
async def reaction_add_role(self, ctx, role: discord.Role, reaction):
global reactions
reactions[role.name] = reaction
await ctx.send(f"Role `{role.name}` has been added with the emoji {reaction}")
await ctx.message.delete()
print(reactions)
#commands.command(aliases=['rrr'])
async def reaction_remove_role(self, ctx, role: discord.Role):
if role.name in reactions:
del reactions[role.name]
await ctx.send(f"Role `{role.name}` has been deleted")
await ctx.message.delete()
else:
await ctx.send("That role wasn't even added smh")
print(reactions)
#commands.command(aliases=['rsp'])
async def reaction_send_post(self, ctx):
description = "React to add roles\n"
for role in reactions:
description += f"`{role}` - {reactions[role]}\n"
embed = discord.Embed(title=reaction_title, description=description, color=discord.Colour.purple())
embed.set_author(name="Botpuns")
message = await ctx.send(embed=embed)
global reaction_message_id
reaction_message_id = str(message.id)
for role in reactions:
await message.add_reaction(reactions[role])
await ctx.message.delete()
#commands.Cog.listener()
async def on_reaction_add(self, reaction, user):
if not user.bot:
message = reaction.message
if str(message.id) == reaction_message_id:
# Add roles to user
role_to_give = ""
for role in reactions:
if reactions[role] == reaction.emoji:
role_to_give = role
role_for_reaction = discord.utils.get(user.guild.roles, name=role_to_give)
await user.add_roles(role_for_reaction)
#commands.Cog.listener()
async def on_reaction_remove(self, reaction, user):
if not user.bot:
message = reaction.message
if str(message.id) == reaction_message_id:
# Add roles to user
role_to_remove = ""
for role in reactions:
if reactions[role] == reaction.emoji:
role_to_remove = role
role_for_reaction = discord.utils.get(user.guild.roles, name=role_to_remove)
await user.remove_roles(role_for_reaction)
def setup(bot):
bot.add_cog(ReactionRoles(bot))

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)

How to make lockdown and unlock commands discord.py

Im trying to make a lockdown and unlock command using discord.py rewrite. I have the code but it doesn't work at all. Can someone help me?
#client.command()
#commands.has_permissions(manage_channels = True)
async def lockdown(ctx):
await ctx.channel.set_permissions(ctx.guild.default_role, send_messages=False)
await ctx.send( ctx.channel.mention + " ***is now in lockdown.***")
#client.command()
#commands.has_permissions(manage_channels=True)
async def unlock(ctx):
await ctx.channel.set_permissions(ctx.guild.default_role, send_messages=True)
await ctx.send(ctx.channel.mention + " ***has been unlocked.***")
I found out the issue. The commands work on every other server except for the one I'm testing it on. It turns out that That server makes everyone admin as soon as they join.
Try this, to enable the necessary bot permissions:
#client.command()
#has_permissions(manage_channels=True)
async def lockdown(ctx):
await ctx.channel.set_permissions(ctx.guild.default_role,send_messages=False)
await ctx.send( ctx.channel.mention + " ***is now in lockdown.***")
#client.command()
#has_permissions(manage_channels=True)
async def unlock(ctx):
await ctx.channel.set_permissions(ctx.guild.default_role, send_messages=True)
await ctx.send(ctx.channel.mention + " ***has been unlocked.***")
this is my unlock command hope it helps you
you have to use overwrites TextChannel.set_permissions
#client.command()
async def unlock(ctx, role:Optional[Role], channel:Optional[TextChannel]):
role = role or ctx.guild.default_role
channel = channel or ctx.channel
async with ctx.typing():
if ctx.author.permissions_in(channel).manage_permissions:
await ctx.channel.purge(limit=1)
overwrite = channel.overwrites_for(role)
overwrite.send_messages = True
await channel.set_permissions(role, overwrite=overwrite)
unlock_embed = discord.Embed(
title= ("UNLOCKED"),
description= (f"**{channel.mention}** HAS BEEN UNLOCKED FOR **{role}**"),
colour=0x00FFF5,
)
unlock_embed.set_footer(text=ctx.author.name, icon_url=ctx.author.avatar_url)
unlock_embed.set_author(name=client.user.name, icon_url=client.user.avatar_url)
unlock_embed.set_thumbnail(url=ctx.guild.icon_url)
await ctx.channel.send(embed=unlock_embed, delete_after=10)
print("unlock")
else:
error3_embed=discord.Embed(title="ERROR", description="YOU DONT HAVE PERMISSION", colour=0xff0000)
error3_embed.set_thumbnail(url='https://images.emojiterra.com/google/android-11/512px/274c.png')
error3_embed.set_footer(text=ctx.author.name, icon_url=ctx.author.avatar_url)
error3_embed.set_author(name=client.user.name, icon_url=client.user.avatar_url)
await ctx.channel.send(embed=error3_embed, delete_after=10)

Discord.py: Trying to do an action depending on user reaction

This is the code:
import asyncio
import discord
from discord.ext import commands
client = commands.Bot(command_prefix = ".")
Token=""
#client.command()
async def react(ctx):
message = await ctx.send("Test")
await message.add_reaction("<💯>")
await message.add_reaction("<👍>")
user=ctx.message.author
def check(reaction, user):
user == ctx.message.author and str(message.emoji) == '💯'
try:
reaction, user = await client.wait_for('reaction_add', timeout=60.0, check=check)
except asyncio.TimeoutError:
await channel.send('💯')
else:
await channel.send('👍')
client.run(Token)
The problem is that I always get an error "'await' outside async function", and the a of "reaction, user = a" get highlighted. Thank you for any help.

Resources