0

I have tried making a bot in discord.py and i cant figure out how to use discord.ext.

The part that doesn't work is this:

bot = commands.Bot(command_prefix='.')

@bot.command()
async def test(ctx, arg):
    await ctx.channel.send(arg)

When I type .test whatever in discord nothing happens

Is it because of the api update? If so what do I need to change

This is the entire code:

import os
import discord
import asyncio
from dotenv import load_dotenv
from discord.ext import commands
from discord.ext import bot


bot = commands.Bot(command_prefix='$')

@bot.command()
async def test(ctx, arg):
    await ctx.channel.send(arg)

load_dotenv()

token = os.getenv("TOKEN")

client = discord.Client()


class MyClient(discord.Client):
    async def on_ready(self):
        print('Logged on as {0}!'.format(self.user))

    async def on_message(self, message):
        f = open("muteMsg.txt", "r")
        muteMsg = f.read()
        f.close()

        print('Message from {0.author}: {0.content}'.format(message))

        id = message.author.id
        if id == 0:
            await message.delete()
            if muteMsg == "1":
                await message.channel.send(f"stfu {message.author.mention}")

        elif message.content.startswith('good bot') or message.content.startswith('Good bot'):
            await message.channel.send(':)')

        elif message.content.startswith('bad bot') or message.content.startswith('Bad bot'):
            await message.channel.send(':(')

        elif message.content.startswith('.rickroll'):
            await message.channel.send('https://www.youtube.com/watch?v=dQw4w9WgXcQ')

        elif message.content.startswith('.help'):
            await message.channel.send('commands list:\n.help: shows this\n.rickroll: well youll have to try yourself\n')

        elif message.content.startswith('.togglemutemsgs'):
            if muteMsg == "0":
                f = open("muteMsg.txt", "w")
                f.write("1")
                f.close()
                await message.channel.send('mute messages on')
            elif muteMsg == "1":
                f = open("muteMsg.txt", "w")
                f.write("0")
                f.close()
                await message.channel.send('mute messages off')


client = MyClient()
client.run(token)
Josef
  • 2,869
  • 2
  • 22
  • 23
verumIgnis
  • 160
  • 17
  • 2
    are you aware that you're using `.` as the prefix in your first code example, and `$` in the next? – askman Nov 25 '21 at 12:43
  • if you use `bot` then you don't need `client` because `bot = client + commands`. And bot has special code in `on_message` to run `commands` - so if you have to add own code in `on_message` then you have to remeber to execute `await bot.process_commands(message) ` in `on_message` – furas Nov 25 '21 at 15:09

3 Answers3

1

The core issue here is that while you do instantiate discord.ext.commands.Bot on line 9 you never actually use it, instead calling .run() on your subclass of discord.Client which does not interact with your defined method in any way.

The simplest way of getting your command to work is to change your last line from client.run(token) to

bot.run(token)

but your handlers of on_ready and on_message events will not work anymore - you should learn more to figure out why and how to solve it.

As a side note: you really shouldn't be putting any complex logic in on_message handler and you definitely should not be opening files there.

osego
  • 138
  • 1
  • 5
  • BTW: it will need to use `await bot.process_commands(message)` in new `on_message` to run `commands` - [Why does on_message stop commands from working?](https://stackoverflow.com/questions/49331096/why-does-on-message-stop-commands-from-working) – furas Nov 25 '21 at 15:13
  • thank you, changing it to bot.run fixed all my problems :) – verumIgnis Nov 29 '21 at 12:44
  • why wouldnt i want to open files there? everything to do with those files works fine. – verumIgnis Nov 29 '21 at 14:16
  • @verumIgnis in short: because it kills the performance by introducing a major blocking i/o bottleneck when handling *every, single message*. A way better option would be to store the value in memory and only read/write to disk when absolutely necessary (and even then - if you want to introduce more values you should look into using a proper database instead of writing to a file). The performance loss may not seem significant to a human but you definitely should be aware that it's a bad practice. – osego Nov 29 '21 at 14:53
  • ok, how would i get around it? how do i make it so that it saves settings over restarts but dosent have to constantly read file content? – verumIgnis Nov 29 '21 at 14:57
  • You could set it as a field on your instance of `commands.Bot` subclass by overriding `run()` and `close()` methods and calling respective base methods by using `super()`. If you have trouble with that you should ask a new question because this is getting pretty off-topic. – osego Nov 29 '21 at 15:22
0

Well, If you want to take input from user ,you need to use async def test(ctx, *, arg), Try using the code below:

@bot.command()
async def test(ctx, *,arg):
    await ctx.channel.send(arg)

And also beware of the command_prefix properly. Thank you :)

  • This is wrong, changing the signature to include a `*` only makes it so that `arg` becomes a keyword-only argument. This just happens to have some special meaning in discord.py (command parser will treat all remaining text as the argument rather than just the first word) but it's not the problem here. – osego Nov 25 '21 at 13:56
0

To use commands extension, you need to define a bot via commands.Bot because discord.Client doesn't have any infrastructure to make commands.

So you should change your inheritance in class MyClient, it should directly inherit from the commands.Bot. And you should pass the args/kwargs to your MyClient class, then you should run that classes instance rather than discord.Client.

Nyghl
  • 179
  • 5