0
votes

im new to python and discord.py, this is a repost with updated details and without the block of code that was hard to understand. I have not found an answer to this problem online so it is probably a small mistake on my end.

Problem I am trying to program a discord.py bot for my server which can do some basic commands. I wanted to add some functionality into the shell which could allow me to control the bot via python shell. Before this, I had some basic commands which would work as expected (I do c!help and it responds with an embed message with help) After I added the code for control via the console, the commands for discord stopped responding as intended.

Desired Behaviour: I type c!boop {user} in discord, The bot send a dm to said user and a logging message is sent in the logging channel. I do c!console in the python shell, my interactive menu comes up

What Happens: I type c!boop {user} in discord, I get nothing back. I do c!console in the python shell, my interactive menu comes up.

As I said, It worked before I added the new code for the Shell.

My Code The code here has been shortened a lot for the MRE but if you think the full code would be necessary, just ask. Sorry if it still is long, I already removed 3/4 of it to only keep the parts relevant to my problem.

import discord
import time

client = discord.Client()
prefix = 'c!'

@client.event
async def on_message(message):
    if message.author == client.user:
        return
#This bit is the command for within discord
    if message.content.startswith(prefix + "boop"):
        
        #Getting the Victim's user id
        victim = str(message.content)
        victim = victim.replace(prefix + 'boop ', '')
        victim = victim.replace('<@', '')
        victim = victim.replace('!', '')
        victim = victim.replace('>','')
        
        #Booping the user
        user = client.get_user(int(victim))
        await message.channel.send("Booped " + user.name)
        await user.send('**Boop!**')
        t = time.localtime()
        current_time = time.strftime("%H:%M:%S", t)
        channel = client.get_channel(int(759798825161326593))
        LogMsg = str('`' + current_time + '` ' + message.author.name + ' used command in ' + str(message.channel) + ' `' + message.content + '`')
        await channel.send(LogMsg)


#After I added this section, the above command stopped working
@client.event
async def on_ready():
    print('Logged in as')
    print(client.user.name)
    print('USER ID: ' + str(client.user.id))
    print('')
    print('To Open the Console, type ' + prefix + 'console in the shell')
    print('------')

    console = str(prefix + 'console')
    while 1 == 1:
        ConsoleInput = input('')
        if ConsoleInput == console:
            while 1 == 1:
                print('------')
                print('Please Select a Module')
                print('1 - Announce')
                print('99 - Exit Console')
                print('------')
                ConsoleInput = int(input(''))

                if ConsoleInput == 1:
                    print('------')
                    print('Module 1 Selected - Announce')
                    print("What's the id of the channel you want to announce in?")
                    Channel_id = int(input())
                    print("Embed? (1 for yes, 2 for no)")
                    YeNo = int(input())
                    
                    if YeNo == 1:
                        print("What is the Title for the Embed message?")
                        EmbedTitle = str(input())
                        print("What is the Description for the Embed message?")
                        announcement = str(input())
                        print('Announcing')
                        channel = client.get_channel(Channel_id)
                        embed=discord.Embed(title=EmbedTitle, description=announcement, color=0xff40ff)
                        await channel.send(embed=embed)
                        print("Announced")

                        t = time.localtime()
                        current_time = time.strftime("%H:%M:%S", t)
                        channel = client.get_channel(int(759798825161326593))
                        await channel.send('`' + current_time + '` ' + 'Console User used command in Console ' '`' + str(Channel_id) + ' ' + EmbedTitle + ' ' + announcement + ' ' + str(YeNo) + '`')
                        
                    elif YeNo == 2:
                        print("What is the announcement?")
                        announcement = str(input())
                        print("Announcing")
                        channel = client.get_channel(Channel_id)
                        await channel.send(announcement)
                        print("Announced")
                        
                        t = time.localtime()
                        current_time = time.strftime("%H:%M:%S", t)
                        channel = client.get_channel(int(759798825161326593))
                        await channel.send('`' + current_time + '` ' + 'Console User used command in Console ' '`' + str(Channel_id) + ' ' + announcement + ' ' + str(YeNo) + '`')

                elif ConsoleInput == 99:
                    print('------')
                    print('Exiting Console')
                    print('You can restart the console by typing ' + prefix + 'console in the shell')
                    print('------')
                    break

client.run(TOKEN GOES HERE)

Thanks in advance

1

1 Answers

0
votes

Blocking code

It appears that the synchronous code in the on_ready event is what is hanging the bot; waiting for input from the console halts any other code from running, including reacting to commands.

The only way to fix this is to design your announcement command in a different way that doesn't involve using your console, such as having it be a command for your bot.

Sidenote about discord.Client()

Since you're using the lower-level API (discord.Client), you may find it more difficult to develop new commands for your bot. I would recommend using the bot commands framework (discord.ext.commands) that discord.py comes packaged with. The pitch is in the link so instead, here's an example using the framework with your boop command:

import time
import discord
from discord.ext import commands

prefix = 'c!'
TOKEN = ''

client = commands.Bot(command_prefix=prefix)

@client.event
async def on_ready():
    print('Logged in as', client.user.name)

@client.command(name='boop')
async def client_boop(ctx, user: discord.User):
    """Boops a user.
Accepted inputs are: ID, mention, name#discrim, or name
Example: c!boop thegamecracks"""
    await user.send('**Boop!**')
    await ctx.channel.send("Booped " + user.name)

    current_time = time.strftime("%H:%M:%S", time.localtime())
    log_channel = client.get_channel(759798825161326593)
    LogMsg = '`{}` {} used command in {} `{}`'.format(
        current_time,
        ctx.author.name,
        ctx.channel.name,
        ctx.message.content
    )
    await log_channel.send(LogMsg)

client.run(TOKEN)