0

for some reason , the bot does not see the query argument , although in theory it is passed from the list ps:im making a music bot error:

File "C:\Users\pc\Desktop\Bot\Mbot\Bot.py", line 77, in play await play_music(last_item)

     ^^^^^^^^^^^^^^^^^^^^^

TypeError: play_music() missing 1 required keyword-only argument: 'query'

it should work according to the idea like this, I write the play command (link) this link is added to the list for further interaction, and the same link is used to play music, but for some reason the bot does not see the link that I send

im trying replaced last_item with query and still the bot gives the same error

code:

import discord
import os
from discord.ext import commands
from discord.ui import Button,View
from discord.utils import get
import yt_dlp
import youtube_dl

intents = discord.Intents().all()
intents.message_content = True
intents.voice_states = True
intents.presences = True
bot = commands.Bot(command_prefix = '!!', intents=intents)


queue_list = []

async def play_music(ctx, *, query):
        ydl_opts = {
            'format': 'bestaudio/best',
            'postprocessors': [{
                'key': 'FFmpegExtractAudio',
                'preferredcodec': 'mp3',
                'preferredquality': '192',
            }],
        }
        ffmpeg_options = {
            'before_options': '-reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 5',
            'options': '-vn',
        }
        with youtube_dl.YoutubeDL(ydl_opts) as ydl:
            info = ydl.extract_info(query, download=False)
            url2 = info['formats'][0]['url']
        
            voice_client.play(discord.FFmpegPCMAudio(url2, **ffmpeg_options))
@bot.command()
async def join(ctx):
    await ctx.author.voice.channel.connect()

@bot.command()
async def play(ctx, *, query):
    queue_list.append(query)
    last_item = queue_list[-1]
    voice_client = ctx.voice_client
    voice_channel = ctx.author.voice.channel
    if voice_channel is None:
        await ctx.send("text1")
    elif 'youtube.com' in query or 'youtu.be' in query:
        await play_music(last_item) 
    else:
        await ctx.send('text2')

bot.run(os.getenv('TOKEN'))

2 Answers2

1

Your function play_music(ctx, *, query) takes two arguments: ctx, and query, which is a keyword-only argument; that means that you must type in the name of the argument before the actual value, like so: func(argument_name='whatever').

Yet you only inputted a single argument (await play_music(last_item)). You should add another argument when calling the function...

...However, the argument ctx is unused in play_music, so you should just remove the argument ctx, and also make query non-keyword-only (by removing the asterisk), then you wouldn't need to modify the part where you call the function.

ChesterWOV
  • 333
  • 2
  • 10
-2

@bot.command()

async def play(ctx, *, query):

* is used to denote Args in python. Args is used to pass a non-keyworded, variable-length argument list. The syntax is to use the symbol * to take in a variable number of arguments. So anything that is passed as an argument after the arg parameter is considered as a part of the * args.

  • 1
    `*args` does represent a variable-length argument list, however the code there is `*, args`, which represents a keyword-only argument. – ChesterWOV Aug 24 '23 at 08:19
  • Note: however in discord.py, `*, query`, means that the argument can be multiword/multiline. – ChesterWOV Aug 24 '23 at 08:30